diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 266 |
1 files changed, 241 insertions, 25 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index efabea1a3ce4..c7ec3f174782 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 */ | ||
| 138 | static 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) |
| @@ -1305,7 +1309,6 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
| 1305 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 1309 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
| 1306 | struct scsi_target *starget; | 1310 | struct scsi_target *starget; |
| 1307 | struct _raid_device *raid_device; | 1311 | struct _raid_device *raid_device; |
| 1308 | struct _sas_device *sas_device; | ||
| 1309 | unsigned long flags; | 1312 | unsigned long flags; |
| 1310 | 1313 | ||
| 1311 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); | 1314 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); |
| @@ -1332,21 +1335,8 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
| 1332 | if (raid_device) | 1335 | if (raid_device) |
| 1333 | raid_device->sdev = sdev; /* raid is single lun */ | 1336 | raid_device->sdev = sdev; /* raid is single lun */ |
| 1334 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1337 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
| 1335 | } else { | ||
| 1336 | /* set TLR bit for SSP devices */ | ||
| 1337 | if (!(ioc->facts.IOCCapabilities & | ||
| 1338 | MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
| 1339 | goto out; | ||
| 1340 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
| 1341 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
| 1342 | sas_device_priv_data->sas_target->sas_address); | ||
| 1343 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 1344 | if (sas_device && sas_device->device_info & | ||
| 1345 | MPI2_SAS_DEVICE_INFO_SSP_TARGET) | ||
| 1346 | sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON; | ||
| 1347 | } | 1338 | } |
| 1348 | 1339 | ||
| 1349 | out: | ||
| 1350 | return 0; | 1340 | return 0; |
| 1351 | } | 1341 | } |
| 1352 | 1342 | ||
| @@ -1419,6 +1409,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
| 1419 | } | 1409 | } |
| 1420 | 1410 | ||
| 1421 | /** | 1411 | /** |
| 1412 | * _scsih_is_raid - return boolean indicating device is raid volume | ||
| 1413 | * @dev the device struct object | ||
| 1414 | */ | ||
| 1415 | static int | ||
| 1416 | _scsih_is_raid(struct device *dev) | ||
| 1417 | { | ||
| 1418 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 1419 | |||
| 1420 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | /** | ||
| 1424 | * _scsih_get_resync - get raid volume resync percent complete | ||
| 1425 | * @dev the device struct object | ||
| 1426 | */ | ||
| 1427 | static void | ||
| 1428 | _scsih_get_resync(struct device *dev) | ||
| 1429 | { | ||
| 1430 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 1431 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
| 1432 | static struct _raid_device *raid_device; | ||
| 1433 | unsigned long flags; | ||
| 1434 | Mpi2RaidVolPage0_t vol_pg0; | ||
| 1435 | Mpi2ConfigReply_t mpi_reply; | ||
| 1436 | u32 volume_status_flags; | ||
| 1437 | u8 percent_complete = 0; | ||
| 1438 | |||
| 1439 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
| 1440 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | ||
| 1441 | sdev->channel); | ||
| 1442 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
| 1443 | |||
| 1444 | if (!raid_device) | ||
| 1445 | goto out; | ||
| 1446 | |||
| 1447 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | ||
| 1448 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, | ||
| 1449 | sizeof(Mpi2RaidVolPage0_t))) { | ||
| 1450 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 1451 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 1452 | goto out; | ||
| 1453 | } | ||
| 1454 | |||
| 1455 | volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); | ||
| 1456 | if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) | ||
| 1457 | percent_complete = raid_device->percent_complete; | ||
| 1458 | out: | ||
| 1459 | raid_set_resync(mpt2sas_raid_template, dev, percent_complete); | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | /** | ||
| 1463 | * _scsih_get_state - get raid volume level | ||
| 1464 | * @dev the device struct object | ||
| 1465 | */ | ||
| 1466 | static void | ||
| 1467 | _scsih_get_state(struct device *dev) | ||
| 1468 | { | ||
| 1469 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 1470 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
| 1471 | static struct _raid_device *raid_device; | ||
| 1472 | unsigned long flags; | ||
| 1473 | Mpi2RaidVolPage0_t vol_pg0; | ||
| 1474 | Mpi2ConfigReply_t mpi_reply; | ||
| 1475 | u32 volstate; | ||
| 1476 | enum raid_state state = RAID_STATE_UNKNOWN; | ||
| 1477 | |||
| 1478 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
| 1479 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | ||
| 1480 | sdev->channel); | ||
| 1481 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
| 1482 | |||
| 1483 | if (!raid_device) | ||
| 1484 | goto out; | ||
| 1485 | |||
| 1486 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | ||
| 1487 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, | ||
| 1488 | sizeof(Mpi2RaidVolPage0_t))) { | ||
| 1489 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 1490 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 1491 | goto out; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags); | ||
| 1495 | if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { | ||
| 1496 | state = RAID_STATE_RESYNCING; | ||
| 1497 | goto out; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | switch (vol_pg0.VolumeState) { | ||
| 1501 | case MPI2_RAID_VOL_STATE_OPTIMAL: | ||
| 1502 | case MPI2_RAID_VOL_STATE_ONLINE: | ||
| 1503 | state = RAID_STATE_ACTIVE; | ||
| 1504 | break; | ||
| 1505 | case MPI2_RAID_VOL_STATE_DEGRADED: | ||
| 1506 | state = RAID_STATE_DEGRADED; | ||
| 1507 | break; | ||
| 1508 | case MPI2_RAID_VOL_STATE_FAILED: | ||
| 1509 | case MPI2_RAID_VOL_STATE_MISSING: | ||
| 1510 | state = RAID_STATE_OFFLINE; | ||
| 1511 | break; | ||
| 1512 | } | ||
| 1513 | out: | ||
| 1514 | raid_set_state(mpt2sas_raid_template, dev, state); | ||
| 1515 | } | ||
| 1516 | |||
| 1517 | /** | ||
| 1518 | * _scsih_set_level - set raid level | ||
| 1519 | * @sdev: scsi device struct | ||
| 1520 | * @raid_device: raid_device object | ||
| 1521 | */ | ||
| 1522 | static void | ||
| 1523 | _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device) | ||
| 1524 | { | ||
| 1525 | enum raid_level level = RAID_LEVEL_UNKNOWN; | ||
| 1526 | |||
| 1527 | switch (raid_device->volume_type) { | ||
| 1528 | case MPI2_RAID_VOL_TYPE_RAID0: | ||
| 1529 | level = RAID_LEVEL_0; | ||
| 1530 | break; | ||
| 1531 | case MPI2_RAID_VOL_TYPE_RAID10: | ||
| 1532 | level = RAID_LEVEL_10; | ||
| 1533 | break; | ||
| 1534 | case MPI2_RAID_VOL_TYPE_RAID1E: | ||
| 1535 | level = RAID_LEVEL_1E; | ||
| 1536 | break; | ||
| 1537 | case MPI2_RAID_VOL_TYPE_RAID1: | ||
| 1538 | level = RAID_LEVEL_1; | ||
| 1539 | break; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level); | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | /** | ||
| 1422 | * _scsih_get_volume_capabilities - volume capabilities | 1546 | * _scsih_get_volume_capabilities - volume capabilities |
| 1423 | * @ioc: per adapter object | 1547 | * @ioc: per adapter object |
| 1424 | * @sas_device: the raid_device object | 1548 | * @sas_device: the raid_device object |
| @@ -1479,6 +1603,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
| 1479 | } | 1603 | } |
| 1480 | 1604 | ||
| 1481 | /** | 1605 | /** |
| 1606 | * _scsih_enable_tlr - setting TLR flags | ||
| 1607 | * @ioc: per adapter object | ||
| 1608 | * @sdev: scsi device struct | ||
| 1609 | * | ||
| 1610 | * Enabling Transaction Layer Retries for tape devices when | ||
| 1611 | * vpd page 0x90 is present | ||
| 1612 | * | ||
| 1613 | */ | ||
| 1614 | static void | ||
| 1615 | _scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev) | ||
| 1616 | { | ||
| 1617 | /* only for TAPE */ | ||
| 1618 | if (sdev->type != TYPE_TAPE) | ||
| 1619 | return; | ||
| 1620 | |||
| 1621 | if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
| 1622 | return; | ||
| 1623 | |||
| 1624 | sas_enable_tlr(sdev); | ||
| 1625 | sdev_printk(KERN_INFO, sdev, "TLR %s\n", | ||
| 1626 | sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); | ||
| 1627 | return; | ||
| 1628 | |||
| 1629 | } | ||
| 1630 | |||
| 1631 | /** | ||
| 1482 | * _scsih_slave_configure - device configure routine. | 1632 | * _scsih_slave_configure - device configure routine. |
| 1483 | * @sdev: scsi device struct | 1633 | * @sdev: scsi device struct |
| 1484 | * | 1634 | * |
| @@ -1574,6 +1724,8 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
| 1574 | (unsigned long long)raid_device->wwid, | 1724 | (unsigned long long)raid_device->wwid, |
| 1575 | raid_device->num_pds, ds); | 1725 | raid_device->num_pds, ds); |
| 1576 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); | 1726 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
| 1727 | /* raid transport support */ | ||
| 1728 | _scsih_set_level(sdev, raid_device); | ||
| 1577 | return 0; | 1729 | return 0; |
| 1578 | } | 1730 | } |
| 1579 | 1731 | ||
| @@ -1621,8 +1773,10 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
| 1621 | 1773 | ||
| 1622 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); | 1774 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
| 1623 | 1775 | ||
| 1624 | if (ssp_target) | 1776 | if (ssp_target) { |
| 1625 | sas_read_port_mode_page(sdev); | 1777 | sas_read_port_mode_page(sdev); |
| 1778 | _scsih_enable_tlr(ioc, sdev); | ||
| 1779 | } | ||
| 1626 | return 0; | 1780 | return 0; |
| 1627 | } | 1781 | } |
| 1628 | 1782 | ||
| @@ -2908,8 +3062,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
| 2908 | 3062 | ||
| 2909 | } else | 3063 | } else |
| 2910 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3064 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
| 2911 | 3065 | /* Make sure Device is not raid volume */ | |
| 2912 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) | 3066 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && |
| 3067 | sas_is_tlr_enabled(scmd->device)) | ||
| 2913 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3068 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
| 2914 | 3069 | ||
| 2915 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); | 3070 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); |
| @@ -3298,10 +3453,12 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 3298 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 3453 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
| 3299 | if (!sas_device_priv_data->tlr_snoop_check) { | 3454 | if (!sas_device_priv_data->tlr_snoop_check) { |
| 3300 | sas_device_priv_data->tlr_snoop_check++; | 3455 | sas_device_priv_data->tlr_snoop_check++; |
| 3301 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 3456 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && |
| 3302 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) | 3457 | sas_is_tlr_enabled(scmd->device) && |
| 3303 | sas_device_priv_data->flags &= | 3458 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
| 3304 | ~MPT_DEVICE_TLR_ON; | 3459 | sas_disable_tlr(scmd->device); |
| 3460 | sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); | ||
| 3461 | } | ||
| 3305 | } | 3462 | } |
| 3306 | 3463 | ||
| 3307 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); | 3464 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); |
| @@ -5170,11 +5327,33 @@ static void | |||
| 5170 | _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, | 5327 | _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, |
| 5171 | struct fw_event_work *fw_event) | 5328 | struct fw_event_work *fw_event) |
| 5172 | { | 5329 | { |
| 5330 | Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data; | ||
| 5331 | static struct _raid_device *raid_device; | ||
| 5332 | unsigned long flags; | ||
| 5333 | u16 handle; | ||
| 5334 | |||
| 5173 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5335 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| 5174 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5336 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
| 5175 | _scsih_sas_ir_operation_status_event_debug(ioc, | 5337 | _scsih_sas_ir_operation_status_event_debug(ioc, |
| 5176 | fw_event->event_data); | 5338 | event_data); |
| 5177 | #endif | 5339 | #endif |
| 5340 | |||
| 5341 | /* code added for raid transport support */ | ||
| 5342 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { | ||
| 5343 | |||
| 5344 | handle = le16_to_cpu(event_data->VolDevHandle); | ||
| 5345 | |||
| 5346 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
| 5347 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | ||
| 5348 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
| 5349 | |||
| 5350 | if (!raid_device) | ||
| 5351 | return; | ||
| 5352 | |||
| 5353 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) | ||
| 5354 | raid_device->percent_complete = | ||
| 5355 | event_data->PercentComplete; | ||
| 5356 | } | ||
| 5178 | } | 5357 | } |
| 5179 | 5358 | ||
| 5180 | /** | 5359 | /** |
| @@ -5998,6 +6177,8 @@ _scsih_remove(struct pci_dev *pdev) | |||
| 5998 | struct _sas_port *mpt2sas_port; | 6177 | struct _sas_port *mpt2sas_port; |
| 5999 | struct _sas_device *sas_device; | 6178 | struct _sas_device *sas_device; |
| 6000 | struct _sas_node *expander_sibling; | 6179 | struct _sas_node *expander_sibling; |
| 6180 | struct _raid_device *raid_device, *next; | ||
| 6181 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
| 6001 | struct workqueue_struct *wq; | 6182 | struct workqueue_struct *wq; |
| 6002 | unsigned long flags; | 6183 | unsigned long flags; |
| 6003 | 6184 | ||
| @@ -6011,6 +6192,21 @@ _scsih_remove(struct pci_dev *pdev) | |||
| 6011 | if (wq) | 6192 | if (wq) |
| 6012 | destroy_workqueue(wq); | 6193 | destroy_workqueue(wq); |
| 6013 | 6194 | ||
| 6195 | /* release all the volumes */ | ||
| 6196 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | ||
| 6197 | list) { | ||
| 6198 | if (raid_device->starget) { | ||
| 6199 | sas_target_priv_data = | ||
| 6200 | raid_device->starget->hostdata; | ||
| 6201 | sas_target_priv_data->deleted = 1; | ||
| 6202 | scsi_remove_target(&raid_device->starget->dev); | ||
| 6203 | } | ||
| 6204 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" | ||
| 6205 | "(0x%016llx)\n", ioc->name, raid_device->handle, | ||
| 6206 | (unsigned long long) raid_device->wwid); | ||
| 6207 | _scsih_raid_device_remove(ioc, raid_device); | ||
| 6208 | } | ||
| 6209 | |||
| 6014 | /* free ports attached to the sas_host */ | 6210 | /* free ports attached to the sas_host */ |
| 6015 | retry_again: | 6211 | retry_again: |
| 6016 | list_for_each_entry(mpt2sas_port, | 6212 | list_for_each_entry(mpt2sas_port, |
| @@ -6373,6 +6569,13 @@ static struct pci_driver scsih_driver = { | |||
| 6373 | #endif | 6569 | #endif |
| 6374 | }; | 6570 | }; |
| 6375 | 6571 | ||
| 6572 | /* raid transport support */ | ||
| 6573 | static struct raid_function_template mpt2sas_raid_functions = { | ||
| 6574 | .cookie = &scsih_driver_template, | ||
| 6575 | .is_raid = _scsih_is_raid, | ||
| 6576 | .get_resync = _scsih_get_resync, | ||
| 6577 | .get_state = _scsih_get_state, | ||
| 6578 | }; | ||
| 6376 | 6579 | ||
| 6377 | /** | 6580 | /** |
| 6378 | * _scsih_init - main entry point for this driver. | 6581 | * _scsih_init - main entry point for this driver. |
| @@ -6392,6 +6595,12 @@ _scsih_init(void) | |||
| 6392 | sas_attach_transport(&mpt2sas_transport_functions); | 6595 | sas_attach_transport(&mpt2sas_transport_functions); |
| 6393 | if (!mpt2sas_transport_template) | 6596 | if (!mpt2sas_transport_template) |
| 6394 | return -ENODEV; | 6597 | return -ENODEV; |
| 6598 | /* raid transport support */ | ||
| 6599 | mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions); | ||
| 6600 | if (!mpt2sas_raid_template) { | ||
| 6601 | sas_release_transport(mpt2sas_transport_template); | ||
| 6602 | return -ENODEV; | ||
| 6603 | } | ||
| 6395 | 6604 | ||
| 6396 | mpt2sas_base_initialize_callback_handler(); | 6605 | mpt2sas_base_initialize_callback_handler(); |
| 6397 | 6606 | ||
| @@ -6426,8 +6635,11 @@ _scsih_init(void) | |||
| 6426 | mpt2sas_ctl_init(); | 6635 | mpt2sas_ctl_init(); |
| 6427 | 6636 | ||
| 6428 | error = pci_register_driver(&scsih_driver); | 6637 | error = pci_register_driver(&scsih_driver); |
| 6429 | if (error) | 6638 | if (error) { |
| 6639 | /* raid transport support */ | ||
| 6640 | raid_class_release(mpt2sas_raid_template); | ||
| 6430 | sas_release_transport(mpt2sas_transport_template); | 6641 | sas_release_transport(mpt2sas_transport_template); |
| 6642 | } | ||
| 6431 | 6643 | ||
| 6432 | return error; | 6644 | return error; |
| 6433 | } | 6645 | } |
| @@ -6445,7 +6657,8 @@ _scsih_exit(void) | |||
| 6445 | 6657 | ||
| 6446 | pci_unregister_driver(&scsih_driver); | 6658 | pci_unregister_driver(&scsih_driver); |
| 6447 | 6659 | ||
| 6448 | sas_release_transport(mpt2sas_transport_template); | 6660 | mpt2sas_ctl_exit(); |
| 6661 | |||
| 6449 | mpt2sas_base_release_callback_handler(scsi_io_cb_idx); | 6662 | mpt2sas_base_release_callback_handler(scsi_io_cb_idx); |
| 6450 | mpt2sas_base_release_callback_handler(tm_cb_idx); | 6663 | mpt2sas_base_release_callback_handler(tm_cb_idx); |
| 6451 | mpt2sas_base_release_callback_handler(base_cb_idx); | 6664 | mpt2sas_base_release_callback_handler(base_cb_idx); |
| @@ -6457,7 +6670,10 @@ _scsih_exit(void) | |||
| 6457 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); | 6670 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); |
| 6458 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); | 6671 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); |
| 6459 | 6672 | ||
| 6460 | mpt2sas_ctl_exit(); | 6673 | /* raid transport support */ |
| 6674 | raid_class_release(mpt2sas_raid_template); | ||
| 6675 | sas_release_transport(mpt2sas_transport_template); | ||
| 6676 | |||
| 6461 | } | 6677 | } |
| 6462 | 6678 | ||
| 6463 | module_init(_scsih_init); | 6679 | module_init(_scsih_init); |
