mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 14:20:55 +07:00
[SCSI] mpt2sas: Added raid transport support
Adding support for raid transport layer. This will provide sysfs attributes containing raid level, state, and resync rate. MPT2SAS module will select RAID_ATTRS. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Reviewed-by: Eric Moore <eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
22c88425e0
commit
f7c95ef02b
@ -44,6 +44,7 @@ config SCSI_MPT2SAS
|
||||
tristate "LSI MPT Fusion SAS 2.0 Device Driver"
|
||||
depends on PCI && SCSI
|
||||
select SCSI_SAS_ATTRS
|
||||
select RAID_ATTRS
|
||||
---help---
|
||||
This driver supports PCI-Express SAS 6Gb/s Host Adapters.
|
||||
|
||||
|
@ -323,6 +323,7 @@ struct _sas_device {
|
||||
* @device_info: bitfield provides detailed info about the hidden components
|
||||
* @num_pds: number of hidden raid components
|
||||
* @responding: used in _scsih_raid_device_mark_responding
|
||||
* @percent_complete: resync percent complete
|
||||
*/
|
||||
struct _raid_device {
|
||||
struct list_head list;
|
||||
@ -336,6 +337,7 @@ struct _raid_device {
|
||||
u32 device_info;
|
||||
u8 num_pds;
|
||||
u8 responding;
|
||||
u8 percent_complete;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/raid_class.h>
|
||||
|
||||
#include "mpt2sas_base.h"
|
||||
|
||||
@ -133,6 +134,9 @@ struct fw_event_work {
|
||||
void *event_data;
|
||||
};
|
||||
|
||||
/* raid transport support */
|
||||
static struct raid_template *mpt2sas_raid_template;
|
||||
|
||||
/**
|
||||
* struct _scsi_io_transfer - scsi io transfer
|
||||
* @handle: sas device handle (assigned by firmware)
|
||||
@ -1418,6 +1422,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
|
||||
(flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n");
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_is_raid - return boolean indicating device is raid volume
|
||||
* @dev the device struct object
|
||||
*/
|
||||
static int
|
||||
_scsih_is_raid(struct device *dev)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
|
||||
return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_get_resync - get raid volume resync percent complete
|
||||
* @dev the device struct object
|
||||
*/
|
||||
static void
|
||||
_scsih_get_resync(struct device *dev)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
|
||||
static struct _raid_device *raid_device;
|
||||
unsigned long flags;
|
||||
Mpi2RaidVolPage0_t vol_pg0;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
u32 volume_status_flags;
|
||||
u8 percent_complete = 0;
|
||||
|
||||
spin_lock_irqsave(&ioc->raid_device_lock, flags);
|
||||
raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
|
||||
sdev->channel);
|
||||
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
|
||||
if (!raid_device)
|
||||
goto out;
|
||||
|
||||
if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
|
||||
MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
|
||||
sizeof(Mpi2RaidVolPage0_t))) {
|
||||
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
||||
ioc->name, __FILE__, __LINE__, __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
|
||||
if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
|
||||
percent_complete = raid_device->percent_complete;
|
||||
out:
|
||||
raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_get_state - get raid volume level
|
||||
* @dev the device struct object
|
||||
*/
|
||||
static void
|
||||
_scsih_get_state(struct device *dev)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
|
||||
static struct _raid_device *raid_device;
|
||||
unsigned long flags;
|
||||
Mpi2RaidVolPage0_t vol_pg0;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
u32 volstate;
|
||||
enum raid_state state = RAID_STATE_UNKNOWN;
|
||||
|
||||
spin_lock_irqsave(&ioc->raid_device_lock, flags);
|
||||
raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
|
||||
sdev->channel);
|
||||
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
|
||||
if (!raid_device)
|
||||
goto out;
|
||||
|
||||
if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
|
||||
MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
|
||||
sizeof(Mpi2RaidVolPage0_t))) {
|
||||
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
||||
ioc->name, __FILE__, __LINE__, __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
|
||||
if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
|
||||
state = RAID_STATE_RESYNCING;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (vol_pg0.VolumeState) {
|
||||
case MPI2_RAID_VOL_STATE_OPTIMAL:
|
||||
case MPI2_RAID_VOL_STATE_ONLINE:
|
||||
state = RAID_STATE_ACTIVE;
|
||||
break;
|
||||
case MPI2_RAID_VOL_STATE_DEGRADED:
|
||||
state = RAID_STATE_DEGRADED;
|
||||
break;
|
||||
case MPI2_RAID_VOL_STATE_FAILED:
|
||||
case MPI2_RAID_VOL_STATE_MISSING:
|
||||
state = RAID_STATE_OFFLINE;
|
||||
break;
|
||||
}
|
||||
out:
|
||||
raid_set_state(mpt2sas_raid_template, dev, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_set_level - set raid level
|
||||
* @sdev: scsi device struct
|
||||
* @raid_device: raid_device object
|
||||
*/
|
||||
static void
|
||||
_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
|
||||
{
|
||||
enum raid_level level = RAID_LEVEL_UNKNOWN;
|
||||
|
||||
switch (raid_device->volume_type) {
|
||||
case MPI2_RAID_VOL_TYPE_RAID0:
|
||||
level = RAID_LEVEL_0;
|
||||
break;
|
||||
case MPI2_RAID_VOL_TYPE_RAID10:
|
||||
level = RAID_LEVEL_10;
|
||||
break;
|
||||
case MPI2_RAID_VOL_TYPE_RAID1E:
|
||||
level = RAID_LEVEL_1E;
|
||||
break;
|
||||
case MPI2_RAID_VOL_TYPE_RAID1:
|
||||
level = RAID_LEVEL_1;
|
||||
break;
|
||||
}
|
||||
|
||||
raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_get_volume_capabilities - volume capabilities
|
||||
* @ioc: per adapter object
|
||||
@ -1574,6 +1712,8 @@ _scsih_slave_configure(struct scsi_device *sdev)
|
||||
(unsigned long long)raid_device->wwid,
|
||||
raid_device->num_pds, ds);
|
||||
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
|
||||
/* raid transport support */
|
||||
_scsih_set_level(sdev, raid_device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5170,11 +5310,33 @@ static void
|
||||
_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
|
||||
struct fw_event_work *fw_event)
|
||||
{
|
||||
Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
|
||||
static struct _raid_device *raid_device;
|
||||
unsigned long flags;
|
||||
u16 handle;
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
|
||||
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
|
||||
_scsih_sas_ir_operation_status_event_debug(ioc,
|
||||
fw_event->event_data);
|
||||
event_data);
|
||||
#endif
|
||||
|
||||
/* code added for raid transport support */
|
||||
if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
|
||||
|
||||
handle = le16_to_cpu(event_data->VolDevHandle);
|
||||
|
||||
spin_lock_irqsave(&ioc->raid_device_lock, flags);
|
||||
raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
|
||||
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
|
||||
if (!raid_device)
|
||||
return;
|
||||
|
||||
if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
|
||||
raid_device->percent_complete =
|
||||
event_data->PercentComplete;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6390,6 +6552,13 @@ static struct pci_driver scsih_driver = {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* raid transport support */
|
||||
static struct raid_function_template mpt2sas_raid_functions = {
|
||||
.cookie = &scsih_driver_template,
|
||||
.is_raid = _scsih_is_raid,
|
||||
.get_resync = _scsih_get_resync,
|
||||
.get_state = _scsih_get_state,
|
||||
};
|
||||
|
||||
/**
|
||||
* _scsih_init - main entry point for this driver.
|
||||
@ -6409,6 +6578,12 @@ _scsih_init(void)
|
||||
sas_attach_transport(&mpt2sas_transport_functions);
|
||||
if (!mpt2sas_transport_template)
|
||||
return -ENODEV;
|
||||
/* raid transport support */
|
||||
mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
|
||||
if (!mpt2sas_raid_template) {
|
||||
sas_release_transport(mpt2sas_transport_template);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mpt2sas_base_initialize_callback_handler();
|
||||
|
||||
@ -6443,8 +6618,11 @@ _scsih_init(void)
|
||||
mpt2sas_ctl_init();
|
||||
|
||||
error = pci_register_driver(&scsih_driver);
|
||||
if (error)
|
||||
if (error) {
|
||||
/* raid transport support */
|
||||
raid_class_release(mpt2sas_raid_template);
|
||||
sas_release_transport(mpt2sas_transport_template);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -6462,7 +6640,8 @@ _scsih_exit(void)
|
||||
|
||||
pci_unregister_driver(&scsih_driver);
|
||||
|
||||
sas_release_transport(mpt2sas_transport_template);
|
||||
mpt2sas_ctl_exit();
|
||||
|
||||
mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
|
||||
mpt2sas_base_release_callback_handler(tm_cb_idx);
|
||||
mpt2sas_base_release_callback_handler(base_cb_idx);
|
||||
@ -6474,7 +6653,10 @@ _scsih_exit(void)
|
||||
mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
|
||||
mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
|
||||
|
||||
mpt2sas_ctl_exit();
|
||||
/* raid transport support */
|
||||
raid_class_release(mpt2sas_raid_template);
|
||||
sas_release_transport(mpt2sas_transport_template);
|
||||
|
||||
}
|
||||
|
||||
module_init(_scsih_init);
|
||||
|
@ -32,6 +32,7 @@ enum raid_level {
|
||||
RAID_LEVEL_0,
|
||||
RAID_LEVEL_1,
|
||||
RAID_LEVEL_10,
|
||||
RAID_LEVEL_1E,
|
||||
RAID_LEVEL_3,
|
||||
RAID_LEVEL_4,
|
||||
RAID_LEVEL_5,
|
||||
|
Loading…
Reference in New Issue
Block a user