aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c1078
1 files changed, 797 insertions, 281 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 86ab32d7ab15..be171ed682e0 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -52,6 +52,8 @@
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>
56#include <linux/slab.h>
55 57
56#include "mpt2sas_base.h" 58#include "mpt2sas_base.h"
57 59
@@ -76,6 +78,7 @@ static u8 tm_cb_idx = -1;
76static u8 ctl_cb_idx = -1; 78static u8 ctl_cb_idx = -1;
77static u8 base_cb_idx = -1; 79static u8 base_cb_idx = -1;
78static u8 transport_cb_idx = -1; 80static u8 transport_cb_idx = -1;
81static u8 scsih_cb_idx = -1;
79static u8 config_cb_idx = -1; 82static u8 config_cb_idx = -1;
80static int mpt_ids; 83static int mpt_ids;
81 84
@@ -132,6 +135,9 @@ struct fw_event_work {
132 void *event_data; 135 void *event_data;
133}; 136};
134 137
138/* raid transport support */
139static struct raid_template *mpt2sas_raid_template;
140
135/** 141/**
136 * struct _scsi_io_transfer - scsi io transfer 142 * struct _scsi_io_transfer - scsi io transfer
137 * @handle: sas device handle (assigned by firmware) 143 * @handle: sas device handle (assigned by firmware)
@@ -196,10 +202,28 @@ static struct pci_device_id scsih_pci_table[] = {
196 PCI_ANY_ID, PCI_ANY_ID }, 202 PCI_ANY_ID, PCI_ANY_ID },
197 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, 203 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
198 PCI_ANY_ID, PCI_ANY_ID }, 204 PCI_ANY_ID, PCI_ANY_ID },
205 /* Meteor ~ 2116 */
199 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, 206 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
200 PCI_ANY_ID, PCI_ANY_ID }, 207 PCI_ANY_ID, PCI_ANY_ID },
201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, 208 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
202 PCI_ANY_ID, PCI_ANY_ID }, 209 PCI_ANY_ID, PCI_ANY_ID },
210 /* Thunderbolt ~ 2208 */
211 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
212 PCI_ANY_ID, PCI_ANY_ID },
213 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
214 PCI_ANY_ID, PCI_ANY_ID },
215 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
216 PCI_ANY_ID, PCI_ANY_ID },
217 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
218 PCI_ANY_ID, PCI_ANY_ID },
219 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
220 PCI_ANY_ID, PCI_ANY_ID },
221 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
222 PCI_ANY_ID, PCI_ANY_ID },
223 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
224 PCI_ANY_ID, PCI_ANY_ID },
225 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
226 PCI_ANY_ID, PCI_ANY_ID },
203 {0} /* Terminating entry */ 227 {0} /* Terminating entry */
204}; 228};
205MODULE_DEVICE_TABLE(pci, scsih_pci_table); 229MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -317,6 +341,47 @@ _scsih_is_boot_device(u64 sas_address, u64 device_name,
317} 341}
318 342
319/** 343/**
344 * _scsih_get_sas_address - set the sas_address for given device handle
345 * @handle: device handle
346 * @sas_address: sas address
347 *
348 * Returns 0 success, non-zero when failure
349 */
350static int
351_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
352 u64 *sas_address)
353{
354 Mpi2SasDevicePage0_t sas_device_pg0;
355 Mpi2ConfigReply_t mpi_reply;
356 u32 ioc_status;
357
358 if (handle <= ioc->sas_hba.num_phys) {
359 *sas_address = ioc->sas_hba.sas_address;
360 return 0;
361 } else
362 *sas_address = 0;
363
364 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
365 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
366 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
367 ioc->name, __FILE__, __LINE__, __func__);
368 return -ENXIO;
369 }
370
371 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
372 MPI2_IOCSTATUS_MASK;
373 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
374 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
375 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
376 __FILE__, __LINE__, __func__);
377 return -EIO;
378 }
379
380 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
381 return 0;
382}
383
384/**
320 * _scsih_determine_boot_device - determine boot device. 385 * _scsih_determine_boot_device - determine boot device.
321 * @ioc: per adapter object 386 * @ioc: per adapter object
322 * @device: either sas_device or raid_device object 387 * @device: either sas_device or raid_device object
@@ -510,8 +575,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
510 struct _sas_device *sas_device) 575 struct _sas_device *sas_device)
511{ 576{
512 unsigned long flags; 577 unsigned long flags;
513 u16 handle, parent_handle;
514 u64 sas_address;
515 578
516 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 579 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
517 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 580 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
@@ -521,10 +584,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
521 list_add_tail(&sas_device->list, &ioc->sas_device_list); 584 list_add_tail(&sas_device->list, &ioc->sas_device_list);
522 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 585 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
523 586
524 handle = sas_device->handle; 587 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
525 parent_handle = sas_device->parent_handle; 588 sas_device->sas_address_parent))
526 sas_address = sas_device->sas_address;
527 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle))
528 _scsih_sas_device_remove(ioc, sas_device); 589 _scsih_sas_device_remove(ioc, sas_device);
529} 590}
530 591
@@ -553,31 +614,6 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
553} 614}
554 615
555/** 616/**
556 * mpt2sas_scsih_expander_find_by_handle - expander device search
557 * @ioc: per adapter object
558 * @handle: expander handle (assigned by firmware)
559 * Context: Calling function should acquire ioc->sas_device_lock
560 *
561 * This searches for expander device based on handle, then returns the
562 * sas_node object.
563 */
564struct _sas_node *
565mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
566{
567 struct _sas_node *sas_expander, *r;
568
569 r = NULL;
570 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
571 if (sas_expander->handle != handle)
572 continue;
573 r = sas_expander;
574 goto out;
575 }
576 out:
577 return r;
578}
579
580/**
581 * _scsih_raid_device_find_by_id - raid device search 617 * _scsih_raid_device_find_by_id - raid device search
582 * @ioc: per adapter object 618 * @ioc: per adapter object
583 * @id: sas device target id 619 * @id: sas device target id
@@ -699,6 +735,31 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
699} 735}
700 736
701/** 737/**
738 * mpt2sas_scsih_expander_find_by_handle - expander device search
739 * @ioc: per adapter object
740 * @handle: expander handle (assigned by firmware)
741 * Context: Calling function should acquire ioc->sas_device_lock
742 *
743 * This searches for expander device based on handle, then returns the
744 * sas_node object.
745 */
746struct _sas_node *
747mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
748{
749 struct _sas_node *sas_expander, *r;
750
751 r = NULL;
752 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
753 if (sas_expander->handle != handle)
754 continue;
755 r = sas_expander;
756 goto out;
757 }
758 out:
759 return r;
760}
761
762/**
702 * mpt2sas_scsih_expander_find_by_sas_address - expander device search 763 * mpt2sas_scsih_expander_find_by_sas_address - expander device search
703 * @ioc: per adapter object 764 * @ioc: per adapter object
704 * @sas_address: sas address 765 * @sas_address: sas address
@@ -1043,17 +1104,46 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1043 * _scsih_change_queue_depth - setting device queue depth 1104 * _scsih_change_queue_depth - setting device queue depth
1044 * @sdev: scsi device struct 1105 * @sdev: scsi device struct
1045 * @qdepth: requested queue depth 1106 * @qdepth: requested queue depth
1107 * @reason: calling context
1046 * 1108 *
1047 * Returns queue depth. 1109 * Returns queue depth.
1048 */ 1110 */
1049static int 1111static int
1050_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) 1112_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1051{ 1113{
1052 struct Scsi_Host *shost = sdev->host; 1114 struct Scsi_Host *shost = sdev->host;
1053 int max_depth; 1115 int max_depth;
1054 int tag_type; 1116 int tag_type;
1117 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1118 struct MPT2SAS_DEVICE *sas_device_priv_data;
1119 struct MPT2SAS_TARGET *sas_target_priv_data;
1120 struct _sas_device *sas_device;
1121 unsigned long flags;
1122
1123 if (reason != SCSI_QDEPTH_DEFAULT)
1124 return -EOPNOTSUPP;
1055 1125
1056 max_depth = shost->can_queue; 1126 max_depth = shost->can_queue;
1127
1128 /* limit max device queue for SATA to 32 */
1129 sas_device_priv_data = sdev->hostdata;
1130 if (!sas_device_priv_data)
1131 goto not_sata;
1132 sas_target_priv_data = sas_device_priv_data->sas_target;
1133 if (!sas_target_priv_data)
1134 goto not_sata;
1135 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
1136 goto not_sata;
1137 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1138 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1139 sas_device_priv_data->sas_target->sas_address);
1140 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1141 if (sas_device && sas_device->device_info &
1142 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1143 max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
1144
1145 not_sata:
1146
1057 if (!sdev->tagged_supported) 1147 if (!sdev->tagged_supported)
1058 max_depth = 1; 1148 max_depth = 1;
1059 if (qdepth > max_depth) 1149 if (qdepth > max_depth)
@@ -1220,7 +1310,6 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1220 struct MPT2SAS_DEVICE *sas_device_priv_data; 1310 struct MPT2SAS_DEVICE *sas_device_priv_data;
1221 struct scsi_target *starget; 1311 struct scsi_target *starget;
1222 struct _raid_device *raid_device; 1312 struct _raid_device *raid_device;
1223 struct _sas_device *sas_device;
1224 unsigned long flags; 1313 unsigned long flags;
1225 1314
1226 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); 1315 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@@ -1247,21 +1336,8 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1247 if (raid_device) 1336 if (raid_device)
1248 raid_device->sdev = sdev; /* raid is single lun */ 1337 raid_device->sdev = sdev; /* raid is single lun */
1249 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1338 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1250 } else {
1251 /* set TLR bit for SSP devices */
1252 if (!(ioc->facts.IOCCapabilities &
1253 MPI2_IOCFACTS_CAPABILITY_TLR))
1254 goto out;
1255 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1256 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1257 sas_device_priv_data->sas_target->sas_address);
1258 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1259 if (sas_device && sas_device->device_info &
1260 MPI2_SAS_DEVICE_INFO_SSP_TARGET)
1261 sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON;
1262 } 1339 }
1263 1340
1264 out:
1265 return 0; 1341 return 0;
1266} 1342}
1267 1343
@@ -1334,6 +1410,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1334} 1410}
1335 1411
1336/** 1412/**
1413 * _scsih_is_raid - return boolean indicating device is raid volume
1414 * @dev the device struct object
1415 */
1416static int
1417_scsih_is_raid(struct device *dev)
1418{
1419 struct scsi_device *sdev = to_scsi_device(dev);
1420
1421 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1422}
1423
1424/**
1425 * _scsih_get_resync - get raid volume resync percent complete
1426 * @dev the device struct object
1427 */
1428static void
1429_scsih_get_resync(struct device *dev)
1430{
1431 struct scsi_device *sdev = to_scsi_device(dev);
1432 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1433 static struct _raid_device *raid_device;
1434 unsigned long flags;
1435 Mpi2RaidVolPage0_t vol_pg0;
1436 Mpi2ConfigReply_t mpi_reply;
1437 u32 volume_status_flags;
1438 u8 percent_complete = 0;
1439
1440 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1441 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1442 sdev->channel);
1443 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1444
1445 if (!raid_device)
1446 goto out;
1447
1448 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1449 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1450 sizeof(Mpi2RaidVolPage0_t))) {
1451 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1452 ioc->name, __FILE__, __LINE__, __func__);
1453 goto out;
1454 }
1455
1456 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1457 if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
1458 percent_complete = raid_device->percent_complete;
1459 out:
1460 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
1461}
1462
1463/**
1464 * _scsih_get_state - get raid volume level
1465 * @dev the device struct object
1466 */
1467static void
1468_scsih_get_state(struct device *dev)
1469{
1470 struct scsi_device *sdev = to_scsi_device(dev);
1471 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1472 static struct _raid_device *raid_device;
1473 unsigned long flags;
1474 Mpi2RaidVolPage0_t vol_pg0;
1475 Mpi2ConfigReply_t mpi_reply;
1476 u32 volstate;
1477 enum raid_state state = RAID_STATE_UNKNOWN;
1478
1479 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1480 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1481 sdev->channel);
1482 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1483
1484 if (!raid_device)
1485 goto out;
1486
1487 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1488 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1489 sizeof(Mpi2RaidVolPage0_t))) {
1490 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1491 ioc->name, __FILE__, __LINE__, __func__);
1492 goto out;
1493 }
1494
1495 volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1496 if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
1497 state = RAID_STATE_RESYNCING;
1498 goto out;
1499 }
1500
1501 switch (vol_pg0.VolumeState) {
1502 case MPI2_RAID_VOL_STATE_OPTIMAL:
1503 case MPI2_RAID_VOL_STATE_ONLINE:
1504 state = RAID_STATE_ACTIVE;
1505 break;
1506 case MPI2_RAID_VOL_STATE_DEGRADED:
1507 state = RAID_STATE_DEGRADED;
1508 break;
1509 case MPI2_RAID_VOL_STATE_FAILED:
1510 case MPI2_RAID_VOL_STATE_MISSING:
1511 state = RAID_STATE_OFFLINE;
1512 break;
1513 }
1514 out:
1515 raid_set_state(mpt2sas_raid_template, dev, state);
1516}
1517
1518/**
1519 * _scsih_set_level - set raid level
1520 * @sdev: scsi device struct
1521 * @raid_device: raid_device object
1522 */
1523static void
1524_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1525{
1526 enum raid_level level = RAID_LEVEL_UNKNOWN;
1527
1528 switch (raid_device->volume_type) {
1529 case MPI2_RAID_VOL_TYPE_RAID0:
1530 level = RAID_LEVEL_0;
1531 break;
1532 case MPI2_RAID_VOL_TYPE_RAID10:
1533 level = RAID_LEVEL_10;
1534 break;
1535 case MPI2_RAID_VOL_TYPE_RAID1E:
1536 level = RAID_LEVEL_1E;
1537 break;
1538 case MPI2_RAID_VOL_TYPE_RAID1:
1539 level = RAID_LEVEL_1;
1540 break;
1541 }
1542
1543 raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
1544}
1545
1546/**
1337 * _scsih_get_volume_capabilities - volume capabilities 1547 * _scsih_get_volume_capabilities - volume capabilities
1338 * @ioc: per adapter object 1548 * @ioc: per adapter object
1339 * @sas_device: the raid_device object 1549 * @sas_device: the raid_device object
@@ -1394,6 +1604,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1394} 1604}
1395 1605
1396/** 1606/**
1607 * _scsih_enable_tlr - setting TLR flags
1608 * @ioc: per adapter object
1609 * @sdev: scsi device struct
1610 *
1611 * Enabling Transaction Layer Retries for tape devices when
1612 * vpd page 0x90 is present
1613 *
1614 */
1615static void
1616_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev)
1617{
1618 /* only for TAPE */
1619 if (sdev->type != TYPE_TAPE)
1620 return;
1621
1622 if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
1623 return;
1624
1625 sas_enable_tlr(sdev);
1626 sdev_printk(KERN_INFO, sdev, "TLR %s\n",
1627 sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
1628 return;
1629
1630}
1631
1632/**
1397 * _scsih_slave_configure - device configure routine. 1633 * _scsih_slave_configure - device configure routine.
1398 * @sdev: scsi device struct 1634 * @sdev: scsi device struct
1399 * 1635 *
@@ -1488,7 +1724,9 @@ _scsih_slave_configure(struct scsi_device *sdev)
1488 r_level, raid_device->handle, 1724 r_level, raid_device->handle,
1489 (unsigned long long)raid_device->wwid, 1725 (unsigned long long)raid_device->wwid,
1490 raid_device->num_pds, ds); 1726 raid_device->num_pds, ds);
1491 _scsih_change_queue_depth(sdev, qdepth); 1727 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1728 /* raid transport support */
1729 _scsih_set_level(sdev, raid_device);
1492 return 0; 1730 return 0;
1493 } 1731 }
1494 1732
@@ -1534,10 +1772,12 @@ _scsih_slave_configure(struct scsi_device *sdev)
1534 _scsih_display_sata_capabilities(ioc, sas_device, sdev); 1772 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
1535 } 1773 }
1536 1774
1537 _scsih_change_queue_depth(sdev, qdepth); 1775 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1538 1776
1539 if (ssp_target) 1777 if (ssp_target) {
1540 sas_read_port_mode_page(sdev); 1778 sas_read_port_mode_page(sdev);
1779 _scsih_enable_tlr(ioc, sdev);
1780 }
1541 return 0; 1781 return 0;
1542} 1782}
1543 1783
@@ -1874,6 +2114,8 @@ _scsih_abort(struct scsi_cmnd *scmd)
1874 goto out; 2114 goto out;
1875 } 2115 }
1876 2116
2117 mpt2sas_halt_firmware(ioc);
2118
1877 mutex_lock(&ioc->tm_cmds.mutex); 2119 mutex_lock(&ioc->tm_cmds.mutex);
1878 handle = sas_device_priv_data->sas_target->handle; 2120 handle = sas_device_priv_data->sas_target->handle;
1879 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, 2121 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
@@ -2297,7 +2539,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2297 u16 handle; 2539 u16 handle;
2298 u16 reason_code; 2540 u16 reason_code;
2299 u8 phy_number; 2541 u8 phy_number;
2300 u8 link_rate;
2301 2542
2302 for (i = 0; i < event_data->NumEntries; i++) { 2543 for (i = 0; i < event_data->NumEntries; i++) {
2303 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 2544 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2308,11 +2549,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2308 MPI2_EVENT_SAS_TOPO_RC_MASK; 2549 MPI2_EVENT_SAS_TOPO_RC_MASK;
2309 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) 2550 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2310 _scsih_block_io_device(ioc, handle); 2551 _scsih_block_io_device(ioc, handle);
2311 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
2312 link_rate = event_data->PHY[i].LinkRate >> 4;
2313 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
2314 _scsih_ublock_io_device(ioc, handle);
2315 }
2316 } 2552 }
2317} 2553}
2318 2554
@@ -2349,16 +2585,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2349 2585
2350 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2586 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2351 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2587 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2352 if (!sas_device) {
2353 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2354 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2355 ioc->name, __func__);
2356 return;
2357 }
2358 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2588 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2359 2589
2360 /* skip is hidden raid component */ 2590 /* skip is hidden raid component */
2361 if (sas_device->hidden_raid_component) 2591 if (sas_device && sas_device->hidden_raid_component)
2362 return; 2592 return;
2363 2593
2364 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2594 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2371,18 +2601,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2371 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2601 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2372 list_add_tail(&delayed_tr->list, 2602 list_add_tail(&delayed_tr->list,
2373 &ioc->delayed_tr_list); 2603 &ioc->delayed_tr_list);
2374 if (sas_device->starget) 2604 if (sas_device && sas_device->starget) {
2375 dewtprintk(ioc, starget_printk(KERN_INFO, 2605 dewtprintk(ioc, starget_printk(KERN_INFO,
2376 sas_device->starget, "DELAYED:tr:handle(0x%04x), " 2606 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2377 "(open)\n", sas_device->handle)); 2607 "(open)\n", handle));
2608 } else {
2609 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2610 "DELAYED:tr:handle(0x%04x), (open)\n",
2611 ioc->name, handle));
2612 }
2378 return; 2613 return;
2379 } 2614 }
2380 2615
2381 if (sas_device->starget && sas_device->starget->hostdata) { 2616 if (sas_device) {
2382 sas_target_priv_data = sas_device->starget->hostdata; 2617 sas_device->state |= MPTSAS_STATE_TR_SEND;
2383 sas_target_priv_data->tm_busy = 1; 2618 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2384 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2619 if (sas_device->starget && sas_device->starget->hostdata) {
2385 "tr:handle(0x%04x), (open)\n", sas_device->handle)); 2620 sas_target_priv_data = sas_device->starget->hostdata;
2621 sas_target_priv_data->tm_busy = 1;
2622 dewtprintk(ioc, starget_printk(KERN_INFO,
2623 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2624 handle));
2625 }
2626 } else {
2627 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2628 "tr:handle(0x%04x), (open)\n", ioc->name, handle));
2386 } 2629 }
2387 2630
2388 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2390,8 +2633,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2390 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2633 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2391 mpi_request->DevHandle = cpu_to_le16(handle); 2634 mpi_request->DevHandle = cpu_to_le16(handle);
2392 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 2635 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2393 sas_device->state |= MPTSAS_STATE_TR_SEND;
2394 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2395 mpt2sas_base_put_smid_hi_priority(ioc, smid); 2636 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2396} 2637}
2397 2638
@@ -2426,21 +2667,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2426 2667
2427 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2668 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2428 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2669 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2429 if (!sas_device) {
2430 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2431 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2432 ioc->name, __func__);
2433 return 1;
2434 }
2435 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2436 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2670 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2437 2671
2438 if (sas_device->starget) 2672 if (sas_device) {
2439 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2673 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2674 if (sas_device->starget)
2675 dewtprintk(ioc, starget_printk(KERN_INFO,
2676 sas_device->starget,
2677 "sc_complete:handle(0x%04x), "
2678 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2679 handle, le16_to_cpu(mpi_reply->IOCStatus),
2680 le32_to_cpu(mpi_reply->IOCLogInfo)));
2681 } else {
2682 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2440 "sc_complete:handle(0x%04x), " 2683 "sc_complete:handle(0x%04x), "
2441 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2684 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2442 handle, le16_to_cpu(mpi_reply->IOCStatus), 2685 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
2443 le32_to_cpu(mpi_reply->IOCLogInfo))); 2686 le32_to_cpu(mpi_reply->IOCLogInfo)));
2687 }
2688
2444 return 1; 2689 return 1;
2445} 2690}
2446 2691
@@ -2478,28 +2723,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2478 handle = le16_to_cpu(mpi_reply->DevHandle); 2723 handle = le16_to_cpu(mpi_reply->DevHandle);
2479 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2724 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2480 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2725 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2481 if (!sas_device) {
2482 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2483 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2484 ioc->name, __func__);
2485 return 1;
2486 }
2487 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2488 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2726 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2489 2727
2490 if (sas_device->starget) 2728 if (sas_device) {
2491 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2729 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2492 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " 2730 if (sas_device->starget) {
2493 "loginfo(0x%08x), completed(%d)\n", 2731 dewtprintk(ioc, starget_printk(KERN_INFO,
2494 sas_device->handle, (sas_device->state & 2732 sas_device->starget, "tr_complete:handle(0x%04x), "
2495 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", 2733 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2496 le16_to_cpu(mpi_reply->IOCStatus), 2734 "completed(%d)\n", sas_device->handle,
2735 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2736 "open" : "active",
2737 le16_to_cpu(mpi_reply->IOCStatus),
2738 le32_to_cpu(mpi_reply->IOCLogInfo),
2739 le32_to_cpu(mpi_reply->TerminationCount)));
2740 if (sas_device->starget->hostdata) {
2741 sas_target_priv_data =
2742 sas_device->starget->hostdata;
2743 sas_target_priv_data->tm_busy = 0;
2744 }
2745 }
2746 } else {
2747 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2748 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2749 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2750 handle, le16_to_cpu(mpi_reply->IOCStatus),
2497 le32_to_cpu(mpi_reply->IOCLogInfo), 2751 le32_to_cpu(mpi_reply->IOCLogInfo),
2498 le32_to_cpu(mpi_reply->TerminationCount))); 2752 le32_to_cpu(mpi_reply->TerminationCount)));
2499
2500 if (sas_device->starget && sas_device->starget->hostdata) {
2501 sas_target_priv_data = sas_device->starget->hostdata;
2502 sas_target_priv_data->tm_busy = 0;
2503 } 2753 }
2504 2754
2505 if (!list_empty(&ioc->delayed_tr_list)) { 2755 if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2514,8 +2764,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2514 } else 2764 } else
2515 rc = 1; 2765 rc = 1;
2516 2766
2517 2767 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2518 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2519 return rc; 2768 return rc;
2520 2769
2521 if (ioc->shost_recovery) { 2770 if (ioc->shost_recovery) {
@@ -2531,12 +2780,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2531 return rc; 2780 return rc;
2532 } 2781 }
2533 2782
2783 if (sas_device)
2784 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2785
2534 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2786 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2535 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2787 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2536 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2788 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2537 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2789 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2538 mpi_request->DevHandle = mpi_reply->DevHandle; 2790 mpi_request->DevHandle = mpi_reply->DevHandle;
2539 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2540 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2791 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2541 return rc; 2792 return rc;
2542} 2793}
@@ -2678,8 +2929,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2678 else 2929 else
2679 return; 2930 return;
2680 2931
2681 mpi_request->EEDPBlockSize = scmd->device->sector_size;
2682
2683 switch (prot_type) { 2932 switch (prot_type) {
2684 case SCSI_PROT_DIF_TYPE1: 2933 case SCSI_PROT_DIF_TYPE1:
2685 2934
@@ -2687,8 +2936,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2687 * enable ref/guard checking 2936 * enable ref/guard checking
2688 * auto increment ref tag 2937 * auto increment ref tag
2689 */ 2938 */
2690 mpi_request->EEDPFlags = eedp_flags | 2939 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2691 MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2692 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | 2940 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
2693 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; 2941 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2694 mpi_request->CDB.EEDP32.PrimaryReferenceTag = 2942 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
@@ -2701,11 +2949,11 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2701 /* 2949 /*
2702 * enable guard checking 2950 * enable guard checking
2703 */ 2951 */
2704 mpi_request->EEDPFlags = eedp_flags | 2952 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2705 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2706
2707 break; 2953 break;
2708 } 2954 }
2955 mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
2956 mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
2709} 2957}
2710 2958
2711/** 2959/**
@@ -2788,7 +3036,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2788 } 3036 }
2789 3037
2790 /* see if we are busy with task managment stuff */ 3038 /* see if we are busy with task managment stuff */
2791 if (sas_target_priv_data->tm_busy) 3039 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
2792 return SCSI_MLQUEUE_DEVICE_BUSY; 3040 return SCSI_MLQUEUE_DEVICE_BUSY;
2793 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) 3041 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2794 return SCSI_MLQUEUE_HOST_BUSY; 3042 return SCSI_MLQUEUE_HOST_BUSY;
@@ -2815,8 +3063,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2815 3063
2816 } else 3064 } else
2817 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 3065 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
2818 3066 /* Make sure Device is not raid volume */
2819 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) 3067 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3068 sas_is_tlr_enabled(scmd->device))
2820 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; 3069 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
2821 3070
2822 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); 3071 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -2842,7 +3091,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2842 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; 3091 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
2843 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; 3092 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
2844 mpi_request->SenseBufferLowAddress = 3093 mpi_request->SenseBufferLowAddress =
2845 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 3094 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
2846 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; 3095 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2847 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + 3096 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2848 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); 3097 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
@@ -2894,7 +3143,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
2894 3143
2895#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 3144#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
2896/** 3145/**
2897 * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request 3146 * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request
2898 * @ioc: per adapter object 3147 * @ioc: per adapter object
2899 * @scmd: pointer to scsi command object 3148 * @scmd: pointer to scsi command object
2900 * @mpi_reply: reply mf payload returned from firmware 3149 * @mpi_reply: reply mf payload returned from firmware
@@ -3059,7 +3308,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3059 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 3308 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
3060 response_info = le32_to_cpu(mpi_reply->ResponseInfo); 3309 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
3061 response_bytes = (u8 *)&response_info; 3310 response_bytes = (u8 *)&response_info;
3062 _scsih_response_code(ioc, response_bytes[3]); 3311 _scsih_response_code(ioc, response_bytes[0]);
3063 } 3312 }
3064} 3313}
3065#endif 3314#endif
@@ -3177,7 +3426,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3177 u8 scsi_status; 3426 u8 scsi_status;
3178 u32 log_info; 3427 u32 log_info;
3179 struct MPT2SAS_DEVICE *sas_device_priv_data; 3428 struct MPT2SAS_DEVICE *sas_device_priv_data;
3180 u32 response_code; 3429 u32 response_code = 0;
3181 3430
3182 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 3431 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3183 scmd = _scsih_scsi_lookup_get(ioc, smid); 3432 scmd = _scsih_scsi_lookup_get(ioc, smid);
@@ -3199,15 +3448,17 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3199 } 3448 }
3200 3449
3201 /* turning off TLR */ 3450 /* turning off TLR */
3451 scsi_state = mpi_reply->SCSIState;
3452 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
3453 response_code =
3454 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
3202 if (!sas_device_priv_data->tlr_snoop_check) { 3455 if (!sas_device_priv_data->tlr_snoop_check) {
3203 sas_device_priv_data->tlr_snoop_check++; 3456 sas_device_priv_data->tlr_snoop_check++;
3204 if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) { 3457 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3205 response_code = (le32_to_cpu(mpi_reply->ResponseInfo) 3458 sas_is_tlr_enabled(scmd->device) &&
3206 >> 24); 3459 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
3207 if (response_code == 3460 sas_disable_tlr(scmd->device);
3208 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) 3461 sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
3209 sas_device_priv_data->flags &=
3210 ~MPT_DEVICE_TLR_ON;
3211 } 3462 }
3212 } 3463 }
3213 3464
@@ -3219,7 +3470,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3219 else 3470 else
3220 log_info = 0; 3471 log_info = 0;
3221 ioc_status &= MPI2_IOCSTATUS_MASK; 3472 ioc_status &= MPI2_IOCSTATUS_MASK;
3222 scsi_state = mpi_reply->SCSIState;
3223 scsi_status = mpi_reply->SCSIStatus; 3473 scsi_status = mpi_reply->SCSIStatus;
3224 3474
3225 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && 3475 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
@@ -3255,10 +3505,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3255 3505
3256 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 3506 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
3257 if (sas_device_priv_data->block) { 3507 if (sas_device_priv_data->block) {
3258 scmd->result = (DID_BUS_BUSY << 16); 3508 scmd->result = DID_TRANSPORT_DISRUPTED << 16;
3259 break; 3509 goto out;
3260 } 3510 }
3261
3262 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 3511 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
3263 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 3512 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
3264 scmd->result = DID_RESET << 16; 3513 scmd->result = DID_RESET << 16;
@@ -3304,8 +3553,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3304 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: 3553 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
3305 case MPI2_IOCSTATUS_SUCCESS: 3554 case MPI2_IOCSTATUS_SUCCESS:
3306 scmd->result = (DID_OK << 16) | scsi_status; 3555 scmd->result = (DID_OK << 16) | scsi_status;
3307 if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | 3556 if (response_code ==
3308 MPI2_SCSI_STATE_NO_SCSI_STATUS)) 3557 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
3558 (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
3559 MPI2_SCSI_STATE_NO_SCSI_STATUS)))
3309 scmd->result = DID_SOFT_ERROR << 16; 3560 scmd->result = DID_SOFT_ERROR << 16;
3310 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) 3561 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3311 scmd->result = DID_RESET << 16; 3562 scmd->result = DID_RESET << 16;
@@ -3344,7 +3595,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3344/** 3595/**
3345 * _scsih_sas_host_refresh - refreshing sas host object contents 3596 * _scsih_sas_host_refresh - refreshing sas host object contents
3346 * @ioc: per adapter object 3597 * @ioc: per adapter object
3347 * @update: update link information
3348 * Context: user 3598 * Context: user
3349 * 3599 *
3350 * During port enable, fw will send topology events for every device. Its 3600 * During port enable, fw will send topology events for every device. Its
@@ -3354,13 +3604,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3354 * Return nothing. 3604 * Return nothing.
3355 */ 3605 */
3356static void 3606static void
3357_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) 3607_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
3358{ 3608{
3359 u16 sz; 3609 u16 sz;
3360 u16 ioc_status; 3610 u16 ioc_status;
3361 int i; 3611 int i;
3362 Mpi2ConfigReply_t mpi_reply; 3612 Mpi2ConfigReply_t mpi_reply;
3363 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; 3613 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3614 u16 attached_handle;
3364 3615
3365 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT 3616 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3366 "updating handles for sas_host(0x%016llx)\n", 3617 "updating handles for sas_host(0x%016llx)\n",
@@ -3374,27 +3625,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
3374 ioc->name, __FILE__, __LINE__, __func__); 3625 ioc->name, __FILE__, __LINE__, __func__);
3375 return; 3626 return;
3376 } 3627 }
3377 if (!(mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3378 sas_iounit_pg0, sz))) {
3379 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3380 MPI2_IOCSTATUS_MASK;
3381 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3382 goto out;
3383 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3384 ioc->sas_hba.phy[i].handle =
3385 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3386 ControllerDevHandle);
3387 if (update)
3388 mpt2sas_transport_update_links(
3389 ioc,
3390 ioc->sas_hba.phy[i].handle,
3391 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3392 AttachedDevHandle), i,
3393 sas_iounit_pg0->PhyData[i].
3394 NegotiatedLinkRate >> 4);
3395 }
3396 }
3397 3628
3629 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3630 sas_iounit_pg0, sz)) != 0)
3631 goto out;
3632 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
3633 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3634 goto out;
3635 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3636 if (i == 0)
3637 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3638 PhyData[0].ControllerDevHandle);
3639 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3640 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
3641 AttachedDevHandle);
3642 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
3643 attached_handle, i, sas_iounit_pg0->PhyData[i].
3644 NegotiatedLinkRate >> 4);
3645 }
3398 out: 3646 out:
3399 kfree(sas_iounit_pg0); 3647 kfree(sas_iounit_pg0);
3400} 3648}
@@ -3507,19 +3755,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
3507 ioc->name, __FILE__, __LINE__, __func__); 3755 ioc->name, __FILE__, __LINE__, __func__);
3508 goto out; 3756 goto out;
3509 } 3757 }
3510 ioc->sas_hba.phy[i].handle = 3758
3511 le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle); 3759 if (i == 0)
3760 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3761 PhyData[0].ControllerDevHandle);
3762 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3512 ioc->sas_hba.phy[i].phy_id = i; 3763 ioc->sas_hba.phy[i].phy_id = i;
3513 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], 3764 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
3514 phy_pg0, ioc->sas_hba.parent_dev); 3765 phy_pg0, ioc->sas_hba.parent_dev);
3515 } 3766 }
3516 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 3767 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
3517 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.phy[0].handle))) { 3768 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
3518 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3769 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3519 ioc->name, __FILE__, __LINE__, __func__); 3770 ioc->name, __FILE__, __LINE__, __func__);
3520 goto out; 3771 goto out;
3521 } 3772 }
3522 ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
3523 ioc->sas_hba.enclosure_handle = 3773 ioc->sas_hba.enclosure_handle =
3524 le16_to_cpu(sas_device_pg0.EnclosureHandle); 3774 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3525 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 3775 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
@@ -3562,7 +3812,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3562 Mpi2SasEnclosurePage0_t enclosure_pg0; 3812 Mpi2SasEnclosurePage0_t enclosure_pg0;
3563 u32 ioc_status; 3813 u32 ioc_status;
3564 u16 parent_handle; 3814 u16 parent_handle;
3565 __le64 sas_address; 3815 __le64 sas_address, sas_address_parent = 0;
3566 int i; 3816 int i;
3567 unsigned long flags; 3817 unsigned long flags;
3568 struct _sas_port *mpt2sas_port = NULL; 3818 struct _sas_port *mpt2sas_port = NULL;
@@ -3591,10 +3841,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3591 3841
3592 /* handle out of order topology events */ 3842 /* handle out of order topology events */
3593 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); 3843 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
3594 if (parent_handle >= ioc->sas_hba.num_phys) { 3844 if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
3845 != 0) {
3846 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3847 ioc->name, __FILE__, __LINE__, __func__);
3848 return -1;
3849 }
3850 if (sas_address_parent != ioc->sas_hba.sas_address) {
3595 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3851 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3596 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 3852 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3597 parent_handle); 3853 sas_address_parent);
3598 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3854 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3599 if (!sas_expander) { 3855 if (!sas_expander) {
3600 rc = _scsih_expander_add(ioc, parent_handle); 3856 rc = _scsih_expander_add(ioc, parent_handle);
@@ -3622,14 +3878,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3622 3878
3623 sas_expander->handle = handle; 3879 sas_expander->handle = handle;
3624 sas_expander->num_phys = expander_pg0.NumPhys; 3880 sas_expander->num_phys = expander_pg0.NumPhys;
3625 sas_expander->parent_handle = parent_handle; 3881 sas_expander->sas_address_parent = sas_address_parent;
3626 sas_expander->enclosure_handle =
3627 le16_to_cpu(expander_pg0.EnclosureHandle);
3628 sas_expander->sas_address = sas_address; 3882 sas_expander->sas_address = sas_address;
3629 3883
3630 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," 3884 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
3631 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, 3885 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
3632 handle, sas_expander->parent_handle, (unsigned long long) 3886 handle, parent_handle, (unsigned long long)
3633 sas_expander->sas_address, sas_expander->num_phys); 3887 sas_expander->sas_address, sas_expander->num_phys);
3634 3888
3635 if (!sas_expander->num_phys) 3889 if (!sas_expander->num_phys)
@@ -3645,7 +3899,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3645 3899
3646 INIT_LIST_HEAD(&sas_expander->sas_port_list); 3900 INIT_LIST_HEAD(&sas_expander->sas_port_list);
3647 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, 3901 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
3648 sas_expander->parent_handle); 3902 sas_address_parent);
3649 if (!mpt2sas_port) { 3903 if (!mpt2sas_port) {
3650 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3904 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3651 ioc->name, __FILE__, __LINE__, __func__); 3905 ioc->name, __FILE__, __LINE__, __func__);
@@ -3691,20 +3945,54 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3691 3945
3692 if (mpt2sas_port) 3946 if (mpt2sas_port)
3693 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 3947 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
3694 sas_expander->parent_handle); 3948 sas_address_parent);
3695 kfree(sas_expander); 3949 kfree(sas_expander);
3696 return rc; 3950 return rc;
3697} 3951}
3698 3952
3699/** 3953/**
3954 * _scsih_done - scsih callback handler.
3955 * @ioc: per adapter object
3956 * @smid: system request message index
3957 * @msix_index: MSIX table index supplied by the OS
3958 * @reply: reply message frame(lower 32bit addr)
3959 *
3960 * Callback handler when sending internal generated message frames.
3961 * The callback index passed is `ioc->scsih_cb_idx`
3962 *
3963 * Return 1 meaning mf should be freed from _base_interrupt
3964 * 0 means the mf is freed from this function.
3965 */
3966static u8
3967_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3968{
3969 MPI2DefaultReply_t *mpi_reply;
3970
3971 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3972 if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
3973 return 1;
3974 if (ioc->scsih_cmds.smid != smid)
3975 return 1;
3976 ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
3977 if (mpi_reply) {
3978 memcpy(ioc->scsih_cmds.reply, mpi_reply,
3979 mpi_reply->MsgLength*4);
3980 ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
3981 }
3982 ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
3983 complete(&ioc->scsih_cmds.done);
3984 return 1;
3985}
3986
3987/**
3700 * _scsih_expander_remove - removing expander object 3988 * _scsih_expander_remove - removing expander object
3701 * @ioc: per adapter object 3989 * @ioc: per adapter object
3702 * @handle: expander handle 3990 * @sas_address: expander sas_address
3703 * 3991 *
3704 * Return nothing. 3992 * Return nothing.
3705 */ 3993 */
3706static void 3994static void
3707_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) 3995_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3708{ 3996{
3709 struct _sas_node *sas_expander; 3997 struct _sas_node *sas_expander;
3710 unsigned long flags; 3998 unsigned long flags;
@@ -3713,7 +4001,8 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3713 return; 4001 return;
3714 4002
3715 spin_lock_irqsave(&ioc->sas_node_lock, flags); 4003 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3716 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); 4004 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
4005 sas_address);
3717 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 4006 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3718 _scsih_expander_node_remove(ioc, sas_expander); 4007 _scsih_expander_node_remove(ioc, sas_expander);
3719} 4008}
@@ -3805,8 +4094,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3805 } 4094 }
3806 4095
3807 sas_device->handle = handle; 4096 sas_device->handle = handle;
3808 sas_device->parent_handle = 4097 if (_scsih_get_sas_address(ioc, le16_to_cpu
3809 le16_to_cpu(sas_device_pg0.ParentDevHandle); 4098 (sas_device_pg0.ParentDevHandle),
4099 &sas_device->sas_address_parent) != 0)
4100 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4101 ioc->name, __FILE__, __LINE__, __func__);
3810 sas_device->enclosure_handle = 4102 sas_device->enclosure_handle =
3811 le16_to_cpu(sas_device_pg0.EnclosureHandle); 4103 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3812 sas_device->slot = 4104 sas_device->slot =
@@ -3836,43 +4128,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3836/** 4128/**
3837 * _scsih_remove_device - removing sas device object 4129 * _scsih_remove_device - removing sas device object
3838 * @ioc: per adapter object 4130 * @ioc: per adapter object
3839 * @handle: sas device handle 4131 * @sas_device: the sas_device object
3840 * 4132 *
3841 * Return nothing. 4133 * Return nothing.
3842 */ 4134 */
3843static void 4135static void
3844_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) 4136_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
4137 *sas_device)
3845{ 4138{
3846 struct MPT2SAS_TARGET *sas_target_priv_data; 4139 struct MPT2SAS_TARGET *sas_target_priv_data;
3847 struct _sas_device *sas_device;
3848 unsigned long flags;
3849 Mpi2SasIoUnitControlReply_t mpi_reply; 4140 Mpi2SasIoUnitControlReply_t mpi_reply;
3850 Mpi2SasIoUnitControlRequest_t mpi_request; 4141 Mpi2SasIoUnitControlRequest_t mpi_request;
3851 u16 device_handle; 4142 u16 device_handle, handle;
3852 4143
3853 /* lookup sas_device */ 4144 if (!sas_device)
3854 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3855 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
3856 if (!sas_device) {
3857 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3858 return; 4145 return;
3859 }
3860 4146
3861 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle" 4147 handle = sas_device->handle;
3862 "(0x%04x)\n", ioc->name, __func__, handle)); 4148 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
4149 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4150 (unsigned long long) sas_device->sas_address));
3863 4151
3864 if (sas_device->starget && sas_device->starget->hostdata) { 4152 if (sas_device->starget && sas_device->starget->hostdata) {
3865 sas_target_priv_data = sas_device->starget->hostdata; 4153 sas_target_priv_data = sas_device->starget->hostdata;
3866 sas_target_priv_data->deleted = 1; 4154 sas_target_priv_data->deleted = 1;
3867 } 4155 }
3868 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3869 4156
3870 if (ioc->remove_host) 4157 if (ioc->remove_host || ioc->shost_recovery || !handle)
3871 goto out; 4158 goto out;
3872 4159
3873 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { 4160 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
3874 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4161 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3875 "target_reset handle(0x%04x)\n", ioc->name, handle)); 4162 "target_reset handle(0x%04x)\n", ioc->name,
4163 handle));
3876 goto skip_tr; 4164 goto skip_tr;
3877 } 4165 }
3878 4166
@@ -3925,10 +4213,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3925 _scsih_ublock_io_device(ioc, handle); 4213 _scsih_ublock_io_device(ioc, handle);
3926 4214
3927 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 4215 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
3928 sas_device->parent_handle); 4216 sas_device->sas_address_parent);
3929 4217
3930 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 4218 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
3931 "(0x%016llx)\n", ioc->name, sas_device->handle, 4219 "(0x%016llx)\n", ioc->name, handle,
3932 (unsigned long long) sas_device->sas_address); 4220 (unsigned long long) sas_device->sas_address);
3933 _scsih_sas_device_remove(ioc, sas_device); 4221 _scsih_sas_device_remove(ioc, sas_device);
3934 4222
@@ -3952,7 +4240,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3952 u16 reason_code; 4240 u16 reason_code;
3953 u8 phy_number; 4241 u8 phy_number;
3954 char *status_str = NULL; 4242 char *status_str = NULL;
3955 char link_rate[25]; 4243 u8 link_rate, prev_link_rate;
3956 4244
3957 switch (event_data->ExpStatus) { 4245 switch (event_data->ExpStatus) {
3958 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 4246 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
@@ -3962,6 +4250,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3962 status_str = "remove"; 4250 status_str = "remove";
3963 break; 4251 break;
3964 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 4252 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
4253 case 0:
3965 status_str = "responding"; 4254 status_str = "responding";
3966 break; 4255 break;
3967 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 4256 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
@@ -3987,30 +4276,30 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3987 MPI2_EVENT_SAS_TOPO_RC_MASK; 4276 MPI2_EVENT_SAS_TOPO_RC_MASK;
3988 switch (reason_code) { 4277 switch (reason_code) {
3989 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4278 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3990 snprintf(link_rate, 25, ": add, link(0x%02x)", 4279 status_str = "target add";
3991 (event_data->PHY[i].LinkRate >> 4));
3992 status_str = link_rate;
3993 break; 4280 break;
3994 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4281 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
3995 status_str = ": remove"; 4282 status_str = "target remove";
3996 break; 4283 break;
3997 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 4284 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
3998 status_str = ": remove_delay"; 4285 status_str = "delay target remove";
3999 break; 4286 break;
4000 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4287 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4001 snprintf(link_rate, 25, ": link(0x%02x)", 4288 status_str = "link rate change";
4002 (event_data->PHY[i].LinkRate >> 4));
4003 status_str = link_rate;
4004 break; 4289 break;
4005 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 4290 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
4006 status_str = ": responding"; 4291 status_str = "target responding";
4007 break; 4292 break;
4008 default: 4293 default:
4009 status_str = ": unknown"; 4294 status_str = "unknown";
4010 break; 4295 break;
4011 } 4296 }
4012 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n", 4297 link_rate = event_data->PHY[i].LinkRate >> 4;
4013 phy_number, handle, status_str); 4298 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4299 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
4300 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
4301 handle, status_str, link_rate, prev_link_rate);
4302
4014 } 4303 }
4015} 4304}
4016#endif 4305#endif
@@ -4031,8 +4320,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4031 u16 reason_code; 4320 u16 reason_code;
4032 u8 phy_number; 4321 u8 phy_number;
4033 struct _sas_node *sas_expander; 4322 struct _sas_node *sas_expander;
4323 struct _sas_device *sas_device;
4324 u64 sas_address;
4034 unsigned long flags; 4325 unsigned long flags;
4035 u8 link_rate_; 4326 u8 link_rate, prev_link_rate;
4036 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; 4327 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
4037 4328
4038#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4329#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4040,10 +4331,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4040 _scsih_sas_topology_change_event_debug(ioc, event_data); 4331 _scsih_sas_topology_change_event_debug(ioc, event_data);
4041#endif 4332#endif
4042 4333
4334 if (ioc->shost_recovery)
4335 return;
4336
4043 if (!ioc->sas_hba.num_phys) 4337 if (!ioc->sas_hba.num_phys)
4044 _scsih_sas_host_add(ioc); 4338 _scsih_sas_host_add(ioc);
4045 else 4339 else
4046 _scsih_sas_host_refresh(ioc, 0); 4340 _scsih_sas_host_refresh(ioc);
4047 4341
4048 if (fw_event->ignore) { 4342 if (fw_event->ignore) {
4049 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " 4343 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
@@ -4058,6 +4352,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4058 if (_scsih_expander_add(ioc, parent_handle) != 0) 4352 if (_scsih_expander_add(ioc, parent_handle) != 0)
4059 return; 4353 return;
4060 4354
4355 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4356 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
4357 parent_handle);
4358 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4359 if (sas_expander)
4360 sas_address = sas_expander->sas_address;
4361 else if (parent_handle < ioc->sas_hba.num_phys)
4362 sas_address = ioc->sas_hba.sas_address;
4363 else
4364 return;
4365
4061 /* handle siblings events */ 4366 /* handle siblings events */
4062 for (i = 0; i < event_data->NumEntries; i++) { 4367 for (i = 0; i < event_data->NumEntries; i++) {
4063 if (fw_event->ignore) { 4368 if (fw_event->ignore) {
@@ -4077,48 +4382,47 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4077 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 4382 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
4078 if (!handle) 4383 if (!handle)
4079 continue; 4384 continue;
4080 link_rate_ = event_data->PHY[i].LinkRate >> 4; 4385 link_rate = event_data->PHY[i].LinkRate >> 4;
4386 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4081 switch (reason_code) { 4387 switch (reason_code) {
4082 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4388 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4389
4390 if (link_rate == prev_link_rate)
4391 break;
4392
4393 mpt2sas_transport_update_links(ioc, sas_address,
4394 handle, phy_number, link_rate);
4395
4396 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
4397 _scsih_ublock_io_device(ioc, handle);
4398 break;
4083 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4399 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4084 if (!parent_handle) { 4400
4085 if (phy_number < ioc->sas_hba.num_phys) 4401 mpt2sas_transport_update_links(ioc, sas_address,
4086 mpt2sas_transport_update_links( 4402 handle, phy_number, link_rate);
4087 ioc, 4403
4088 ioc->sas_hba.phy[phy_number].handle, 4404 _scsih_add_device(ioc, handle, phy_number, 0);
4089 handle, phy_number, link_rate_);
4090 } else {
4091 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4092 sas_expander =
4093 mpt2sas_scsih_expander_find_by_handle(ioc,
4094 parent_handle);
4095 spin_unlock_irqrestore(&ioc->sas_node_lock,
4096 flags);
4097 if (sas_expander) {
4098 if (phy_number < sas_expander->num_phys)
4099 mpt2sas_transport_update_links(
4100 ioc,
4101 sas_expander->
4102 phy[phy_number].handle,
4103 handle, phy_number,
4104 link_rate_);
4105 }
4106 }
4107 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
4108 if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
4109 break;
4110 _scsih_add_device(ioc, handle, phy_number, 0);
4111 }
4112 break; 4405 break;
4113 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4406 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
4114 _scsih_remove_device(ioc, handle); 4407
4408 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4409 sas_device = _scsih_sas_device_find_by_handle(ioc,
4410 handle);
4411 if (!sas_device) {
4412 spin_unlock_irqrestore(&ioc->sas_device_lock,
4413 flags);
4414 break;
4415 }
4416 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4417 _scsih_remove_device(ioc, sas_device);
4115 break; 4418 break;
4116 } 4419 }
4117 } 4420 }
4118 4421
4119 /* handle expander removal */ 4422 /* handle expander removal */
4120 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) 4423 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
4121 _scsih_expander_remove(ioc, parent_handle); 4424 sas_expander)
4425 _scsih_expander_remove(ioc, sas_address);
4122 4426
4123} 4427}
4124 4428
@@ -4170,6 +4474,12 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4170 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 4474 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
4171 reason_str = "internal async notification"; 4475 reason_str = "internal async notification";
4172 break; 4476 break;
4477 case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
4478 reason_str = "expander reduced functionality";
4479 break;
4480 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
4481 reason_str = "expander reduced functionality complete";
4482 break;
4173 default: 4483 default:
4174 reason_str = "unknown reason"; 4484 reason_str = "unknown reason";
4175 break; 4485 break;
@@ -4197,11 +4507,43 @@ static void
4197_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, 4507_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4198 struct fw_event_work *fw_event) 4508 struct fw_event_work *fw_event)
4199{ 4509{
4510 struct MPT2SAS_TARGET *target_priv_data;
4511 struct _sas_device *sas_device;
4512 __le64 sas_address;
4513 unsigned long flags;
4514 Mpi2EventDataSasDeviceStatusChange_t *event_data =
4515 fw_event->event_data;
4516
4200#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4517#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4201 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4518 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4202 _scsih_sas_device_status_change_event_debug(ioc, 4519 _scsih_sas_device_status_change_event_debug(ioc,
4203 fw_event->event_data); 4520 event_data);
4204#endif 4521#endif
4522
4523 if (!(event_data->ReasonCode ==
4524 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4525 event_data->ReasonCode ==
4526 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
4527 return;
4528
4529 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4530 sas_address = le64_to_cpu(event_data->SASAddress);
4531 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4532 sas_address);
4533 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4534
4535 if (!sas_device || !sas_device->starget)
4536 return;
4537
4538 target_priv_data = sas_device->starget->hostdata;
4539 if (!target_priv_data)
4540 return;
4541
4542 if (event_data->ReasonCode ==
4543 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
4544 target_priv_data->tm_busy = 1;
4545 else
4546 target_priv_data->tm_busy = 0;
4205} 4547}
4206 4548
4207#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4549#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4281,6 +4623,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4281#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4623#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4282 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; 4624 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4283#endif 4625#endif
4626 u16 ioc_status;
4284 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 4627 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4285 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 4628 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4286 event_data->PortWidth)); 4629 event_data->PortWidth));
@@ -4314,8 +4657,9 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4314 mpt2sas_scsih_issue_tm(ioc, handle, lun, 4657 mpt2sas_scsih_issue_tm(ioc, handle, lun,
4315 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); 4658 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
4316 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 4659 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4317 4660 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4318 if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) && 4661 & MPI2_IOCSTATUS_MASK;
4662 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
4319 (mpi_reply->ResponseCode == 4663 (mpi_reply->ResponseCode ==
4320 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || 4664 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4321 mpi_reply->ResponseCode == 4665 mpi_reply->ResponseCode ==
@@ -4570,7 +4914,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
4570 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4914 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4571 if (!sas_device) 4915 if (!sas_device)
4572 return; 4916 return;
4573 _scsih_remove_device(ioc, handle); 4917 _scsih_remove_device(ioc, sas_device);
4574} 4918}
4575 4919
4576/** 4920/**
@@ -4591,6 +4935,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4591 Mpi2ConfigReply_t mpi_reply; 4935 Mpi2ConfigReply_t mpi_reply;
4592 Mpi2SasDevicePage0_t sas_device_pg0; 4936 Mpi2SasDevicePage0_t sas_device_pg0;
4593 u32 ioc_status; 4937 u32 ioc_status;
4938 u64 sas_address;
4939 u16 parent_handle;
4594 4940
4595 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4941 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4596 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 4942 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -4615,9 +4961,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4615 return; 4961 return;
4616 } 4962 }
4617 4963
4618 mpt2sas_transport_update_links(ioc, 4964 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4619 le16_to_cpu(sas_device_pg0.ParentDevHandle), 4965 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4620 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 4966 mpt2sas_transport_update_links(ioc, sas_address, handle,
4967 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4621 4968
4622 _scsih_add_device(ioc, handle, 0, 1); 4969 _scsih_add_device(ioc, handle, 0, 1);
4623} 4970}
@@ -4857,7 +5204,7 @@ static void
4857_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, 5204_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4858 struct fw_event_work *fw_event) 5205 struct fw_event_work *fw_event)
4859{ 5206{
4860 u16 handle; 5207 u16 handle, parent_handle;
4861 u32 state; 5208 u32 state;
4862 struct _sas_device *sas_device; 5209 struct _sas_device *sas_device;
4863 unsigned long flags; 5210 unsigned long flags;
@@ -4865,6 +5212,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4865 Mpi2SasDevicePage0_t sas_device_pg0; 5212 Mpi2SasDevicePage0_t sas_device_pg0;
4866 u32 ioc_status; 5213 u32 ioc_status;
4867 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 5214 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
5215 u64 sas_address;
4868 5216
4869 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 5217 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4870 return; 5218 return;
@@ -4906,9 +5254,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4906 return; 5254 return;
4907 } 5255 }
4908 5256
4909 mpt2sas_transport_update_links(ioc, 5257 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4910 le16_to_cpu(sas_device_pg0.ParentDevHandle), 5258 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4911 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 5259 mpt2sas_transport_update_links(ioc, sas_address, handle,
5260 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4912 5261
4913 _scsih_add_device(ioc, handle, 0, 1); 5262 _scsih_add_device(ioc, handle, 0, 1);
4914 5263
@@ -4948,11 +5297,17 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4948 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 5297 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
4949 reason_str = "consistency check"; 5298 reason_str = "consistency check";
4950 break; 5299 break;
4951 default: 5300 case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
4952 reason_str = "unknown reason"; 5301 reason_str = "background init";
5302 break;
5303 case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
5304 reason_str = "make data consistent";
4953 break; 5305 break;
4954 } 5306 }
4955 5307
5308 if (!reason_str)
5309 return;
5310
4956 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)" 5311 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
4957 "\thandle(0x%04x), percent complete(%d)\n", 5312 "\thandle(0x%04x), percent complete(%d)\n",
4958 ioc->name, reason_str, 5313 ioc->name, reason_str,
@@ -4973,11 +5328,33 @@ static void
4973_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, 5328_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
4974 struct fw_event_work *fw_event) 5329 struct fw_event_work *fw_event)
4975{ 5330{
5331 Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
5332 static struct _raid_device *raid_device;
5333 unsigned long flags;
5334 u16 handle;
5335
4976#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5336#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4977 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 5337 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4978 _scsih_sas_ir_operation_status_event_debug(ioc, 5338 _scsih_sas_ir_operation_status_event_debug(ioc,
4979 fw_event->event_data); 5339 event_data);
4980#endif 5340#endif
5341
5342 /* code added for raid transport support */
5343 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
5344
5345 handle = le16_to_cpu(event_data->VolDevHandle);
5346
5347 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5348 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5349 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5350
5351 if (!raid_device)
5352 return;
5353
5354 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
5355 raid_device->percent_complete =
5356 event_data->PercentComplete;
5357 }
4981} 5358}
4982 5359
4983/** 5360/**
@@ -5252,18 +5629,23 @@ _scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5252{ 5629{
5253 struct _sas_node *sas_expander; 5630 struct _sas_node *sas_expander;
5254 unsigned long flags; 5631 unsigned long flags;
5632 int i;
5255 5633
5256 spin_lock_irqsave(&ioc->sas_node_lock, flags); 5634 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5257 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { 5635 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
5258 if (sas_expander->sas_address == sas_address) { 5636 if (sas_expander->sas_address != sas_address)
5259 sas_expander->responding = 1; 5637 continue;
5260 if (sas_expander->handle != handle) { 5638 sas_expander->responding = 1;
5261 printk(KERN_INFO "old handle(0x%04x)\n", 5639 if (sas_expander->handle == handle)
5262 sas_expander->handle);
5263 sas_expander->handle = handle;
5264 }
5265 goto out; 5640 goto out;
5266 } 5641 printk(KERN_INFO "\texpander(0x%016llx): handle changed"
5642 " from(0x%04x) to (0x%04x)!!!\n",
5643 (unsigned long long)sas_expander->sas_address,
5644 sas_expander->handle, handle);
5645 sas_expander->handle = handle;
5646 for (i = 0 ; i < sas_expander->num_phys ; i++)
5647 sas_expander->phy[i].handle = handle;
5648 goto out;
5267 } 5649 }
5268 out: 5650 out:
5269 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5651 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -5340,7 +5722,9 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5340 (unsigned long long) 5722 (unsigned long long)
5341 sas_device->enclosure_logical_id, 5723 sas_device->enclosure_logical_id,
5342 sas_device->slot); 5724 sas_device->slot);
5343 _scsih_remove_device(ioc, sas_device->handle); 5725 /* invalidate the device handle */
5726 sas_device->handle = 0;
5727 _scsih_remove_device(ioc, sas_device);
5344 } 5728 }
5345 5729
5346 list_for_each_entry_safe(raid_device, raid_device_next, 5730 list_for_each_entry_safe(raid_device, raid_device_next,
@@ -5366,7 +5750,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5366 sas_expander->responding = 0; 5750 sas_expander->responding = 0;
5367 continue; 5751 continue;
5368 } 5752 }
5369 _scsih_expander_remove(ioc, sas_expander->handle); 5753 _scsih_expander_remove(ioc, sas_expander->sas_address);
5370 goto retry_expander_search; 5754 goto retry_expander_search;
5371 } 5755 }
5372} 5756}
@@ -5406,7 +5790,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5406 case MPT2_IOC_DONE_RESET: 5790 case MPT2_IOC_DONE_RESET:
5407 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5791 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5408 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 5792 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5409 _scsih_sas_host_refresh(ioc, 0); 5793 _scsih_sas_host_refresh(ioc);
5410 _scsih_search_responding_sas_devices(ioc); 5794 _scsih_search_responding_sas_devices(ioc);
5411 _scsih_search_responding_raid_devices(ioc); 5795 _scsih_search_responding_raid_devices(ioc);
5412 _scsih_search_responding_expanders(ioc); 5796 _scsih_search_responding_expanders(ioc);
@@ -5646,7 +6030,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5646 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6030 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5647 if (!sas_device) 6031 if (!sas_device)
5648 continue; 6032 continue;
5649 _scsih_remove_device(ioc, sas_device->handle); 6033 _scsih_remove_device(ioc, sas_device);
5650 if (ioc->shost_recovery) 6034 if (ioc->shost_recovery)
5651 return; 6035 return;
5652 goto retry_device_search; 6036 goto retry_device_search;
@@ -5669,7 +6053,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5669 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 6053 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5670 if (!expander_sibling) 6054 if (!expander_sibling)
5671 continue; 6055 continue;
5672 _scsih_expander_remove(ioc, expander_sibling->handle); 6056 _scsih_expander_remove(ioc,
6057 expander_sibling->sas_address);
5673 if (ioc->shost_recovery) 6058 if (ioc->shost_recovery)
5674 return; 6059 return;
5675 goto retry_expander_search; 6060 goto retry_expander_search;
@@ -5677,7 +6062,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5677 } 6062 }
5678 6063
5679 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 6064 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
5680 sas_expander->parent_handle); 6065 sas_expander->sas_address_parent);
5681 6066
5682 printk(MPT2SAS_INFO_FMT "expander_remove: handle" 6067 printk(MPT2SAS_INFO_FMT "expander_remove: handle"
5683 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, 6068 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
@@ -5690,9 +6075,99 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5690} 6075}
5691 6076
5692/** 6077/**
6078 * _scsih_ir_shutdown - IR shutdown notification
6079 * @ioc: per adapter object
6080 *
6081 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
6082 * the host system is shutting down.
6083 *
6084 * Return nothing.
6085 */
6086static void
6087_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
6088{
6089 Mpi2RaidActionRequest_t *mpi_request;
6090 Mpi2RaidActionReply_t *mpi_reply;
6091 u16 smid;
6092
6093 /* is IR firmware build loaded ? */
6094 if (!ioc->ir_firmware)
6095 return;
6096
6097 /* are there any volumes ? */
6098 if (list_empty(&ioc->raid_device_list))
6099 return;
6100
6101 mutex_lock(&ioc->scsih_cmds.mutex);
6102
6103 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
6104 printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
6105 ioc->name, __func__);
6106 goto out;
6107 }
6108 ioc->scsih_cmds.status = MPT2_CMD_PENDING;
6109
6110 smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
6111 if (!smid) {
6112 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
6113 ioc->name, __func__);
6114 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
6115 goto out;
6116 }
6117
6118 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
6119 ioc->scsih_cmds.smid = smid;
6120 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
6121
6122 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
6123 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
6124
6125 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
6126 init_completion(&ioc->scsih_cmds.done);
6127 mpt2sas_base_put_smid_default(ioc, smid);
6128 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
6129
6130 if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
6131 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
6132 ioc->name, __func__);
6133 goto out;
6134 }
6135
6136 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
6137 mpi_reply = ioc->scsih_cmds.reply;
6138
6139 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
6140 "ioc_status(0x%04x), loginfo(0x%08x)\n",
6141 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
6142 le32_to_cpu(mpi_reply->IOCLogInfo));
6143 }
6144
6145 out:
6146 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
6147 mutex_unlock(&ioc->scsih_cmds.mutex);
6148}
6149
6150/**
6151 * _scsih_shutdown - routine call during system shutdown
6152 * @pdev: PCI device struct
6153 *
6154 * Return nothing.
6155 */
6156static void
6157_scsih_shutdown(struct pci_dev *pdev)
6158{
6159 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6160 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6161
6162 _scsih_ir_shutdown(ioc);
6163 mpt2sas_base_detach(ioc);
6164}
6165
6166/**
5693 * _scsih_remove - detach and remove add host 6167 * _scsih_remove - detach and remove add host
5694 * @pdev: PCI device struct 6168 * @pdev: PCI device struct
5695 * 6169 *
6170 * Routine called when unloading the driver.
5696 * Return nothing. 6171 * Return nothing.
5697 */ 6172 */
5698static void __devexit 6173static void __devexit
@@ -5703,6 +6178,8 @@ _scsih_remove(struct pci_dev *pdev)
5703 struct _sas_port *mpt2sas_port; 6178 struct _sas_port *mpt2sas_port;
5704 struct _sas_device *sas_device; 6179 struct _sas_device *sas_device;
5705 struct _sas_node *expander_sibling; 6180 struct _sas_node *expander_sibling;
6181 struct _raid_device *raid_device, *next;
6182 struct MPT2SAS_TARGET *sas_target_priv_data;
5706 struct workqueue_struct *wq; 6183 struct workqueue_struct *wq;
5707 unsigned long flags; 6184 unsigned long flags;
5708 6185
@@ -5716,6 +6193,21 @@ _scsih_remove(struct pci_dev *pdev)
5716 if (wq) 6193 if (wq)
5717 destroy_workqueue(wq); 6194 destroy_workqueue(wq);
5718 6195
6196 /* release all the volumes */
6197 list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
6198 list) {
6199 if (raid_device->starget) {
6200 sas_target_priv_data =
6201 raid_device->starget->hostdata;
6202 sas_target_priv_data->deleted = 1;
6203 scsi_remove_target(&raid_device->starget->dev);
6204 }
6205 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
6206 "(0x%016llx)\n", ioc->name, raid_device->handle,
6207 (unsigned long long) raid_device->wwid);
6208 _scsih_raid_device_remove(ioc, raid_device);
6209 }
6210
5719 /* free ports attached to the sas_host */ 6211 /* free ports attached to the sas_host */
5720 retry_again: 6212 retry_again:
5721 list_for_each_entry(mpt2sas_port, 6213 list_for_each_entry(mpt2sas_port,
@@ -5726,7 +6218,7 @@ _scsih_remove(struct pci_dev *pdev)
5726 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 6218 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5727 mpt2sas_port->remote_identify.sas_address); 6219 mpt2sas_port->remote_identify.sas_address);
5728 if (sas_device) { 6220 if (sas_device) {
5729 _scsih_remove_device(ioc, sas_device->handle); 6221 _scsih_remove_device(ioc, sas_device);
5730 goto retry_again; 6222 goto retry_again;
5731 } 6223 }
5732 } else { 6224 } else {
@@ -5735,7 +6227,7 @@ _scsih_remove(struct pci_dev *pdev)
5735 mpt2sas_port->remote_identify.sas_address); 6227 mpt2sas_port->remote_identify.sas_address);
5736 if (expander_sibling) { 6228 if (expander_sibling) {
5737 _scsih_expander_remove(ioc, 6229 _scsih_expander_remove(ioc,
5738 expander_sibling->handle); 6230 expander_sibling->sas_address);
5739 goto retry_again; 6231 goto retry_again;
5740 } 6232 }
5741 } 6233 }
@@ -5749,7 +6241,7 @@ _scsih_remove(struct pci_dev *pdev)
5749 } 6241 }
5750 6242
5751 sas_remove_host(shost); 6243 sas_remove_host(shost);
5752 mpt2sas_base_detach(ioc); 6244 _scsih_shutdown(pdev);
5753 list_del(&ioc->list); 6245 list_del(&ioc->list);
5754 scsi_remove_host(shost); 6246 scsi_remove_host(shost);
5755 scsi_host_put(shost); 6247 scsi_host_put(shost);
@@ -5770,7 +6262,8 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5770 void *device; 6262 void *device;
5771 struct _sas_device *sas_device; 6263 struct _sas_device *sas_device;
5772 struct _raid_device *raid_device; 6264 struct _raid_device *raid_device;
5773 u16 handle, parent_handle; 6265 u16 handle;
6266 u64 sas_address_parent;
5774 u64 sas_address; 6267 u64 sas_address;
5775 unsigned long flags; 6268 unsigned long flags;
5776 int rc; 6269 int rc;
@@ -5799,17 +6292,17 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5799 } else { 6292 } else {
5800 sas_device = device; 6293 sas_device = device;
5801 handle = sas_device->handle; 6294 handle = sas_device->handle;
5802 parent_handle = sas_device->parent_handle; 6295 sas_address_parent = sas_device->sas_address_parent;
5803 sas_address = sas_device->sas_address; 6296 sas_address = sas_device->sas_address;
5804 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6297 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5805 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6298 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5806 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6299 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5807 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 6300 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5808 sas_device->parent_handle)) { 6301 sas_device->sas_address_parent)) {
5809 _scsih_sas_device_remove(ioc, sas_device); 6302 _scsih_sas_device_remove(ioc, sas_device);
5810 } else if (!sas_device->starget) { 6303 } else if (!sas_device->starget) {
5811 mpt2sas_transport_port_remove(ioc, sas_address, 6304 mpt2sas_transport_port_remove(ioc, sas_address,
5812 parent_handle); 6305 sas_address_parent);
5813 _scsih_sas_device_remove(ioc, sas_device); 6306 _scsih_sas_device_remove(ioc, sas_device);
5814 } 6307 }
5815 } 6308 }
@@ -5849,8 +6342,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5849{ 6342{
5850 struct _sas_device *sas_device, *next; 6343 struct _sas_device *sas_device, *next;
5851 unsigned long flags; 6344 unsigned long flags;
5852 u16 handle, parent_handle;
5853 u64 sas_address;
5854 6345
5855 /* SAS Device List */ 6346 /* SAS Device List */
5856 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 6347 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
@@ -5859,14 +6350,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5859 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6350 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5860 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6351 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5861 6352
5862 handle = sas_device->handle; 6353 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5863 parent_handle = sas_device->parent_handle; 6354 sas_device->sas_address_parent)) {
5864 sas_address = sas_device->sas_address;
5865 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
5866 _scsih_sas_device_remove(ioc, sas_device); 6355 _scsih_sas_device_remove(ioc, sas_device);
5867 } else if (!sas_device->starget) { 6356 } else if (!sas_device->starget) {
5868 mpt2sas_transport_port_remove(ioc, sas_address, 6357 mpt2sas_transport_port_remove(ioc,
5869 parent_handle); 6358 sas_device->sas_address,
6359 sas_device->sas_address_parent);
5870 _scsih_sas_device_remove(ioc, sas_device); 6360 _scsih_sas_device_remove(ioc, sas_device);
5871 } 6361 }
5872 } 6362 }
@@ -5935,6 +6425,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5935 ioc->ctl_cb_idx = ctl_cb_idx; 6425 ioc->ctl_cb_idx = ctl_cb_idx;
5936 ioc->base_cb_idx = base_cb_idx; 6426 ioc->base_cb_idx = base_cb_idx;
5937 ioc->transport_cb_idx = transport_cb_idx; 6427 ioc->transport_cb_idx = transport_cb_idx;
6428 ioc->scsih_cb_idx = scsih_cb_idx;
5938 ioc->config_cb_idx = config_cb_idx; 6429 ioc->config_cb_idx = config_cb_idx;
5939 ioc->tm_tr_cb_idx = tm_tr_cb_idx; 6430 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
5940 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; 6431 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
@@ -6072,12 +6563,20 @@ static struct pci_driver scsih_driver = {
6072 .id_table = scsih_pci_table, 6563 .id_table = scsih_pci_table,
6073 .probe = _scsih_probe, 6564 .probe = _scsih_probe,
6074 .remove = __devexit_p(_scsih_remove), 6565 .remove = __devexit_p(_scsih_remove),
6566 .shutdown = _scsih_shutdown,
6075#ifdef CONFIG_PM 6567#ifdef CONFIG_PM
6076 .suspend = _scsih_suspend, 6568 .suspend = _scsih_suspend,
6077 .resume = _scsih_resume, 6569 .resume = _scsih_resume,
6078#endif 6570#endif
6079}; 6571};
6080 6572
6573/* raid transport support */
6574static struct raid_function_template mpt2sas_raid_functions = {
6575 .cookie = &scsih_driver_template,
6576 .is_raid = _scsih_is_raid,
6577 .get_resync = _scsih_get_resync,
6578 .get_state = _scsih_get_state,
6579};
6081 6580
6082/** 6581/**
6083 * _scsih_init - main entry point for this driver. 6582 * _scsih_init - main entry point for this driver.
@@ -6097,6 +6596,12 @@ _scsih_init(void)
6097 sas_attach_transport(&mpt2sas_transport_functions); 6596 sas_attach_transport(&mpt2sas_transport_functions);
6098 if (!mpt2sas_transport_template) 6597 if (!mpt2sas_transport_template)
6099 return -ENODEV; 6598 return -ENODEV;
6599 /* raid transport support */
6600 mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
6601 if (!mpt2sas_raid_template) {
6602 sas_release_transport(mpt2sas_transport_template);
6603 return -ENODEV;
6604 }
6100 6605
6101 mpt2sas_base_initialize_callback_handler(); 6606 mpt2sas_base_initialize_callback_handler();
6102 6607
@@ -6113,6 +6618,9 @@ _scsih_init(void)
6113 transport_cb_idx = mpt2sas_base_register_callback_handler( 6618 transport_cb_idx = mpt2sas_base_register_callback_handler(
6114 mpt2sas_transport_done); 6619 mpt2sas_transport_done);
6115 6620
6621 /* scsih internal commands callback handler */
6622 scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
6623
6116 /* configuration page API internal commands callback handler */ 6624 /* configuration page API internal commands callback handler */
6117 config_cb_idx = mpt2sas_base_register_callback_handler( 6625 config_cb_idx = mpt2sas_base_register_callback_handler(
6118 mpt2sas_config_done); 6626 mpt2sas_config_done);
@@ -6128,8 +6636,11 @@ _scsih_init(void)
6128 mpt2sas_ctl_init(); 6636 mpt2sas_ctl_init();
6129 6637
6130 error = pci_register_driver(&scsih_driver); 6638 error = pci_register_driver(&scsih_driver);
6131 if (error) 6639 if (error) {
6640 /* raid transport support */
6641 raid_class_release(mpt2sas_raid_template);
6132 sas_release_transport(mpt2sas_transport_template); 6642 sas_release_transport(mpt2sas_transport_template);
6643 }
6133 6644
6134 return error; 6645 return error;
6135} 6646}
@@ -6147,18 +6658,23 @@ _scsih_exit(void)
6147 6658
6148 pci_unregister_driver(&scsih_driver); 6659 pci_unregister_driver(&scsih_driver);
6149 6660
6150 sas_release_transport(mpt2sas_transport_template); 6661 mpt2sas_ctl_exit();
6662
6151 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 6663 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
6152 mpt2sas_base_release_callback_handler(tm_cb_idx); 6664 mpt2sas_base_release_callback_handler(tm_cb_idx);
6153 mpt2sas_base_release_callback_handler(base_cb_idx); 6665 mpt2sas_base_release_callback_handler(base_cb_idx);
6154 mpt2sas_base_release_callback_handler(transport_cb_idx); 6666 mpt2sas_base_release_callback_handler(transport_cb_idx);
6667 mpt2sas_base_release_callback_handler(scsih_cb_idx);
6155 mpt2sas_base_release_callback_handler(config_cb_idx); 6668 mpt2sas_base_release_callback_handler(config_cb_idx);
6156 mpt2sas_base_release_callback_handler(ctl_cb_idx); 6669 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6157 6670
6158 mpt2sas_base_release_callback_handler(tm_tr_cb_idx); 6671 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
6159 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); 6672 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6160 6673
6161 mpt2sas_ctl_exit(); 6674 /* raid transport support */
6675 raid_class_release(mpt2sas_raid_template);
6676 sas_release_transport(mpt2sas_transport_template);
6677
6162} 6678}
6163 6679
6164module_init(_scsih_init); 6680module_init(_scsih_init);