Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Kashyap, Desai and committed by
James Bottomley
f7c95ef0 22c88425

+190 -4
+1
drivers/scsi/mpt2sas/Kconfig
··· 44 44 tristate "LSI MPT Fusion SAS 2.0 Device Driver" 45 45 depends on PCI && SCSI 46 46 select SCSI_SAS_ATTRS 47 + select RAID_ATTRS 47 48 ---help--- 48 49 This driver supports PCI-Express SAS 6Gb/s Host Adapters. 49 50
+2
drivers/scsi/mpt2sas/mpt2sas_base.h
··· 323 323 * @device_info: bitfield provides detailed info about the hidden components 324 324 * @num_pds: number of hidden raid components 325 325 * @responding: used in _scsih_raid_device_mark_responding 326 + * @percent_complete: resync percent complete 326 327 */ 327 328 struct _raid_device { 328 329 struct list_head list; ··· 337 336 u32 device_info; 338 337 u8 num_pds; 339 338 u8 responding; 339 + u8 percent_complete; 340 340 }; 341 341 342 342 /**
+186 -4
drivers/scsi/mpt2sas/mpt2sas_scsih.c
··· 52 52 #include <linux/delay.h> 53 53 #include <linux/pci.h> 54 54 #include <linux/interrupt.h> 55 + #include <linux/raid_class.h> 55 56 56 57 #include "mpt2sas_base.h" 57 58 ··· 133 132 u16 event; 134 133 void *event_data; 135 134 }; 135 + 136 + /* raid transport support */ 137 + static struct raid_template *mpt2sas_raid_template; 136 138 137 139 /** 138 140 * struct _scsi_io_transfer - scsi io transfer ··· 1423 1419 } 1424 1420 1425 1421 /** 1422 + * _scsih_is_raid - return boolean indicating device is raid volume 1423 + * @dev the device struct object 1424 + */ 1425 + static int 1426 + _scsih_is_raid(struct device *dev) 1427 + { 1428 + struct scsi_device *sdev = to_scsi_device(dev); 1429 + 1430 + return (sdev->channel == RAID_CHANNEL) ? 1 : 0; 1431 + } 1432 + 1433 + /** 1434 + * _scsih_get_resync - get raid volume resync percent complete 1435 + * @dev the device struct object 1436 + */ 1437 + static void 1438 + _scsih_get_resync(struct device *dev) 1439 + { 1440 + struct scsi_device *sdev = to_scsi_device(dev); 1441 + struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); 1442 + static struct _raid_device *raid_device; 1443 + unsigned long flags; 1444 + Mpi2RaidVolPage0_t vol_pg0; 1445 + Mpi2ConfigReply_t mpi_reply; 1446 + u32 volume_status_flags; 1447 + u8 percent_complete = 0; 1448 + 1449 + spin_lock_irqsave(&ioc->raid_device_lock, flags); 1450 + raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, 1451 + sdev->channel); 1452 + spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1453 + 1454 + if (!raid_device) 1455 + goto out; 1456 + 1457 + if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, 1458 + MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, 1459 + sizeof(Mpi2RaidVolPage0_t))) { 1460 + printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1461 + ioc->name, __FILE__, __LINE__, __func__); 1462 + goto out; 1463 + } 1464 + 1465 + volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); 1466 + if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) 1467 + percent_complete = raid_device->percent_complete; 1468 + out: 1469 + raid_set_resync(mpt2sas_raid_template, dev, percent_complete); 1470 + } 1471 + 1472 + /** 1473 + * _scsih_get_state - get raid volume level 1474 + * @dev the device struct object 1475 + */ 1476 + static void 1477 + _scsih_get_state(struct device *dev) 1478 + { 1479 + struct scsi_device *sdev = to_scsi_device(dev); 1480 + struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); 1481 + static struct _raid_device *raid_device; 1482 + unsigned long flags; 1483 + Mpi2RaidVolPage0_t vol_pg0; 1484 + Mpi2ConfigReply_t mpi_reply; 1485 + u32 volstate; 1486 + enum raid_state state = RAID_STATE_UNKNOWN; 1487 + 1488 + spin_lock_irqsave(&ioc->raid_device_lock, flags); 1489 + raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, 1490 + sdev->channel); 1491 + spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1492 + 1493 + if (!raid_device) 1494 + goto out; 1495 + 1496 + if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, 1497 + MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, 1498 + sizeof(Mpi2RaidVolPage0_t))) { 1499 + printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1500 + ioc->name, __FILE__, __LINE__, __func__); 1501 + goto out; 1502 + } 1503 + 1504 + volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags); 1505 + if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { 1506 + state = RAID_STATE_RESYNCING; 1507 + goto out; 1508 + } 1509 + 1510 + switch (vol_pg0.VolumeState) { 1511 + case MPI2_RAID_VOL_STATE_OPTIMAL: 1512 + case MPI2_RAID_VOL_STATE_ONLINE: 1513 + state = RAID_STATE_ACTIVE; 1514 + break; 1515 + case MPI2_RAID_VOL_STATE_DEGRADED: 1516 + state = RAID_STATE_DEGRADED; 1517 + break; 1518 + case MPI2_RAID_VOL_STATE_FAILED: 1519 + case MPI2_RAID_VOL_STATE_MISSING: 1520 + state = RAID_STATE_OFFLINE; 1521 + break; 1522 + } 1523 + out: 1524 + raid_set_state(mpt2sas_raid_template, dev, state); 1525 + } 1526 + 1527 + /** 1528 + * _scsih_set_level - set raid level 1529 + * @sdev: scsi device struct 1530 + * @raid_device: raid_device object 1531 + */ 1532 + static void 1533 + _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device) 1534 + { 1535 + enum raid_level level = RAID_LEVEL_UNKNOWN; 1536 + 1537 + switch (raid_device->volume_type) { 1538 + case MPI2_RAID_VOL_TYPE_RAID0: 1539 + level = RAID_LEVEL_0; 1540 + break; 1541 + case MPI2_RAID_VOL_TYPE_RAID10: 1542 + level = RAID_LEVEL_10; 1543 + break; 1544 + case MPI2_RAID_VOL_TYPE_RAID1E: 1545 + level = RAID_LEVEL_1E; 1546 + break; 1547 + case MPI2_RAID_VOL_TYPE_RAID1: 1548 + level = RAID_LEVEL_1; 1549 + break; 1550 + } 1551 + 1552 + raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level); 1553 + } 1554 + 1555 + /** 1426 1556 * _scsih_get_volume_capabilities - volume capabilities 1427 1557 * @ioc: per adapter object 1428 1558 * @sas_device: the raid_device object ··· 1712 1574 (unsigned long long)raid_device->wwid, 1713 1575 raid_device->num_pds, ds); 1714 1576 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 1577 + /* raid transport support */ 1578 + _scsih_set_level(sdev, raid_device); 1715 1579 return 0; 1716 1580 } 1717 1581 ··· 5310 5170 _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, 5311 5171 struct fw_event_work *fw_event) 5312 5172 { 5173 + Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data; 5174 + static struct _raid_device *raid_device; 5175 + unsigned long flags; 5176 + u16 handle; 5177 + 5313 5178 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5314 5179 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 5315 5180 _scsih_sas_ir_operation_status_event_debug(ioc, 5316 - fw_event->event_data); 5181 + event_data); 5317 5182 #endif 5183 + 5184 + /* code added for raid transport support */ 5185 + if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { 5186 + 5187 + handle = le16_to_cpu(event_data->VolDevHandle); 5188 + 5189 + spin_lock_irqsave(&ioc->raid_device_lock, flags); 5190 + raid_device = _scsih_raid_device_find_by_handle(ioc, handle); 5191 + spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 5192 + 5193 + if (!raid_device) 5194 + return; 5195 + 5196 + if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) 5197 + raid_device->percent_complete = 5198 + event_data->PercentComplete; 5199 + } 5318 5200 } 5319 5201 5320 5202 /** ··· 6552 6390 #endif 6553 6391 }; 6554 6392 6393 + /* raid transport support */ 6394 + static struct raid_function_template mpt2sas_raid_functions = { 6395 + .cookie = &scsih_driver_template, 6396 + .is_raid = _scsih_is_raid, 6397 + .get_resync = _scsih_get_resync, 6398 + .get_state = _scsih_get_state, 6399 + }; 6555 6400 6556 6401 /** 6557 6402 * _scsih_init - main entry point for this driver. ··· 6578 6409 sas_attach_transport(&mpt2sas_transport_functions); 6579 6410 if (!mpt2sas_transport_template) 6580 6411 return -ENODEV; 6412 + /* raid transport support */ 6413 + mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions); 6414 + if (!mpt2sas_raid_template) { 6415 + sas_release_transport(mpt2sas_transport_template); 6416 + return -ENODEV; 6417 + } 6581 6418 6582 6419 mpt2sas_base_initialize_callback_handler(); 6583 6420 ··· 6618 6443 mpt2sas_ctl_init(); 6619 6444 6620 6445 error = pci_register_driver(&scsih_driver); 6621 - if (error) 6446 + if (error) { 6447 + /* raid transport support */ 6448 + raid_class_release(mpt2sas_raid_template); 6622 6449 sas_release_transport(mpt2sas_transport_template); 6450 + } 6623 6451 6624 6452 return error; 6625 6453 } ··· 6640 6462 6641 6463 pci_unregister_driver(&scsih_driver); 6642 6464 6643 - sas_release_transport(mpt2sas_transport_template); 6465 + mpt2sas_ctl_exit(); 6466 + 6644 6467 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 6645 6468 mpt2sas_base_release_callback_handler(tm_cb_idx); 6646 6469 mpt2sas_base_release_callback_handler(base_cb_idx); ··· 6653 6474 mpt2sas_base_release_callback_handler(tm_tr_cb_idx); 6654 6475 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); 6655 6476 6656 - mpt2sas_ctl_exit(); 6477 + /* raid transport support */ 6478 + raid_class_release(mpt2sas_raid_template); 6479 + sas_release_transport(mpt2sas_transport_template); 6480 + 6657 6481 } 6658 6482 6659 6483 module_init(_scsih_init);
+1
include/linux/raid_class.h
··· 32 32 RAID_LEVEL_0, 33 33 RAID_LEVEL_1, 34 34 RAID_LEVEL_10, 35 + RAID_LEVEL_1E, 35 36 RAID_LEVEL_3, 36 37 RAID_LEVEL_4, 37 38 RAID_LEVEL_5,