[SCSI] qla4xxx: Added ping support
Added ping support for network connection diagnostics. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
ac20c7bf07
commit
c0b9d3f750
7 changed files with 328 additions and 0 deletions
|
@ -221,6 +221,15 @@ struct srb {
|
||||||
uint16_t reserved2;
|
uint16_t reserved2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Mailbox request block structure */
|
||||||
|
struct mrb {
|
||||||
|
struct scsi_qla_host *ha;
|
||||||
|
struct mbox_cmd_iocb *mbox;
|
||||||
|
uint32_t mbox_cmd;
|
||||||
|
uint16_t iocb_cnt; /* Number of used iocbs */
|
||||||
|
uint32_t pid;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asynchronous Event Queue structure
|
* Asynchronous Event Queue structure
|
||||||
*/
|
*/
|
||||||
|
@ -303,6 +312,7 @@ struct ql4_tuple_ddb {
|
||||||
|
|
||||||
enum qla4_work_type {
|
enum qla4_work_type {
|
||||||
QLA4_EVENT_AEN,
|
QLA4_EVENT_AEN,
|
||||||
|
QLA4_EVENT_PING_STATUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qla4_work_evt {
|
struct qla4_work_evt {
|
||||||
|
@ -314,6 +324,12 @@ struct qla4_work_evt {
|
||||||
uint32_t data_size;
|
uint32_t data_size;
|
||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
} aen;
|
} aen;
|
||||||
|
struct {
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t pid;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint8_t data[0];
|
||||||
|
} ping;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -690,6 +706,11 @@ struct scsi_qla_host {
|
||||||
/* event work list */
|
/* event work list */
|
||||||
struct list_head work_list;
|
struct list_head work_list;
|
||||||
spinlock_t work_lock;
|
spinlock_t work_lock;
|
||||||
|
|
||||||
|
/* mbox iocb */
|
||||||
|
#define MAX_MRB 128
|
||||||
|
struct mrb *active_mrb_array[MAX_MRB];
|
||||||
|
uint32_t mrb_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ql4_task_data {
|
struct ql4_task_data {
|
||||||
|
|
|
@ -331,6 +331,10 @@ struct qla_flt_region {
|
||||||
/* Mailbox command definitions */
|
/* Mailbox command definitions */
|
||||||
#define MBOX_CMD_ABOUT_FW 0x0009
|
#define MBOX_CMD_ABOUT_FW 0x0009
|
||||||
#define MBOX_CMD_PING 0x000B
|
#define MBOX_CMD_PING 0x000B
|
||||||
|
#define PING_IPV6_PROTOCOL_ENABLE 0x1
|
||||||
|
#define PING_IPV6_LINKLOCAL_ADDR 0x4
|
||||||
|
#define PING_IPV6_ADDR0 0x8
|
||||||
|
#define PING_IPV6_ADDR1 0xC
|
||||||
#define MBOX_CMD_ENABLE_INTRS 0x0010
|
#define MBOX_CMD_ENABLE_INTRS 0x0010
|
||||||
#define INTR_DISABLE 0
|
#define INTR_DISABLE 0
|
||||||
#define INTR_ENABLE 1
|
#define INTR_ENABLE 1
|
||||||
|
@ -922,6 +926,8 @@ struct qla4_header {
|
||||||
#define ET_CMND_T3 0x19
|
#define ET_CMND_T3 0x19
|
||||||
#define ET_PASSTHRU0 0x3A
|
#define ET_PASSTHRU0 0x3A
|
||||||
#define ET_PASSTHRU_STATUS 0x3C
|
#define ET_PASSTHRU_STATUS 0x3C
|
||||||
|
#define ET_MBOX_CMD 0x38
|
||||||
|
#define ET_MBOX_STATUS 0x39
|
||||||
|
|
||||||
uint8_t entryStatus;
|
uint8_t entryStatus;
|
||||||
uint8_t systemDefined;
|
uint8_t systemDefined;
|
||||||
|
@ -1122,6 +1128,20 @@ struct passthru_status {
|
||||||
uint8_t res4[16]; /* 30-3F */
|
uint8_t res4[16]; /* 30-3F */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mbox_cmd_iocb {
|
||||||
|
struct qla4_header hdr; /* 00-03 */
|
||||||
|
uint32_t handle; /* 04-07 */
|
||||||
|
uint32_t in_mbox[8]; /* 08-25 */
|
||||||
|
uint32_t res1[6]; /* 26-3F */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mbox_status_iocb {
|
||||||
|
struct qla4_header hdr; /* 00-03 */
|
||||||
|
uint32_t handle; /* 04-07 */
|
||||||
|
uint32_t out_mbox[8]; /* 08-25 */
|
||||||
|
uint32_t res1[6]; /* 26-3F */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISP queue - response queue entry definition.
|
* ISP queue - response queue entry definition.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -183,6 +183,11 @@ int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
|
||||||
void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
|
void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
|
||||||
int qla4xxx_post_aen_work(struct scsi_qla_host *ha, uint32_t aen_code,
|
int qla4xxx_post_aen_work(struct scsi_qla_host *ha, uint32_t aen_code,
|
||||||
uint32_t data_size, uint8_t *data);
|
uint32_t data_size, uint8_t *data);
|
||||||
|
int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
|
||||||
|
uint32_t payload_size, uint32_t pid, uint8_t *ipaddr);
|
||||||
|
int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
|
||||||
|
uint32_t status, uint32_t pid,
|
||||||
|
uint32_t data_size, uint8_t *data);
|
||||||
|
|
||||||
/* BSG Functions */
|
/* BSG Functions */
|
||||||
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
|
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
|
||||||
|
|
|
@ -86,6 +86,7 @@ static void qla4xxx_init_response_q_entries(struct scsi_qla_host *ha)
|
||||||
int qla4xxx_init_rings(struct scsi_qla_host *ha)
|
int qla4xxx_init_rings(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Initialize request queue. */
|
/* Initialize request queue. */
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
@ -125,6 +126,10 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
|
||||||
|
|
||||||
qla4xxx_init_response_q_entries(ha);
|
qla4xxx_init_response_q_entries(ha);
|
||||||
|
|
||||||
|
/* Initialize mabilbox active array */
|
||||||
|
for (i = 0; i < MAX_MRB; i++)
|
||||||
|
ha->active_mrb_array[i] = NULL;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
|
|
|
@ -445,3 +445,95 @@ queuing_error:
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mrb *qla4xxx_get_new_mrb(struct scsi_qla_host *ha)
|
||||||
|
{
|
||||||
|
struct mrb *mrb;
|
||||||
|
|
||||||
|
mrb = kzalloc(sizeof(*mrb), GFP_KERNEL);
|
||||||
|
if (!mrb)
|
||||||
|
return mrb;
|
||||||
|
|
||||||
|
mrb->ha = ha;
|
||||||
|
return mrb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qla4xxx_send_mbox_iocb(struct scsi_qla_host *ha, struct mrb *mrb,
|
||||||
|
uint32_t *in_mbox)
|
||||||
|
{
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
uint32_t i;
|
||||||
|
unsigned long flags;
|
||||||
|
uint32_t index = 0;
|
||||||
|
|
||||||
|
/* Acquire hardware specific lock */
|
||||||
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
/* Get pointer to the queue entry for the marker */
|
||||||
|
rval = qla4xxx_get_req_pkt(ha, (struct queue_entry **) &(mrb->mbox));
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
goto exit_mbox_iocb;
|
||||||
|
|
||||||
|
index = ha->mrb_index;
|
||||||
|
/* get valid mrb index*/
|
||||||
|
for (i = 0; i < MAX_MRB; i++) {
|
||||||
|
index++;
|
||||||
|
if (index == MAX_MRB)
|
||||||
|
index = 1;
|
||||||
|
if (ha->active_mrb_array[index] == NULL) {
|
||||||
|
ha->mrb_index = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mrb->iocb_cnt = 1;
|
||||||
|
ha->active_mrb_array[index] = mrb;
|
||||||
|
mrb->mbox->handle = index;
|
||||||
|
mrb->mbox->hdr.entryType = ET_MBOX_CMD;
|
||||||
|
mrb->mbox->hdr.entryCount = mrb->iocb_cnt;
|
||||||
|
memcpy(mrb->mbox->in_mbox, in_mbox, 32);
|
||||||
|
mrb->mbox_cmd = in_mbox[0];
|
||||||
|
wmb();
|
||||||
|
|
||||||
|
ha->isp_ops->queue_iocb(ha);
|
||||||
|
exit_mbox_iocb:
|
||||||
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
|
||||||
|
uint32_t payload_size, uint32_t pid, uint8_t *ipaddr)
|
||||||
|
{
|
||||||
|
uint32_t in_mbox[8];
|
||||||
|
struct mrb *mrb = NULL;
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
memset(in_mbox, 0, sizeof(in_mbox));
|
||||||
|
|
||||||
|
mrb = qla4xxx_get_new_mrb(ha);
|
||||||
|
if (!mrb) {
|
||||||
|
DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: fail to get new mrb\n",
|
||||||
|
__func__));
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
goto exit_ping;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_mbox[0] = MBOX_CMD_PING;
|
||||||
|
in_mbox[1] = options;
|
||||||
|
memcpy(&in_mbox[2], &ipaddr[0], 4);
|
||||||
|
memcpy(&in_mbox[3], &ipaddr[4], 4);
|
||||||
|
memcpy(&in_mbox[4], &ipaddr[8], 4);
|
||||||
|
memcpy(&in_mbox[5], &ipaddr[12], 4);
|
||||||
|
in_mbox[6] = payload_size;
|
||||||
|
|
||||||
|
mrb->pid = pid;
|
||||||
|
rval = qla4xxx_send_mbox_iocb(ha, mrb, in_mbox);
|
||||||
|
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
goto exit_ping;
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
exit_ping:
|
||||||
|
kfree(mrb);
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
|
@ -385,6 +385,71 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha,
|
||||||
queue_work(ha->task_wq, &task_data->task_work);
|
queue_work(ha->task_wq, &task_data->task_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mrb *qla4xxx_del_mrb_from_active_array(struct scsi_qla_host *ha,
|
||||||
|
uint32_t index)
|
||||||
|
{
|
||||||
|
struct mrb *mrb = NULL;
|
||||||
|
|
||||||
|
/* validate handle and remove from active array */
|
||||||
|
if (index >= MAX_MRB)
|
||||||
|
return mrb;
|
||||||
|
|
||||||
|
mrb = ha->active_mrb_array[index];
|
||||||
|
ha->active_mrb_array[index] = NULL;
|
||||||
|
if (!mrb)
|
||||||
|
return mrb;
|
||||||
|
|
||||||
|
/* update counters */
|
||||||
|
ha->req_q_count += mrb->iocb_cnt;
|
||||||
|
ha->iocb_cnt -= mrb->iocb_cnt;
|
||||||
|
|
||||||
|
return mrb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qla4xxx_mbox_status_entry(struct scsi_qla_host *ha,
|
||||||
|
struct mbox_status_iocb *mbox_sts_entry)
|
||||||
|
{
|
||||||
|
struct mrb *mrb;
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t data_size;
|
||||||
|
|
||||||
|
mrb = qla4xxx_del_mrb_from_active_array(ha,
|
||||||
|
le32_to_cpu(mbox_sts_entry->handle));
|
||||||
|
|
||||||
|
if (mrb == NULL) {
|
||||||
|
ql4_printk(KERN_WARNING, ha, "%s: mrb[%d] is null\n", __func__,
|
||||||
|
mbox_sts_entry->handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mrb->mbox_cmd) {
|
||||||
|
case MBOX_CMD_PING:
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: mbox_cmd = 0x%x, "
|
||||||
|
"mbox_sts[0] = 0x%x, mbox_sts[6] = 0x%x\n",
|
||||||
|
__func__, mrb->mbox_cmd,
|
||||||
|
mbox_sts_entry->out_mbox[0],
|
||||||
|
mbox_sts_entry->out_mbox[6]));
|
||||||
|
|
||||||
|
if (mbox_sts_entry->out_mbox[0] == MBOX_STS_COMMAND_COMPLETE)
|
||||||
|
status = QLA_SUCCESS;
|
||||||
|
else
|
||||||
|
status = QLA_ERROR;
|
||||||
|
|
||||||
|
data_size = sizeof(mbox_sts_entry->out_mbox);
|
||||||
|
|
||||||
|
qla4xxx_post_ping_evt_work(ha, status, mrb->pid, data_size,
|
||||||
|
(uint8_t *) mbox_sts_entry->out_mbox);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: invalid mbox_cmd = "
|
||||||
|
"0x%x\n", __func__, mrb->mbox_cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(mrb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla4xxx_process_response_queue - process response queue completions
|
* qla4xxx_process_response_queue - process response queue completions
|
||||||
* @ha: Pointer to host adapter structure.
|
* @ha: Pointer to host adapter structure.
|
||||||
|
@ -461,6 +526,13 @@ void qla4xxx_process_response_queue(struct scsi_qla_host *ha)
|
||||||
"ignoring\n", ha->host_no, __func__));
|
"ignoring\n", ha->host_no, __func__));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ET_MBOX_STATUS:
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||||
|
"%s: mbox status IOCB\n", __func__));
|
||||||
|
qla4xxx_mbox_status_entry(ha,
|
||||||
|
(struct mbox_status_iocb *)sts_entry);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* Invalid entry in response queue, reset RISC
|
* Invalid entry in response queue, reset RISC
|
||||||
|
|
|
@ -118,6 +118,10 @@ static void qla4xxx_task_cleanup(struct iscsi_task *);
|
||||||
static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session);
|
static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session);
|
||||||
static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn,
|
static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn,
|
||||||
struct iscsi_stats *stats);
|
struct iscsi_stats *stats);
|
||||||
|
static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
|
||||||
|
uint32_t iface_type, uint32_t payload_size,
|
||||||
|
uint32_t pid, struct sockaddr *dst_addr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCSI host template entry points
|
* SCSI host template entry points
|
||||||
*/
|
*/
|
||||||
|
@ -194,10 +198,91 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
|
||||||
.set_iface_param = qla4xxx_iface_set_param,
|
.set_iface_param = qla4xxx_iface_set_param,
|
||||||
.get_iface_param = qla4xxx_get_iface_param,
|
.get_iface_param = qla4xxx_get_iface_param,
|
||||||
.bsg_request = qla4xxx_bsg_request,
|
.bsg_request = qla4xxx_bsg_request,
|
||||||
|
.send_ping = qla4xxx_send_ping,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct scsi_transport_template *qla4xxx_scsi_transport;
|
static struct scsi_transport_template *qla4xxx_scsi_transport;
|
||||||
|
|
||||||
|
static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
|
||||||
|
uint32_t iface_type, uint32_t payload_size,
|
||||||
|
uint32_t pid, struct sockaddr *dst_addr)
|
||||||
|
{
|
||||||
|
struct scsi_qla_host *ha = to_qla_host(shost);
|
||||||
|
struct sockaddr_in *addr;
|
||||||
|
struct sockaddr_in6 *addr6;
|
||||||
|
uint32_t options = 0;
|
||||||
|
uint8_t ipaddr[IPv6_ADDR_LEN];
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
memset(ipaddr, 0, IPv6_ADDR_LEN);
|
||||||
|
/* IPv4 to IPv4 */
|
||||||
|
if ((iface_type == ISCSI_IFACE_TYPE_IPV4) &&
|
||||||
|
(dst_addr->sa_family == AF_INET)) {
|
||||||
|
addr = (struct sockaddr_in *)dst_addr;
|
||||||
|
memcpy(ipaddr, &addr->sin_addr.s_addr, IP_ADDR_LEN);
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv4 Ping src: %pI4 "
|
||||||
|
"dest: %pI4\n", __func__,
|
||||||
|
&ha->ip_config.ip_address, ipaddr));
|
||||||
|
rval = qla4xxx_ping_iocb(ha, options, payload_size, pid,
|
||||||
|
ipaddr);
|
||||||
|
if (rval)
|
||||||
|
rval = -EINVAL;
|
||||||
|
} else if ((iface_type == ISCSI_IFACE_TYPE_IPV6) &&
|
||||||
|
(dst_addr->sa_family == AF_INET6)) {
|
||||||
|
/* IPv6 to IPv6 */
|
||||||
|
addr6 = (struct sockaddr_in6 *)dst_addr;
|
||||||
|
memcpy(ipaddr, &addr6->sin6_addr.in6_u.u6_addr8, IPv6_ADDR_LEN);
|
||||||
|
|
||||||
|
options |= PING_IPV6_PROTOCOL_ENABLE;
|
||||||
|
|
||||||
|
/* Ping using LinkLocal address */
|
||||||
|
if ((iface_num == 0) || (iface_num == 1)) {
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: LinkLocal Ping "
|
||||||
|
"src: %pI6 dest: %pI6\n", __func__,
|
||||||
|
&ha->ip_config.ipv6_link_local_addr,
|
||||||
|
ipaddr));
|
||||||
|
options |= PING_IPV6_LINKLOCAL_ADDR;
|
||||||
|
rval = qla4xxx_ping_iocb(ha, options, payload_size,
|
||||||
|
pid, ipaddr);
|
||||||
|
} else {
|
||||||
|
ql4_printk(KERN_WARNING, ha, "%s: iface num = %d "
|
||||||
|
"not supported\n", __func__, iface_num);
|
||||||
|
rval = -ENOSYS;
|
||||||
|
goto exit_send_ping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If ping using LinkLocal address fails, try ping using
|
||||||
|
* IPv6 address
|
||||||
|
*/
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
options &= ~PING_IPV6_LINKLOCAL_ADDR;
|
||||||
|
if (iface_num == 0) {
|
||||||
|
options |= PING_IPV6_ADDR0;
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "
|
||||||
|
"Ping src: %pI6 "
|
||||||
|
"dest: %pI6\n", __func__,
|
||||||
|
&ha->ip_config.ipv6_addr0,
|
||||||
|
ipaddr));
|
||||||
|
} else if (iface_num == 1) {
|
||||||
|
options |= PING_IPV6_ADDR1;
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "
|
||||||
|
"Ping src: %pI6 "
|
||||||
|
"dest: %pI6\n", __func__,
|
||||||
|
&ha->ip_config.ipv6_addr1,
|
||||||
|
ipaddr));
|
||||||
|
}
|
||||||
|
rval = qla4xxx_ping_iocb(ha, options, payload_size,
|
||||||
|
pid, ipaddr);
|
||||||
|
if (rval)
|
||||||
|
rval = -EINVAL;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
rval = -ENOSYS;
|
||||||
|
exit_send_ping:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
static umode_t ql4_attr_is_visible(int param_type, int param)
|
static umode_t ql4_attr_is_visible(int param_type, int param)
|
||||||
{
|
{
|
||||||
switch (param_type) {
|
switch (param_type) {
|
||||||
|
@ -2897,6 +2982,26 @@ int qla4xxx_post_aen_work(struct scsi_qla_host *ha,
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
|
||||||
|
uint32_t status, uint32_t pid,
|
||||||
|
uint32_t data_size, uint8_t *data)
|
||||||
|
{
|
||||||
|
struct qla4_work_evt *e;
|
||||||
|
|
||||||
|
e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_PING_STATUS);
|
||||||
|
if (!e)
|
||||||
|
return QLA_ERROR;
|
||||||
|
|
||||||
|
e->u.ping.status = status;
|
||||||
|
e->u.ping.pid = pid;
|
||||||
|
e->u.ping.data_size = data_size;
|
||||||
|
memcpy(e->u.ping.data, data, data_size);
|
||||||
|
|
||||||
|
qla4xxx_post_work(ha, e);
|
||||||
|
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void qla4xxx_do_work(struct scsi_qla_host *ha)
|
void qla4xxx_do_work(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
struct qla4_work_evt *e, *tmp;
|
struct qla4_work_evt *e, *tmp;
|
||||||
|
@ -2918,6 +3023,14 @@ void qla4xxx_do_work(struct scsi_qla_host *ha)
|
||||||
e->u.aen.data_size,
|
e->u.aen.data_size,
|
||||||
e->u.aen.data);
|
e->u.aen.data);
|
||||||
break;
|
break;
|
||||||
|
case QLA4_EVENT_PING_STATUS:
|
||||||
|
iscsi_ping_comp_event(ha->host_no,
|
||||||
|
&qla4xxx_iscsi_transport,
|
||||||
|
e->u.ping.status,
|
||||||
|
e->u.ping.pid,
|
||||||
|
e->u.ping.data_size,
|
||||||
|
e->u.ping.data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "
|
ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "
|
||||||
"supported", e->type);
|
"supported", e->type);
|
||||||
|
|
Loading…
Add table
Reference in a new issue