Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 181282
b: refs/heads/master
c: f7c95ef
h: refs/heads/master
v: v3
  • Loading branch information
Kashyap, Desai authored and James Bottomley committed Feb 9, 2010
1 parent 5fdd861 commit 03c93c5
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 5 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: 22c88425e03e8476176375ab0457c88ff3a5b68c
refs/heads/master: f7c95ef02b564d9984c0655c9659791b1dd5d7ad
1 change: 1 addition & 0 deletions trunk/drivers/scsi/mpt2sas/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/scsi/mpt2sas/mpt2sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -336,6 +337,7 @@ struct _raid_device {
u32 device_info;
u8 num_pds;
u8 responding;
u8 percent_complete;
};

/**
Expand Down
190 changes: 186 additions & 4 deletions trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
}

/**
Expand Down Expand Up @@ -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.
Expand All @@ -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();

Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/raid_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 03c93c5

Please sign in to comment.