mirror of https://gitee.com/openkylin/linux.git
[SCSI] qla4xxx: added support for host event
Added support to post kernel host event to application using netlink interface. 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
a11e254595
commit
ff88443080
|
@ -301,7 +301,21 @@ struct ql4_tuple_ddb {
|
||||||
#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */
|
#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */
|
||||||
#define DF_FO_MASKED 3
|
#define DF_FO_MASKED 3
|
||||||
|
|
||||||
|
enum qla4_work_type {
|
||||||
|
QLA4_EVENT_AEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qla4_work_evt {
|
||||||
|
struct list_head list;
|
||||||
|
enum qla4_work_type type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
enum iscsi_host_event_code code;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint8_t data[0];
|
||||||
|
} aen;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
struct ql82xx_hw_data {
|
struct ql82xx_hw_data {
|
||||||
/* Offsets for flash/nvram access (set to ~0 if not used). */
|
/* Offsets for flash/nvram access (set to ~0 if not used). */
|
||||||
|
@ -672,6 +686,10 @@ struct scsi_qla_host {
|
||||||
uint16_t sec_ddb_idx;
|
uint16_t sec_ddb_idx;
|
||||||
int is_reset;
|
int is_reset;
|
||||||
uint16_t temperature;
|
uint16_t temperature;
|
||||||
|
|
||||||
|
/* event work list */
|
||||||
|
struct list_head work_list;
|
||||||
|
spinlock_t work_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ql4_task_data {
|
struct ql4_task_data {
|
||||||
|
|
|
@ -181,6 +181,8 @@ int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
|
||||||
int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
|
int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
|
||||||
struct ddb_entry *ddb_entry, uint32_t state);
|
struct ddb_entry *ddb_entry, uint32_t state);
|
||||||
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,
|
||||||
|
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);
|
||||||
|
|
|
@ -576,6 +576,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
|
||||||
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
|
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
|
||||||
|
|
||||||
ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
|
ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
|
||||||
|
qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKUP,
|
||||||
|
sizeof(mbox_sts),
|
||||||
|
(uint8_t *) mbox_sts);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MBOX_ASTS_LINK_DOWN:
|
case MBOX_ASTS_LINK_DOWN:
|
||||||
|
@ -584,6 +587,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
|
||||||
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
|
set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
|
||||||
|
|
||||||
ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
|
ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
|
||||||
|
qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKDOWN,
|
||||||
|
sizeof(mbox_sts),
|
||||||
|
(uint8_t *) mbox_sts);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MBOX_ASTS_HEARTBEAT:
|
case MBOX_ASTS_HEARTBEAT:
|
||||||
|
|
|
@ -2282,6 +2282,10 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process any deferred work. */
|
||||||
|
if (!list_empty(&ha->work_list))
|
||||||
|
start_dpc++;
|
||||||
|
|
||||||
/* Wakeup the dpc routine for this adapter, if needed. */
|
/* Wakeup the dpc routine for this adapter, if needed. */
|
||||||
if (start_dpc ||
|
if (start_dpc ||
|
||||||
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
|
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
|
||||||
|
@ -2847,6 +2851,81 @@ void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
|
||||||
queue_work(ha->dpc_thread, &ha->dpc_work);
|
queue_work(ha->dpc_thread, &ha->dpc_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct qla4_work_evt *
|
||||||
|
qla4xxx_alloc_work(struct scsi_qla_host *ha, uint32_t data_size,
|
||||||
|
enum qla4_work_type type)
|
||||||
|
{
|
||||||
|
struct qla4_work_evt *e;
|
||||||
|
uint32_t size = sizeof(struct qla4_work_evt) + data_size;
|
||||||
|
|
||||||
|
e = kzalloc(size, GFP_ATOMIC);
|
||||||
|
if (!e)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&e->list);
|
||||||
|
e->type = type;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qla4xxx_post_work(struct scsi_qla_host *ha,
|
||||||
|
struct qla4_work_evt *e)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ha->work_lock, flags);
|
||||||
|
list_add_tail(&e->list, &ha->work_list);
|
||||||
|
spin_unlock_irqrestore(&ha->work_lock, flags);
|
||||||
|
qla4xxx_wake_dpc(ha);
|
||||||
|
}
|
||||||
|
|
||||||
|
int qla4xxx_post_aen_work(struct scsi_qla_host *ha,
|
||||||
|
enum iscsi_host_event_code aen_code,
|
||||||
|
uint32_t data_size, uint8_t *data)
|
||||||
|
{
|
||||||
|
struct qla4_work_evt *e;
|
||||||
|
|
||||||
|
e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_AEN);
|
||||||
|
if (!e)
|
||||||
|
return QLA_ERROR;
|
||||||
|
|
||||||
|
e->u.aen.code = aen_code;
|
||||||
|
e->u.aen.data_size = data_size;
|
||||||
|
memcpy(e->u.aen.data, data, data_size);
|
||||||
|
|
||||||
|
qla4xxx_post_work(ha, e);
|
||||||
|
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qla4xxx_do_work(struct scsi_qla_host *ha)
|
||||||
|
{
|
||||||
|
struct qla4_work_evt *e, *tmp;
|
||||||
|
unsigned long flags;
|
||||||
|
LIST_HEAD(work);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ha->work_lock, flags);
|
||||||
|
list_splice_init(&ha->work_list, &work);
|
||||||
|
spin_unlock_irqrestore(&ha->work_lock, flags);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(e, tmp, &work, list) {
|
||||||
|
list_del_init(&e->list);
|
||||||
|
|
||||||
|
switch (e->type) {
|
||||||
|
case QLA4_EVENT_AEN:
|
||||||
|
iscsi_post_host_event(ha->host_no,
|
||||||
|
&qla4xxx_iscsi_transport,
|
||||||
|
e->u.aen.code,
|
||||||
|
e->u.aen.data_size,
|
||||||
|
e->u.aen.data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "
|
||||||
|
"supported", e->type);
|
||||||
|
}
|
||||||
|
kfree(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla4xxx_do_dpc - dpc routine
|
* qla4xxx_do_dpc - dpc routine
|
||||||
* @data: in our case pointer to adapter structure
|
* @data: in our case pointer to adapter structure
|
||||||
|
@ -2878,6 +2957,9 @@ static void qla4xxx_do_dpc(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* post events to application */
|
||||||
|
qla4xxx_do_work(ha);
|
||||||
|
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
|
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
|
||||||
qla4_8xxx_idc_lock(ha);
|
qla4_8xxx_idc_lock(ha);
|
||||||
|
@ -4450,6 +4532,9 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
|
||||||
|
|
||||||
spin_lock_init(&ha->hardware_lock);
|
spin_lock_init(&ha->hardware_lock);
|
||||||
|
|
||||||
|
/* Initialize work list */
|
||||||
|
INIT_LIST_HEAD(&ha->work_list);
|
||||||
|
|
||||||
/* Allocate dma buffers */
|
/* Allocate dma buffers */
|
||||||
if (qla4xxx_mem_alloc(ha)) {
|
if (qla4xxx_mem_alloc(ha)) {
|
||||||
ql4_printk(KERN_WARNING, ha,
|
ql4_printk(KERN_WARNING, ha,
|
||||||
|
|
Loading…
Reference in New Issue