mirror of https://gitee.com/openkylin/linux.git
scsi: mpt3sas: Additional diagnostic buffer query interface
When a host trace buffer is released, applications never know for what reason the buffer is released. Add a new IOCTL MPT3ADDNLDIAGQUERY to provide the trigger information due to which the diag buffer is released. Link: https://lore.kernel.org/r/20210204033724.1345-2-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
664f0dce20
commit
688c1a0a13
|
@ -8191,8 +8191,11 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
|
|||
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
|
||||
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
||||
(ioc_state & MPI2_IOC_STATE_MASK) ==
|
||||
MPI2_IOC_STATE_COREDUMP)
|
||||
MPI2_IOC_STATE_COREDUMP) {
|
||||
is_fault = 1;
|
||||
ioc->htb_rel.trigger_info_dwords[1] =
|
||||
(ioc_state & MPI2_DOORBELL_DATA_MASK);
|
||||
}
|
||||
}
|
||||
_base_pre_reset_handler(ioc);
|
||||
mpt3sas_wait_for_commands_to_complete(ioc);
|
||||
|
|
|
@ -1073,6 +1073,50 @@ struct hba_port {
|
|||
|
||||
#define MULTIPATH_DISABLED_PORT_ID 0xFF
|
||||
|
||||
/**
|
||||
* struct htb_rel_query - diagnostic buffer release reason
|
||||
* @unique_id - unique id associated with this buffer.
|
||||
* @buffer_rel_condition - Release condition ioctl/sysfs/reset
|
||||
* @reserved
|
||||
* @trigger_type - Master/Event/scsi/MPI
|
||||
* @trigger_info_dwords - Data Correspondig to trigger type
|
||||
*/
|
||||
struct htb_rel_query {
|
||||
u16 buffer_rel_condition;
|
||||
u16 reserved;
|
||||
u32 trigger_type;
|
||||
u32 trigger_info_dwords[2];
|
||||
};
|
||||
|
||||
/* Buffer_rel_condition bit fields */
|
||||
|
||||
/* Bit 0 - Diag Buffer not Released */
|
||||
#define MPT3_DIAG_BUFFER_NOT_RELEASED (0x00)
|
||||
/* Bit 0 - Diag Buffer Released */
|
||||
#define MPT3_DIAG_BUFFER_RELEASED (0x01)
|
||||
|
||||
/*
|
||||
* Bit 1 - Diag Buffer Released by IOCTL,
|
||||
* This bit is valid only if Bit 0 is one
|
||||
*/
|
||||
#define MPT3_DIAG_BUFFER_REL_IOCTL (0x02 | MPT3_DIAG_BUFFER_RELEASED)
|
||||
|
||||
/*
|
||||
* Bit 2 - Diag Buffer Released by Trigger,
|
||||
* This bit is valid only if Bit 0 is one
|
||||
*/
|
||||
#define MPT3_DIAG_BUFFER_REL_TRIGGER (0x04 | MPT3_DIAG_BUFFER_RELEASED)
|
||||
|
||||
/*
|
||||
* Bit 3 - Diag Buffer Released by SysFs,
|
||||
* This bit is valid only if Bit 0 is one
|
||||
*/
|
||||
#define MPT3_DIAG_BUFFER_REL_SYSFS (0x08 | MPT3_DIAG_BUFFER_RELEASED)
|
||||
|
||||
/* DIAG RESET Master trigger flags */
|
||||
#define MPT_DIAG_RESET_ISSUED_BY_DRIVER 0x00000000
|
||||
#define MPT_DIAG_RESET_ISSUED_BY_USER 0x00000001
|
||||
|
||||
typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
||||
/**
|
||||
* struct MPT3SAS_ADAPTER - per adapter struct
|
||||
|
@ -1530,6 +1574,8 @@ struct MPT3SAS_ADAPTER {
|
|||
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
|
||||
u32 ring_buffer_offset;
|
||||
u32 ring_buffer_sz;
|
||||
struct htb_rel_query htb_rel;
|
||||
u8 reset_from_user;
|
||||
u8 is_warpdrive;
|
||||
u8 is_mcpu_endpoint;
|
||||
u8 hide_ir_msg;
|
||||
|
@ -1566,6 +1612,7 @@ struct mpt3sas_debugfs_buffer {
|
|||
};
|
||||
|
||||
#define MPT_DRV_SUPPORT_BITMAP_MEMMOVE 0x00000001
|
||||
#define MPT_DRV_SUPPORT_BITMAP_ADDNLQUERY 0x00000002
|
||||
|
||||
typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||
u32 reply);
|
||||
|
|
|
@ -479,6 +479,8 @@ void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc)
|
|||
ioc_info(ioc,
|
||||
"%s: Releasing the trace buffer due to adapter reset.",
|
||||
__func__);
|
||||
ioc->htb_rel.buffer_rel_condition =
|
||||
MPT3_DIAG_BUFFER_REL_TRIGGER;
|
||||
mpt3sas_send_diag_release(ioc, i, &issue_reset);
|
||||
}
|
||||
}
|
||||
|
@ -1334,6 +1336,7 @@ _ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
|||
dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",
|
||||
__func__));
|
||||
|
||||
ioc->reset_from_user = 1;
|
||||
retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
||||
ioc_info(ioc,
|
||||
"Ioctl: host reset: %s\n", ((!retval) ? "SUCCESS" : "FAILED"));
|
||||
|
@ -1687,6 +1690,9 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
|
|||
request_data = ioc->diag_buffer[buffer_type];
|
||||
request_data_sz = diag_register->requested_buffer_size;
|
||||
ioc->unique_id[buffer_type] = diag_register->unique_id;
|
||||
/* Reset ioc variables used for additional query commands */
|
||||
ioc->reset_from_user = 0;
|
||||
memset(&ioc->htb_rel, 0, sizeof(struct htb_rel_query));
|
||||
ioc->diag_buffer_status[buffer_type] &=
|
||||
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
|
||||
memcpy(ioc->product_specific[buffer_type],
|
||||
|
@ -2469,7 +2475,61 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* _ctl_addnl_diag_query - query relevant info associated with diag buffers
|
||||
* @ioc: per adapter object
|
||||
* @arg: user space buffer containing ioctl content
|
||||
*
|
||||
* The application will send only unique_id. Driver will
|
||||
* inspect unique_id first, if valid, fill the details related to cause
|
||||
* for diag buffer release.
|
||||
*/
|
||||
static long
|
||||
_ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
||||
{
|
||||
struct mpt3_addnl_diag_query karg;
|
||||
u32 buffer_type = 0;
|
||||
|
||||
if (copy_from_user(&karg, arg, sizeof(karg))) {
|
||||
pr_err("%s: failure at %s:%d/%s()!\n",
|
||||
ioc->name, __FILE__, __LINE__, __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__));
|
||||
if (karg.unique_id == 0) {
|
||||
ioc_err(ioc, "%s: unique_id is(0x%08x)\n",
|
||||
__func__, karg.unique_id);
|
||||
return -EPERM;
|
||||
}
|
||||
buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);
|
||||
if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {
|
||||
ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",
|
||||
__func__, karg.unique_id);
|
||||
return -EPERM;
|
||||
}
|
||||
memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query));
|
||||
if ((ioc->diag_buffer_status[buffer_type] &
|
||||
MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
|
||||
ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",
|
||||
__func__, buffer_type);
|
||||
goto out;
|
||||
}
|
||||
if ((ioc->diag_buffer_status[buffer_type] &
|
||||
MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {
|
||||
ioc_err(ioc, "%s: buffer_type(0x%02x) is not released\n",
|
||||
__func__, buffer_type);
|
||||
return -EPERM;
|
||||
}
|
||||
memcpy(&karg.buffer_rel_condition, &ioc->htb_rel,
|
||||
sizeof(struct htb_rel_query));
|
||||
out:
|
||||
if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {
|
||||
ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",
|
||||
__func__, arg);
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/**
|
||||
|
@ -2533,7 +2593,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
|||
struct MPT3SAS_ADAPTER *ioc;
|
||||
struct mpt3_ioctl_header ioctl_header;
|
||||
enum block_state state;
|
||||
long ret = -EINVAL;
|
||||
long ret = -ENOIOCTLCMD;
|
||||
|
||||
/* get IOCTL header */
|
||||
if (copy_from_user(&ioctl_header, (char __user *)arg,
|
||||
|
@ -2643,6 +2703,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
|||
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer))
|
||||
ret = _ctl_diag_read_buffer(ioc, arg);
|
||||
break;
|
||||
case MPT3ADDNLDIAGQUERY:
|
||||
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_addnl_diag_query))
|
||||
ret = _ctl_addnl_diag_query(ioc, arg);
|
||||
break;
|
||||
default:
|
||||
dctlprintk(ioc,
|
||||
ioc_info(ioc, "unsupported ioctl opcode(0x%08x)\n",
|
||||
|
@ -3425,6 +3489,7 @@ host_trace_buffer_enable_store(struct device *cdev,
|
|||
MPT3_DIAG_BUFFER_IS_RELEASED))
|
||||
goto out;
|
||||
ioc_info(ioc, "releasing host trace buffer\n");
|
||||
ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_SYSFS;
|
||||
mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
|
||||
&issue_reset);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@
|
|||
struct mpt3_diag_query)
|
||||
#define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \
|
||||
struct mpt3_diag_read_buffer)
|
||||
#define MPT3ADDNLDIAGQUERY _IOWR(MPT3_MAGIC_NUMBER, 32, \
|
||||
struct mpt3_addnl_diag_query)
|
||||
|
||||
/* Trace Buffer default UniqueId */
|
||||
#define MPT2DIAGBUFFUNIQUEID (0x07075900)
|
||||
|
@ -430,4 +432,24 @@ struct mpt3_diag_read_buffer {
|
|||
uint32_t diagnostic_data[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt3_addnl_diag_query - diagnostic buffer release reason
|
||||
* @hdr - generic header
|
||||
* @unique_id - unique id associated with this buffer.
|
||||
* @buffer_rel_condition - Release condition ioctl/sysfs/reset
|
||||
* @reserved1
|
||||
* @trigger_type - Master/Event/scsi/MPI
|
||||
* @trigger_info_dwords - Data Correspondig to trigger type
|
||||
* @reserved2
|
||||
*/
|
||||
struct mpt3_addnl_diag_query {
|
||||
struct mpt3_ioctl_header hdr;
|
||||
uint32_t unique_id;
|
||||
uint16_t buffer_rel_condition;
|
||||
uint16_t reserved1;
|
||||
uint32_t trigger_type;
|
||||
uint32_t trigger_info_dwords[2];
|
||||
uint32_t reserved2[2];
|
||||
};
|
||||
|
||||
#endif /* MPT3SAS_CTL_H_INCLUDED */
|
||||
|
|
|
@ -11947,6 +11947,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
* Enable MEMORY MOVE support flag.
|
||||
*/
|
||||
ioc->drv_support_bitmap |= MPT_DRV_SUPPORT_BITMAP_MEMMOVE;
|
||||
/* Enable ADDITIONAL QUERY support flag. */
|
||||
ioc->drv_support_bitmap |= MPT_DRV_SUPPORT_BITMAP_ADDNLQUERY;
|
||||
|
||||
ioc->enable_sdev_max_qd = enable_sdev_max_qd;
|
||||
|
||||
|
|
|
@ -132,6 +132,35 @@ mpt3sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc,
|
|||
&issue_reset);
|
||||
}
|
||||
|
||||
ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_TRIGGER;
|
||||
if (event_data) {
|
||||
ioc->htb_rel.trigger_type = event_data->trigger_type;
|
||||
switch (event_data->trigger_type) {
|
||||
case MPT3SAS_TRIGGER_SCSI:
|
||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
||||
&event_data->u.scsi,
|
||||
sizeof(struct SL_WH_SCSI_TRIGGER_T));
|
||||
break;
|
||||
case MPT3SAS_TRIGGER_MPI:
|
||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
||||
&event_data->u.mpi,
|
||||
sizeof(struct SL_WH_MPI_TRIGGER_T));
|
||||
break;
|
||||
case MPT3SAS_TRIGGER_MASTER:
|
||||
ioc->htb_rel.trigger_info_dwords[0] =
|
||||
event_data->u.master.MasterData;
|
||||
break;
|
||||
case MPT3SAS_TRIGGER_EVENT:
|
||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
||||
&event_data->u.event,
|
||||
sizeof(struct SL_WH_EVENT_TRIGGER_T));
|
||||
break;
|
||||
default:
|
||||
ioc_err(ioc, "%d - Is not a valid Trigger type\n",
|
||||
event_data->trigger_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_mpt3sas_raise_sigio(ioc, event_data);
|
||||
|
||||
dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
|
||||
|
@ -201,9 +230,14 @@ mpt3sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask)
|
|||
event_data.u.master.MasterData = trigger_bitmask;
|
||||
|
||||
if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
|
||||
trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
|
||||
trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) {
|
||||
ioc->htb_rel.trigger_type = MPT3SAS_TRIGGER_MASTER;
|
||||
ioc->htb_rel.trigger_info_dwords[0] = trigger_bitmask;
|
||||
if (ioc->reset_from_user)
|
||||
ioc->htb_rel.trigger_info_dwords[1] =
|
||||
MPT_DIAG_RESET_ISSUED_BY_USER;
|
||||
_mpt3sas_raise_sigio(ioc, &event_data);
|
||||
else
|
||||
} else
|
||||
mpt3sas_send_trigger_data_event(ioc, &event_data);
|
||||
|
||||
out:
|
||||
|
|
Loading…
Reference in New Issue