aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-12-16 08:24:42 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-08 19:19:41 -0500
commitf7c95ef02b564d9984c0655c9659791b1dd5d7ad (patch)
tree40d9c4457ad24d639578c5734016dfaec4fdc69b /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parent22c88425e03e8476176375ab0457c88ff3a5b68c (diff)
[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>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c190
1 files changed, 186 insertions, 4 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index cd551768bfbf..ca984cbc8e2f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -52,6 +52,7 @@
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/raid_class.h>
55 56
56#include "mpt2sas_base.h" 57#include "mpt2sas_base.h"
57 58
@@ -133,6 +134,9 @@ struct fw_event_work {
133 void *event_data; 134 void *event_data;
134}; 135};
135 136
137/* raid transport support */
138static struct raid_template *mpt2sas_raid_template;
139
136/** 140/**
137 * struct _scsi_io_transfer - scsi io transfer 141 * struct _scsi_io_transfer - scsi io transfer
138 * @handle: sas device handle (assigned by firmware) 142 * @handle: sas device handle (assigned by firmware)
@@ -1419,6 +1423,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1419} 1423}
1420 1424
1421/** 1425/**
1426 * _scsih_is_raid - return boolean indicating device is raid volume
1427 * @dev the device struct object
1428 */
1429static int
1430_scsih_is_raid(struct device *dev)
1431{
1432 struct scsi_device *sdev = to_scsi_device(dev);
1433
1434 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1435}
1436
1437/**
1438 * _scsih_get_resync - get raid volume resync percent complete
1439 * @dev the device struct object
1440 */
1441static void
1442_scsih_get_resync(struct device *dev)
1443{
1444 struct scsi_device *sdev = to_scsi_device(dev);
1445 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1446 static struct _raid_device *raid_device;
1447 unsigned long flags;
1448 Mpi2RaidVolPage0_t vol_pg0;
1449 Mpi2ConfigReply_t mpi_reply;
1450 u32 volume_status_flags;
1451 u8 percent_complete = 0;
1452
1453 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1454 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1455 sdev->channel);
1456 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1457
1458 if (!raid_device)
1459 goto out;
1460
1461 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1462 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1463 sizeof(Mpi2RaidVolPage0_t))) {
1464 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1465 ioc->name, __FILE__, __LINE__, __func__);
1466 goto out;
1467 }
1468
1469 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1470 if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
1471 percent_complete = raid_device->percent_complete;
1472 out:
1473 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
1474}
1475
1476/**
1477 * _scsih_get_state - get raid volume level
1478 * @dev the device struct object
1479 */
1480static void
1481_scsih_get_state(struct device *dev)
1482{
1483 struct scsi_device *sdev = to_scsi_device(dev);
1484 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1485 static struct _raid_device *raid_device;
1486 unsigned long flags;
1487 Mpi2RaidVolPage0_t vol_pg0;
1488 Mpi2ConfigReply_t mpi_reply;
1489 u32 volstate;
1490 enum raid_state state = RAID_STATE_UNKNOWN;
1491
1492 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1493 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1494 sdev->channel);
1495 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1496
1497 if (!raid_device)
1498 goto out;
1499
1500 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1501 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1502 sizeof(Mpi2RaidVolPage0_t))) {
1503 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1504 ioc->name, __FILE__, __LINE__, __func__);
1505 goto out;
1506 }
1507
1508 volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1509 if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
1510 state = RAID_STATE_RESYNCING;
1511 goto out;
1512 }
1513
1514 switch (vol_pg0.VolumeState) {
1515 case MPI2_RAID_VOL_STATE_OPTIMAL:
1516 case MPI2_RAID_VOL_STATE_ONLINE:
1517 state = RAID_STATE_ACTIVE;
1518 break;
1519 case MPI2_RAID_VOL_STATE_DEGRADED:
1520 state = RAID_STATE_DEGRADED;
1521 break;
1522 case MPI2_RAID_VOL_STATE_FAILED:
1523 case MPI2_RAID_VOL_STATE_MISSING:
1524 state = RAID_STATE_OFFLINE;
1525 break;
1526 }
1527 out:
1528 raid_set_state(mpt2sas_raid_template, dev, state);
1529}
1530
1531/**
1532 * _scsih_set_level - set raid level
1533 * @sdev: scsi device struct
1534 * @raid_device: raid_device object
1535 */
1536static void
1537_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1538{
1539 enum raid_level level = RAID_LEVEL_UNKNOWN;
1540
1541 switch (raid_device->volume_type) {
1542 case MPI2_RAID_VOL_TYPE_RAID0:
1543 level = RAID_LEVEL_0;
1544 break;
1545 case MPI2_RAID_VOL_TYPE_RAID10:
1546 level = RAID_LEVEL_10;
1547 break;
1548 case MPI2_RAID_VOL_TYPE_RAID1E:
1549 level = RAID_LEVEL_1E;
1550 break;
1551 case MPI2_RAID_VOL_TYPE_RAID1:
1552 level = RAID_LEVEL_1;
1553 break;
1554 }
1555
1556 raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
1557}
1558
1559/**
1422 * _scsih_get_volume_capabilities - volume capabilities 1560 * _scsih_get_volume_capabilities - volume capabilities
1423 * @ioc: per adapter object 1561 * @ioc: per adapter object
1424 * @sas_device: the raid_device object 1562 * @sas_device: the raid_device object
@@ -1574,6 +1712,8 @@ _scsih_slave_configure(struct scsi_device *sdev)
1574 (unsigned long long)raid_device->wwid, 1712 (unsigned long long)raid_device->wwid,
1575 raid_device->num_pds, ds); 1713 raid_device->num_pds, ds);
1576 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 1714 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1715 /* raid transport support */
1716 _scsih_set_level(sdev, raid_device);
1577 return 0; 1717 return 0;
1578 } 1718 }
1579 1719
@@ -5170,11 +5310,33 @@ static void
5170_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, 5310_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
5171 struct fw_event_work *fw_event) 5311 struct fw_event_work *fw_event)
5172{ 5312{
5313 Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
5314 static struct _raid_device *raid_device;
5315 unsigned long flags;
5316 u16 handle;
5317
5173#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5318#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5174 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 5319 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5175 _scsih_sas_ir_operation_status_event_debug(ioc, 5320 _scsih_sas_ir_operation_status_event_debug(ioc,
5176 fw_event->event_data); 5321 event_data);
5177#endif 5322#endif
5323
5324 /* code added for raid transport support */
5325 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
5326
5327 handle = le16_to_cpu(event_data->VolDevHandle);
5328
5329 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5330 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5331 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5332
5333 if (!raid_device)
5334 return;
5335
5336 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
5337 raid_device->percent_complete =
5338 event_data->PercentComplete;
5339 }
5178} 5340}
5179 5341
5180/** 5342/**
@@ -6390,6 +6552,13 @@ static struct pci_driver scsih_driver = {
6390#endif 6552#endif
6391}; 6553};
6392 6554
6555/* raid transport support */
6556static struct raid_function_template mpt2sas_raid_functions = {
6557 .cookie = &scsih_driver_template,
6558 .is_raid = _scsih_is_raid,
6559 .get_resync = _scsih_get_resync,
6560 .get_state = _scsih_get_state,
6561};
6393 6562
6394/** 6563/**
6395 * _scsih_init - main entry point for this driver. 6564 * _scsih_init - main entry point for this driver.
@@ -6409,6 +6578,12 @@ _scsih_init(void)
6409 sas_attach_transport(&mpt2sas_transport_functions); 6578 sas_attach_transport(&mpt2sas_transport_functions);
6410 if (!mpt2sas_transport_template) 6579 if (!mpt2sas_transport_template)
6411 return -ENODEV; 6580 return -ENODEV;
6581 /* raid transport support */
6582 mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
6583 if (!mpt2sas_raid_template) {
6584 sas_release_transport(mpt2sas_transport_template);
6585 return -ENODEV;
6586 }
6412 6587
6413 mpt2sas_base_initialize_callback_handler(); 6588 mpt2sas_base_initialize_callback_handler();
6414 6589
@@ -6443,8 +6618,11 @@ _scsih_init(void)
6443 mpt2sas_ctl_init(); 6618 mpt2sas_ctl_init();
6444 6619
6445 error = pci_register_driver(&scsih_driver); 6620 error = pci_register_driver(&scsih_driver);
6446 if (error) 6621 if (error) {
6622 /* raid transport support */
6623 raid_class_release(mpt2sas_raid_template);
6447 sas_release_transport(mpt2sas_transport_template); 6624 sas_release_transport(mpt2sas_transport_template);
6625 }
6448 6626
6449 return error; 6627 return error;
6450} 6628}
@@ -6462,7 +6640,8 @@ _scsih_exit(void)
6462 6640
6463 pci_unregister_driver(&scsih_driver); 6641 pci_unregister_driver(&scsih_driver);
6464 6642
6465 sas_release_transport(mpt2sas_transport_template); 6643 mpt2sas_ctl_exit();
6644
6466 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 6645 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
6467 mpt2sas_base_release_callback_handler(tm_cb_idx); 6646 mpt2sas_base_release_callback_handler(tm_cb_idx);
6468 mpt2sas_base_release_callback_handler(base_cb_idx); 6647 mpt2sas_base_release_callback_handler(base_cb_idx);
@@ -6474,7 +6653,10 @@ _scsih_exit(void)
6474 mpt2sas_base_release_callback_handler(tm_tr_cb_idx); 6653 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
6475 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); 6654 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6476 6655
6477 mpt2sas_ctl_exit(); 6656 /* raid transport support */
6657 raid_class_release(mpt2sas_raid_template);
6658 sas_release_transport(mpt2sas_transport_template);
6659
6478} 6660}
6479 6661
6480module_init(_scsih_init); 6662module_init(_scsih_init);