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.c819
1 files changed, 559 insertions, 260 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 86ab32d7ab15..55ee014a7e08 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -76,6 +76,7 @@ static u8 tm_cb_idx = -1;
76static u8 ctl_cb_idx = -1; 76static u8 ctl_cb_idx = -1;
77static u8 base_cb_idx = -1; 77static u8 base_cb_idx = -1;
78static u8 transport_cb_idx = -1; 78static u8 transport_cb_idx = -1;
79static u8 scsih_cb_idx = -1;
79static u8 config_cb_idx = -1; 80static u8 config_cb_idx = -1;
80static int mpt_ids; 81static int mpt_ids;
81 82
@@ -196,10 +197,28 @@ static struct pci_device_id scsih_pci_table[] = {
196 PCI_ANY_ID, PCI_ANY_ID }, 197 PCI_ANY_ID, PCI_ANY_ID },
197 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, 198 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
198 PCI_ANY_ID, PCI_ANY_ID }, 199 PCI_ANY_ID, PCI_ANY_ID },
200 /* Meteor ~ 2116 */
199 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, 201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
200 PCI_ANY_ID, PCI_ANY_ID }, 202 PCI_ANY_ID, PCI_ANY_ID },
201 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, 203 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
202 PCI_ANY_ID, PCI_ANY_ID }, 204 PCI_ANY_ID, PCI_ANY_ID },
205 /* Thunderbolt ~ 2208 */
206 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
207 PCI_ANY_ID, PCI_ANY_ID },
208 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
209 PCI_ANY_ID, PCI_ANY_ID },
210 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
211 PCI_ANY_ID, PCI_ANY_ID },
212 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
213 PCI_ANY_ID, PCI_ANY_ID },
214 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
215 PCI_ANY_ID, PCI_ANY_ID },
216 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
217 PCI_ANY_ID, PCI_ANY_ID },
218 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
219 PCI_ANY_ID, PCI_ANY_ID },
220 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
221 PCI_ANY_ID, PCI_ANY_ID },
203 {0} /* Terminating entry */ 222 {0} /* Terminating entry */
204}; 223};
205MODULE_DEVICE_TABLE(pci, scsih_pci_table); 224MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -317,6 +336,47 @@ _scsih_is_boot_device(u64 sas_address, u64 device_name,
317} 336}
318 337
319/** 338/**
339 * _scsih_get_sas_address - set the sas_address for given device handle
340 * @handle: device handle
341 * @sas_address: sas address
342 *
343 * Returns 0 success, non-zero when failure
344 */
345static int
346_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
347 u64 *sas_address)
348{
349 Mpi2SasDevicePage0_t sas_device_pg0;
350 Mpi2ConfigReply_t mpi_reply;
351 u32 ioc_status;
352
353 if (handle <= ioc->sas_hba.num_phys) {
354 *sas_address = ioc->sas_hba.sas_address;
355 return 0;
356 } else
357 *sas_address = 0;
358
359 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
360 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
361 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
362 ioc->name, __FILE__, __LINE__, __func__);
363 return -ENXIO;
364 }
365
366 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
367 MPI2_IOCSTATUS_MASK;
368 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
369 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
370 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
371 __FILE__, __LINE__, __func__);
372 return -EIO;
373 }
374
375 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
376 return 0;
377}
378
379/**
320 * _scsih_determine_boot_device - determine boot device. 380 * _scsih_determine_boot_device - determine boot device.
321 * @ioc: per adapter object 381 * @ioc: per adapter object
322 * @device: either sas_device or raid_device object 382 * @device: either sas_device or raid_device object
@@ -510,8 +570,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
510 struct _sas_device *sas_device) 570 struct _sas_device *sas_device)
511{ 571{
512 unsigned long flags; 572 unsigned long flags;
513 u16 handle, parent_handle;
514 u64 sas_address;
515 573
516 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 574 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
517 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 575 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
@@ -521,10 +579,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
521 list_add_tail(&sas_device->list, &ioc->sas_device_list); 579 list_add_tail(&sas_device->list, &ioc->sas_device_list);
522 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 580 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
523 581
524 handle = sas_device->handle; 582 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
525 parent_handle = sas_device->parent_handle; 583 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); 584 _scsih_sas_device_remove(ioc, sas_device);
529} 585}
530 586
@@ -553,31 +609,6 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
553} 609}
554 610
555/** 611/**
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 612 * _scsih_raid_device_find_by_id - raid device search
582 * @ioc: per adapter object 613 * @ioc: per adapter object
583 * @id: sas device target id 614 * @id: sas device target id
@@ -699,6 +730,31 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
699} 730}
700 731
701/** 732/**
733 * mpt2sas_scsih_expander_find_by_handle - expander device search
734 * @ioc: per adapter object
735 * @handle: expander handle (assigned by firmware)
736 * Context: Calling function should acquire ioc->sas_device_lock
737 *
738 * This searches for expander device based on handle, then returns the
739 * sas_node object.
740 */
741struct _sas_node *
742mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
743{
744 struct _sas_node *sas_expander, *r;
745
746 r = NULL;
747 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
748 if (sas_expander->handle != handle)
749 continue;
750 r = sas_expander;
751 goto out;
752 }
753 out:
754 return r;
755}
756
757/**
702 * mpt2sas_scsih_expander_find_by_sas_address - expander device search 758 * mpt2sas_scsih_expander_find_by_sas_address - expander device search
703 * @ioc: per adapter object 759 * @ioc: per adapter object
704 * @sas_address: sas address 760 * @sas_address: sas address
@@ -1043,17 +1099,46 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1043 * _scsih_change_queue_depth - setting device queue depth 1099 * _scsih_change_queue_depth - setting device queue depth
1044 * @sdev: scsi device struct 1100 * @sdev: scsi device struct
1045 * @qdepth: requested queue depth 1101 * @qdepth: requested queue depth
1102 * @reason: calling context
1046 * 1103 *
1047 * Returns queue depth. 1104 * Returns queue depth.
1048 */ 1105 */
1049static int 1106static int
1050_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) 1107_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1051{ 1108{
1052 struct Scsi_Host *shost = sdev->host; 1109 struct Scsi_Host *shost = sdev->host;
1053 int max_depth; 1110 int max_depth;
1054 int tag_type; 1111 int tag_type;
1112 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1113 struct MPT2SAS_DEVICE *sas_device_priv_data;
1114 struct MPT2SAS_TARGET *sas_target_priv_data;
1115 struct _sas_device *sas_device;
1116 unsigned long flags;
1117
1118 if (reason != SCSI_QDEPTH_DEFAULT)
1119 return -EOPNOTSUPP;
1055 1120
1056 max_depth = shost->can_queue; 1121 max_depth = shost->can_queue;
1122
1123 /* limit max device queue for SATA to 32 */
1124 sas_device_priv_data = sdev->hostdata;
1125 if (!sas_device_priv_data)
1126 goto not_sata;
1127 sas_target_priv_data = sas_device_priv_data->sas_target;
1128 if (!sas_target_priv_data)
1129 goto not_sata;
1130 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
1131 goto not_sata;
1132 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1133 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1134 sas_device_priv_data->sas_target->sas_address);
1135 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1136 if (sas_device && sas_device->device_info &
1137 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1138 max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
1139
1140 not_sata:
1141
1057 if (!sdev->tagged_supported) 1142 if (!sdev->tagged_supported)
1058 max_depth = 1; 1143 max_depth = 1;
1059 if (qdepth > max_depth) 1144 if (qdepth > max_depth)
@@ -1488,7 +1573,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
1488 r_level, raid_device->handle, 1573 r_level, raid_device->handle,
1489 (unsigned long long)raid_device->wwid, 1574 (unsigned long long)raid_device->wwid,
1490 raid_device->num_pds, ds); 1575 raid_device->num_pds, ds);
1491 _scsih_change_queue_depth(sdev, qdepth); 1576 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1492 return 0; 1577 return 0;
1493 } 1578 }
1494 1579
@@ -1534,7 +1619,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
1534 _scsih_display_sata_capabilities(ioc, sas_device, sdev); 1619 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
1535 } 1620 }
1536 1621
1537 _scsih_change_queue_depth(sdev, qdepth); 1622 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1538 1623
1539 if (ssp_target) 1624 if (ssp_target)
1540 sas_read_port_mode_page(sdev); 1625 sas_read_port_mode_page(sdev);
@@ -1874,6 +1959,8 @@ _scsih_abort(struct scsi_cmnd *scmd)
1874 goto out; 1959 goto out;
1875 } 1960 }
1876 1961
1962 mpt2sas_halt_firmware(ioc);
1963
1877 mutex_lock(&ioc->tm_cmds.mutex); 1964 mutex_lock(&ioc->tm_cmds.mutex);
1878 handle = sas_device_priv_data->sas_target->handle; 1965 handle = sas_device_priv_data->sas_target->handle;
1879 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, 1966 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
@@ -2297,7 +2384,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2297 u16 handle; 2384 u16 handle;
2298 u16 reason_code; 2385 u16 reason_code;
2299 u8 phy_number; 2386 u8 phy_number;
2300 u8 link_rate;
2301 2387
2302 for (i = 0; i < event_data->NumEntries; i++) { 2388 for (i = 0; i < event_data->NumEntries; i++) {
2303 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 2389 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2308,11 +2394,6 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2308 MPI2_EVENT_SAS_TOPO_RC_MASK; 2394 MPI2_EVENT_SAS_TOPO_RC_MASK;
2309 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) 2395 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2310 _scsih_block_io_device(ioc, handle); 2396 _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 } 2397 }
2317} 2398}
2318 2399
@@ -2349,16 +2430,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2349 2430
2350 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2431 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2351 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2432 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); 2433 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2359 2434
2360 /* skip is hidden raid component */ 2435 /* skip is hidden raid component */
2361 if (sas_device->hidden_raid_component) 2436 if (sas_device && sas_device->hidden_raid_component)
2362 return; 2437 return;
2363 2438
2364 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2439 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2371,18 +2446,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2371 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2446 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2372 list_add_tail(&delayed_tr->list, 2447 list_add_tail(&delayed_tr->list,
2373 &ioc->delayed_tr_list); 2448 &ioc->delayed_tr_list);
2374 if (sas_device->starget) 2449 if (sas_device && sas_device->starget) {
2375 dewtprintk(ioc, starget_printk(KERN_INFO, 2450 dewtprintk(ioc, starget_printk(KERN_INFO,
2376 sas_device->starget, "DELAYED:tr:handle(0x%04x), " 2451 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2377 "(open)\n", sas_device->handle)); 2452 "(open)\n", handle));
2453 } else {
2454 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2455 "DELAYED:tr:handle(0x%04x), (open)\n",
2456 ioc->name, handle));
2457 }
2378 return; 2458 return;
2379 } 2459 }
2380 2460
2381 if (sas_device->starget && sas_device->starget->hostdata) { 2461 if (sas_device) {
2382 sas_target_priv_data = sas_device->starget->hostdata; 2462 sas_device->state |= MPTSAS_STATE_TR_SEND;
2383 sas_target_priv_data->tm_busy = 1; 2463 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2384 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2464 if (sas_device->starget && sas_device->starget->hostdata) {
2385 "tr:handle(0x%04x), (open)\n", sas_device->handle)); 2465 sas_target_priv_data = sas_device->starget->hostdata;
2466 sas_target_priv_data->tm_busy = 1;
2467 dewtprintk(ioc, starget_printk(KERN_INFO,
2468 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2469 handle));
2470 }
2471 } else {
2472 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2473 "tr:handle(0x%04x), (open)\n", ioc->name, handle));
2386 } 2474 }
2387 2475
2388 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2476 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2390,8 +2478,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2390 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2478 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2391 mpi_request->DevHandle = cpu_to_le16(handle); 2479 mpi_request->DevHandle = cpu_to_le16(handle);
2392 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 2480 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); 2481 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2396} 2482}
2397 2483
@@ -2426,21 +2512,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2426 2512
2427 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2513 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2428 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2514 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); 2515 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2437 2516
2438 if (sas_device->starget) 2517 if (sas_device) {
2439 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2518 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2519 if (sas_device->starget)
2520 dewtprintk(ioc, starget_printk(KERN_INFO,
2521 sas_device->starget,
2522 "sc_complete:handle(0x%04x), "
2523 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2524 handle, le16_to_cpu(mpi_reply->IOCStatus),
2525 le32_to_cpu(mpi_reply->IOCLogInfo)));
2526 } else {
2527 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2440 "sc_complete:handle(0x%04x), " 2528 "sc_complete:handle(0x%04x), "
2441 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2529 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2442 handle, le16_to_cpu(mpi_reply->IOCStatus), 2530 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
2443 le32_to_cpu(mpi_reply->IOCLogInfo))); 2531 le32_to_cpu(mpi_reply->IOCLogInfo)));
2532 }
2533
2444 return 1; 2534 return 1;
2445} 2535}
2446 2536
@@ -2478,28 +2568,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2478 handle = le16_to_cpu(mpi_reply->DevHandle); 2568 handle = le16_to_cpu(mpi_reply->DevHandle);
2479 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2569 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2480 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2570 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); 2571 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2489 2572
2490 if (sas_device->starget) 2573 if (sas_device) {
2491 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2574 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2492 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " 2575 if (sas_device->starget) {
2493 "loginfo(0x%08x), completed(%d)\n", 2576 dewtprintk(ioc, starget_printk(KERN_INFO,
2494 sas_device->handle, (sas_device->state & 2577 sas_device->starget, "tr_complete:handle(0x%04x), "
2495 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", 2578 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2496 le16_to_cpu(mpi_reply->IOCStatus), 2579 "completed(%d)\n", sas_device->handle,
2580 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2581 "open" : "active",
2582 le16_to_cpu(mpi_reply->IOCStatus),
2583 le32_to_cpu(mpi_reply->IOCLogInfo),
2584 le32_to_cpu(mpi_reply->TerminationCount)));
2585 if (sas_device->starget->hostdata) {
2586 sas_target_priv_data =
2587 sas_device->starget->hostdata;
2588 sas_target_priv_data->tm_busy = 0;
2589 }
2590 }
2591 } else {
2592 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2593 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2594 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2595 handle, le16_to_cpu(mpi_reply->IOCStatus),
2497 le32_to_cpu(mpi_reply->IOCLogInfo), 2596 le32_to_cpu(mpi_reply->IOCLogInfo),
2498 le32_to_cpu(mpi_reply->TerminationCount))); 2597 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 } 2598 }
2504 2599
2505 if (!list_empty(&ioc->delayed_tr_list)) { 2600 if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2514,8 +2609,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2514 } else 2609 } else
2515 rc = 1; 2610 rc = 1;
2516 2611
2517 2612 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2518 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2519 return rc; 2613 return rc;
2520 2614
2521 if (ioc->shost_recovery) { 2615 if (ioc->shost_recovery) {
@@ -2531,12 +2625,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2531 return rc; 2625 return rc;
2532 } 2626 }
2533 2627
2628 if (sas_device)
2629 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2630
2534 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2535 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2632 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2536 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2633 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2537 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2634 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2538 mpi_request->DevHandle = mpi_reply->DevHandle; 2635 mpi_request->DevHandle = mpi_reply->DevHandle;
2539 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2540 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2636 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2541 return rc; 2637 return rc;
2542} 2638}
@@ -2678,8 +2774,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2678 else 2774 else
2679 return; 2775 return;
2680 2776
2681 mpi_request->EEDPBlockSize = scmd->device->sector_size;
2682
2683 switch (prot_type) { 2777 switch (prot_type) {
2684 case SCSI_PROT_DIF_TYPE1: 2778 case SCSI_PROT_DIF_TYPE1:
2685 2779
@@ -2687,8 +2781,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2687 * enable ref/guard checking 2781 * enable ref/guard checking
2688 * auto increment ref tag 2782 * auto increment ref tag
2689 */ 2783 */
2690 mpi_request->EEDPFlags = eedp_flags | 2784 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2691 MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
2692 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | 2785 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
2693 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; 2786 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2694 mpi_request->CDB.EEDP32.PrimaryReferenceTag = 2787 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
@@ -2701,11 +2794,11 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2701 /* 2794 /*
2702 * enable guard checking 2795 * enable guard checking
2703 */ 2796 */
2704 mpi_request->EEDPFlags = eedp_flags | 2797 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2705 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2706
2707 break; 2798 break;
2708 } 2799 }
2800 mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
2801 mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
2709} 2802}
2710 2803
2711/** 2804/**
@@ -2788,7 +2881,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2788 } 2881 }
2789 2882
2790 /* see if we are busy with task managment stuff */ 2883 /* see if we are busy with task managment stuff */
2791 if (sas_target_priv_data->tm_busy) 2884 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
2792 return SCSI_MLQUEUE_DEVICE_BUSY; 2885 return SCSI_MLQUEUE_DEVICE_BUSY;
2793 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) 2886 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2794 return SCSI_MLQUEUE_HOST_BUSY; 2887 return SCSI_MLQUEUE_HOST_BUSY;
@@ -2842,7 +2935,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2842 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; 2935 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
2843 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; 2936 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
2844 mpi_request->SenseBufferLowAddress = 2937 mpi_request->SenseBufferLowAddress =
2845 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 2938 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
2846 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; 2939 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2847 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + 2940 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2848 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); 2941 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
@@ -3059,7 +3152,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3059 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 3152 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
3060 response_info = le32_to_cpu(mpi_reply->ResponseInfo); 3153 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
3061 response_bytes = (u8 *)&response_info; 3154 response_bytes = (u8 *)&response_info;
3062 _scsih_response_code(ioc, response_bytes[3]); 3155 _scsih_response_code(ioc, response_bytes[0]);
3063 } 3156 }
3064} 3157}
3065#endif 3158#endif
@@ -3177,7 +3270,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3177 u8 scsi_status; 3270 u8 scsi_status;
3178 u32 log_info; 3271 u32 log_info;
3179 struct MPT2SAS_DEVICE *sas_device_priv_data; 3272 struct MPT2SAS_DEVICE *sas_device_priv_data;
3180 u32 response_code; 3273 u32 response_code = 0;
3181 3274
3182 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 3275 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3183 scmd = _scsih_scsi_lookup_get(ioc, smid); 3276 scmd = _scsih_scsi_lookup_get(ioc, smid);
@@ -3199,16 +3292,16 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3199 } 3292 }
3200 3293
3201 /* turning off TLR */ 3294 /* turning off TLR */
3295 scsi_state = mpi_reply->SCSIState;
3296 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
3297 response_code =
3298 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
3202 if (!sas_device_priv_data->tlr_snoop_check) { 3299 if (!sas_device_priv_data->tlr_snoop_check) {
3203 sas_device_priv_data->tlr_snoop_check++; 3300 sas_device_priv_data->tlr_snoop_check++;
3204 if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) { 3301 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
3205 response_code = (le32_to_cpu(mpi_reply->ResponseInfo) 3302 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
3206 >> 24); 3303 sas_device_priv_data->flags &=
3207 if (response_code == 3304 ~MPT_DEVICE_TLR_ON;
3208 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
3209 sas_device_priv_data->flags &=
3210 ~MPT_DEVICE_TLR_ON;
3211 }
3212 } 3305 }
3213 3306
3214 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); 3307 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -3219,7 +3312,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3219 else 3312 else
3220 log_info = 0; 3313 log_info = 0;
3221 ioc_status &= MPI2_IOCSTATUS_MASK; 3314 ioc_status &= MPI2_IOCSTATUS_MASK;
3222 scsi_state = mpi_reply->SCSIState;
3223 scsi_status = mpi_reply->SCSIStatus; 3315 scsi_status = mpi_reply->SCSIStatus;
3224 3316
3225 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && 3317 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
@@ -3255,10 +3347,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3255 3347
3256 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 3348 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
3257 if (sas_device_priv_data->block) { 3349 if (sas_device_priv_data->block) {
3258 scmd->result = (DID_BUS_BUSY << 16); 3350 scmd->result = DID_TRANSPORT_DISRUPTED << 16;
3259 break; 3351 goto out;
3260 } 3352 }
3261
3262 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 3353 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
3263 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 3354 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
3264 scmd->result = DID_RESET << 16; 3355 scmd->result = DID_RESET << 16;
@@ -3304,8 +3395,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3304 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: 3395 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
3305 case MPI2_IOCSTATUS_SUCCESS: 3396 case MPI2_IOCSTATUS_SUCCESS:
3306 scmd->result = (DID_OK << 16) | scsi_status; 3397 scmd->result = (DID_OK << 16) | scsi_status;
3307 if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | 3398 if (response_code ==
3308 MPI2_SCSI_STATE_NO_SCSI_STATUS)) 3399 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
3400 (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
3401 MPI2_SCSI_STATE_NO_SCSI_STATUS)))
3309 scmd->result = DID_SOFT_ERROR << 16; 3402 scmd->result = DID_SOFT_ERROR << 16;
3310 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) 3403 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
3311 scmd->result = DID_RESET << 16; 3404 scmd->result = DID_RESET << 16;
@@ -3344,7 +3437,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3344/** 3437/**
3345 * _scsih_sas_host_refresh - refreshing sas host object contents 3438 * _scsih_sas_host_refresh - refreshing sas host object contents
3346 * @ioc: per adapter object 3439 * @ioc: per adapter object
3347 * @update: update link information
3348 * Context: user 3440 * Context: user
3349 * 3441 *
3350 * During port enable, fw will send topology events for every device. Its 3442 * During port enable, fw will send topology events for every device. Its
@@ -3354,13 +3446,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3354 * Return nothing. 3446 * Return nothing.
3355 */ 3447 */
3356static void 3448static void
3357_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) 3449_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
3358{ 3450{
3359 u16 sz; 3451 u16 sz;
3360 u16 ioc_status; 3452 u16 ioc_status;
3361 int i; 3453 int i;
3362 Mpi2ConfigReply_t mpi_reply; 3454 Mpi2ConfigReply_t mpi_reply;
3363 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; 3455 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3456 u16 attached_handle;
3364 3457
3365 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT 3458 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3366 "updating handles for sas_host(0x%016llx)\n", 3459 "updating handles for sas_host(0x%016llx)\n",
@@ -3374,27 +3467,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
3374 ioc->name, __FILE__, __LINE__, __func__); 3467 ioc->name, __FILE__, __LINE__, __func__);
3375 return; 3468 return;
3376 } 3469 }
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 3470
3471 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3472 sas_iounit_pg0, sz)) != 0)
3473 goto out;
3474 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
3475 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3476 goto out;
3477 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3478 if (i == 0)
3479 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3480 PhyData[0].ControllerDevHandle);
3481 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3482 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
3483 AttachedDevHandle);
3484 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
3485 attached_handle, i, sas_iounit_pg0->PhyData[i].
3486 NegotiatedLinkRate >> 4);
3487 }
3398 out: 3488 out:
3399 kfree(sas_iounit_pg0); 3489 kfree(sas_iounit_pg0);
3400} 3490}
@@ -3507,19 +3597,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
3507 ioc->name, __FILE__, __LINE__, __func__); 3597 ioc->name, __FILE__, __LINE__, __func__);
3508 goto out; 3598 goto out;
3509 } 3599 }
3510 ioc->sas_hba.phy[i].handle = 3600
3511 le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle); 3601 if (i == 0)
3602 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3603 PhyData[0].ControllerDevHandle);
3604 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3512 ioc->sas_hba.phy[i].phy_id = i; 3605 ioc->sas_hba.phy[i].phy_id = i;
3513 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], 3606 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
3514 phy_pg0, ioc->sas_hba.parent_dev); 3607 phy_pg0, ioc->sas_hba.parent_dev);
3515 } 3608 }
3516 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 3609 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))) { 3610 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
3518 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3611 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3519 ioc->name, __FILE__, __LINE__, __func__); 3612 ioc->name, __FILE__, __LINE__, __func__);
3520 goto out; 3613 goto out;
3521 } 3614 }
3522 ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
3523 ioc->sas_hba.enclosure_handle = 3615 ioc->sas_hba.enclosure_handle =
3524 le16_to_cpu(sas_device_pg0.EnclosureHandle); 3616 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3525 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 3617 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
@@ -3562,7 +3654,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3562 Mpi2SasEnclosurePage0_t enclosure_pg0; 3654 Mpi2SasEnclosurePage0_t enclosure_pg0;
3563 u32 ioc_status; 3655 u32 ioc_status;
3564 u16 parent_handle; 3656 u16 parent_handle;
3565 __le64 sas_address; 3657 __le64 sas_address, sas_address_parent = 0;
3566 int i; 3658 int i;
3567 unsigned long flags; 3659 unsigned long flags;
3568 struct _sas_port *mpt2sas_port = NULL; 3660 struct _sas_port *mpt2sas_port = NULL;
@@ -3591,10 +3683,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3591 3683
3592 /* handle out of order topology events */ 3684 /* handle out of order topology events */
3593 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); 3685 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
3594 if (parent_handle >= ioc->sas_hba.num_phys) { 3686 if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
3687 != 0) {
3688 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3689 ioc->name, __FILE__, __LINE__, __func__);
3690 return -1;
3691 }
3692 if (sas_address_parent != ioc->sas_hba.sas_address) {
3595 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3693 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3596 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 3694 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3597 parent_handle); 3695 sas_address_parent);
3598 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3696 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3599 if (!sas_expander) { 3697 if (!sas_expander) {
3600 rc = _scsih_expander_add(ioc, parent_handle); 3698 rc = _scsih_expander_add(ioc, parent_handle);
@@ -3622,14 +3720,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3622 3720
3623 sas_expander->handle = handle; 3721 sas_expander->handle = handle;
3624 sas_expander->num_phys = expander_pg0.NumPhys; 3722 sas_expander->num_phys = expander_pg0.NumPhys;
3625 sas_expander->parent_handle = parent_handle; 3723 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; 3724 sas_expander->sas_address = sas_address;
3629 3725
3630 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," 3726 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
3631 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, 3727 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
3632 handle, sas_expander->parent_handle, (unsigned long long) 3728 handle, parent_handle, (unsigned long long)
3633 sas_expander->sas_address, sas_expander->num_phys); 3729 sas_expander->sas_address, sas_expander->num_phys);
3634 3730
3635 if (!sas_expander->num_phys) 3731 if (!sas_expander->num_phys)
@@ -3645,7 +3741,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3645 3741
3646 INIT_LIST_HEAD(&sas_expander->sas_port_list); 3742 INIT_LIST_HEAD(&sas_expander->sas_port_list);
3647 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, 3743 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
3648 sas_expander->parent_handle); 3744 sas_address_parent);
3649 if (!mpt2sas_port) { 3745 if (!mpt2sas_port) {
3650 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3746 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3651 ioc->name, __FILE__, __LINE__, __func__); 3747 ioc->name, __FILE__, __LINE__, __func__);
@@ -3691,20 +3787,54 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3691 3787
3692 if (mpt2sas_port) 3788 if (mpt2sas_port)
3693 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 3789 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
3694 sas_expander->parent_handle); 3790 sas_address_parent);
3695 kfree(sas_expander); 3791 kfree(sas_expander);
3696 return rc; 3792 return rc;
3697} 3793}
3698 3794
3699/** 3795/**
3796 * _scsih_done - scsih callback handler.
3797 * @ioc: per adapter object
3798 * @smid: system request message index
3799 * @msix_index: MSIX table index supplied by the OS
3800 * @reply: reply message frame(lower 32bit addr)
3801 *
3802 * Callback handler when sending internal generated message frames.
3803 * The callback index passed is `ioc->scsih_cb_idx`
3804 *
3805 * Return 1 meaning mf should be freed from _base_interrupt
3806 * 0 means the mf is freed from this function.
3807 */
3808static u8
3809_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3810{
3811 MPI2DefaultReply_t *mpi_reply;
3812
3813 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3814 if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
3815 return 1;
3816 if (ioc->scsih_cmds.smid != smid)
3817 return 1;
3818 ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
3819 if (mpi_reply) {
3820 memcpy(ioc->scsih_cmds.reply, mpi_reply,
3821 mpi_reply->MsgLength*4);
3822 ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
3823 }
3824 ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
3825 complete(&ioc->scsih_cmds.done);
3826 return 1;
3827}
3828
3829/**
3700 * _scsih_expander_remove - removing expander object 3830 * _scsih_expander_remove - removing expander object
3701 * @ioc: per adapter object 3831 * @ioc: per adapter object
3702 * @handle: expander handle 3832 * @sas_address: expander sas_address
3703 * 3833 *
3704 * Return nothing. 3834 * Return nothing.
3705 */ 3835 */
3706static void 3836static void
3707_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) 3837_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3708{ 3838{
3709 struct _sas_node *sas_expander; 3839 struct _sas_node *sas_expander;
3710 unsigned long flags; 3840 unsigned long flags;
@@ -3713,7 +3843,8 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3713 return; 3843 return;
3714 3844
3715 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3845 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3716 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); 3846 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3847 sas_address);
3717 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3848 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3718 _scsih_expander_node_remove(ioc, sas_expander); 3849 _scsih_expander_node_remove(ioc, sas_expander);
3719} 3850}
@@ -3805,8 +3936,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3805 } 3936 }
3806 3937
3807 sas_device->handle = handle; 3938 sas_device->handle = handle;
3808 sas_device->parent_handle = 3939 if (_scsih_get_sas_address(ioc, le16_to_cpu
3809 le16_to_cpu(sas_device_pg0.ParentDevHandle); 3940 (sas_device_pg0.ParentDevHandle),
3941 &sas_device->sas_address_parent) != 0)
3942 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3943 ioc->name, __FILE__, __LINE__, __func__);
3810 sas_device->enclosure_handle = 3944 sas_device->enclosure_handle =
3811 le16_to_cpu(sas_device_pg0.EnclosureHandle); 3945 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3812 sas_device->slot = 3946 sas_device->slot =
@@ -3836,43 +3970,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3836/** 3970/**
3837 * _scsih_remove_device - removing sas device object 3971 * _scsih_remove_device - removing sas device object
3838 * @ioc: per adapter object 3972 * @ioc: per adapter object
3839 * @handle: sas device handle 3973 * @sas_device: the sas_device object
3840 * 3974 *
3841 * Return nothing. 3975 * Return nothing.
3842 */ 3976 */
3843static void 3977static void
3844_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) 3978_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
3979 *sas_device)
3845{ 3980{
3846 struct MPT2SAS_TARGET *sas_target_priv_data; 3981 struct MPT2SAS_TARGET *sas_target_priv_data;
3847 struct _sas_device *sas_device;
3848 unsigned long flags;
3849 Mpi2SasIoUnitControlReply_t mpi_reply; 3982 Mpi2SasIoUnitControlReply_t mpi_reply;
3850 Mpi2SasIoUnitControlRequest_t mpi_request; 3983 Mpi2SasIoUnitControlRequest_t mpi_request;
3851 u16 device_handle; 3984 u16 device_handle, handle;
3852 3985
3853 /* lookup sas_device */ 3986 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; 3987 return;
3859 }
3860 3988
3861 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle" 3989 handle = sas_device->handle;
3862 "(0x%04x)\n", ioc->name, __func__, handle)); 3990 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
3991 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
3992 (unsigned long long) sas_device->sas_address));
3863 3993
3864 if (sas_device->starget && sas_device->starget->hostdata) { 3994 if (sas_device->starget && sas_device->starget->hostdata) {
3865 sas_target_priv_data = sas_device->starget->hostdata; 3995 sas_target_priv_data = sas_device->starget->hostdata;
3866 sas_target_priv_data->deleted = 1; 3996 sas_target_priv_data->deleted = 1;
3867 } 3997 }
3868 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3869 3998
3870 if (ioc->remove_host) 3999 if (ioc->remove_host || ioc->shost_recovery || !handle)
3871 goto out; 4000 goto out;
3872 4001
3873 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { 4002 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
3874 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4003 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3875 "target_reset handle(0x%04x)\n", ioc->name, handle)); 4004 "target_reset handle(0x%04x)\n", ioc->name,
4005 handle));
3876 goto skip_tr; 4006 goto skip_tr;
3877 } 4007 }
3878 4008
@@ -3925,10 +4055,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3925 _scsih_ublock_io_device(ioc, handle); 4055 _scsih_ublock_io_device(ioc, handle);
3926 4056
3927 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 4057 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
3928 sas_device->parent_handle); 4058 sas_device->sas_address_parent);
3929 4059
3930 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 4060 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
3931 "(0x%016llx)\n", ioc->name, sas_device->handle, 4061 "(0x%016llx)\n", ioc->name, handle,
3932 (unsigned long long) sas_device->sas_address); 4062 (unsigned long long) sas_device->sas_address);
3933 _scsih_sas_device_remove(ioc, sas_device); 4063 _scsih_sas_device_remove(ioc, sas_device);
3934 4064
@@ -3952,7 +4082,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3952 u16 reason_code; 4082 u16 reason_code;
3953 u8 phy_number; 4083 u8 phy_number;
3954 char *status_str = NULL; 4084 char *status_str = NULL;
3955 char link_rate[25]; 4085 u8 link_rate, prev_link_rate;
3956 4086
3957 switch (event_data->ExpStatus) { 4087 switch (event_data->ExpStatus) {
3958 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 4088 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
@@ -3962,6 +4092,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3962 status_str = "remove"; 4092 status_str = "remove";
3963 break; 4093 break;
3964 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 4094 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
4095 case 0:
3965 status_str = "responding"; 4096 status_str = "responding";
3966 break; 4097 break;
3967 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 4098 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
@@ -3987,30 +4118,30 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3987 MPI2_EVENT_SAS_TOPO_RC_MASK; 4118 MPI2_EVENT_SAS_TOPO_RC_MASK;
3988 switch (reason_code) { 4119 switch (reason_code) {
3989 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4120 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3990 snprintf(link_rate, 25, ": add, link(0x%02x)", 4121 status_str = "target add";
3991 (event_data->PHY[i].LinkRate >> 4));
3992 status_str = link_rate;
3993 break; 4122 break;
3994 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4123 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
3995 status_str = ": remove"; 4124 status_str = "target remove";
3996 break; 4125 break;
3997 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 4126 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
3998 status_str = ": remove_delay"; 4127 status_str = "delay target remove";
3999 break; 4128 break;
4000 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4129 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4001 snprintf(link_rate, 25, ": link(0x%02x)", 4130 status_str = "link rate change";
4002 (event_data->PHY[i].LinkRate >> 4));
4003 status_str = link_rate;
4004 break; 4131 break;
4005 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 4132 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
4006 status_str = ": responding"; 4133 status_str = "target responding";
4007 break; 4134 break;
4008 default: 4135 default:
4009 status_str = ": unknown"; 4136 status_str = "unknown";
4010 break; 4137 break;
4011 } 4138 }
4012 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n", 4139 link_rate = event_data->PHY[i].LinkRate >> 4;
4013 phy_number, handle, status_str); 4140 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4141 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
4142 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
4143 handle, status_str, link_rate, prev_link_rate);
4144
4014 } 4145 }
4015} 4146}
4016#endif 4147#endif
@@ -4031,8 +4162,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4031 u16 reason_code; 4162 u16 reason_code;
4032 u8 phy_number; 4163 u8 phy_number;
4033 struct _sas_node *sas_expander; 4164 struct _sas_node *sas_expander;
4165 struct _sas_device *sas_device;
4166 u64 sas_address;
4034 unsigned long flags; 4167 unsigned long flags;
4035 u8 link_rate_; 4168 u8 link_rate, prev_link_rate;
4036 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; 4169 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
4037 4170
4038#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4171#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4040,10 +4173,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4040 _scsih_sas_topology_change_event_debug(ioc, event_data); 4173 _scsih_sas_topology_change_event_debug(ioc, event_data);
4041#endif 4174#endif
4042 4175
4176 if (ioc->shost_recovery)
4177 return;
4178
4043 if (!ioc->sas_hba.num_phys) 4179 if (!ioc->sas_hba.num_phys)
4044 _scsih_sas_host_add(ioc); 4180 _scsih_sas_host_add(ioc);
4045 else 4181 else
4046 _scsih_sas_host_refresh(ioc, 0); 4182 _scsih_sas_host_refresh(ioc);
4047 4183
4048 if (fw_event->ignore) { 4184 if (fw_event->ignore) {
4049 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " 4185 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
@@ -4058,6 +4194,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4058 if (_scsih_expander_add(ioc, parent_handle) != 0) 4194 if (_scsih_expander_add(ioc, parent_handle) != 0)
4059 return; 4195 return;
4060 4196
4197 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4198 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
4199 parent_handle);
4200 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4201 if (sas_expander)
4202 sas_address = sas_expander->sas_address;
4203 else if (parent_handle < ioc->sas_hba.num_phys)
4204 sas_address = ioc->sas_hba.sas_address;
4205 else
4206 return;
4207
4061 /* handle siblings events */ 4208 /* handle siblings events */
4062 for (i = 0; i < event_data->NumEntries; i++) { 4209 for (i = 0; i < event_data->NumEntries; i++) {
4063 if (fw_event->ignore) { 4210 if (fw_event->ignore) {
@@ -4077,48 +4224,47 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4077 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 4224 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
4078 if (!handle) 4225 if (!handle)
4079 continue; 4226 continue;
4080 link_rate_ = event_data->PHY[i].LinkRate >> 4; 4227 link_rate = event_data->PHY[i].LinkRate >> 4;
4228 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4081 switch (reason_code) { 4229 switch (reason_code) {
4082 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4230 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
4231
4232 if (link_rate == prev_link_rate)
4233 break;
4234
4235 mpt2sas_transport_update_links(ioc, sas_address,
4236 handle, phy_number, link_rate);
4237
4238 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
4239 _scsih_ublock_io_device(ioc, handle);
4240 break;
4083 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4241 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4084 if (!parent_handle) { 4242
4085 if (phy_number < ioc->sas_hba.num_phys) 4243 mpt2sas_transport_update_links(ioc, sas_address,
4086 mpt2sas_transport_update_links( 4244 handle, phy_number, link_rate);
4087 ioc, 4245
4088 ioc->sas_hba.phy[phy_number].handle, 4246 _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; 4247 break;
4113 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4248 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
4114 _scsih_remove_device(ioc, handle); 4249
4250 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4251 sas_device = _scsih_sas_device_find_by_handle(ioc,
4252 handle);
4253 if (!sas_device) {
4254 spin_unlock_irqrestore(&ioc->sas_device_lock,
4255 flags);
4256 break;
4257 }
4258 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4259 _scsih_remove_device(ioc, sas_device);
4115 break; 4260 break;
4116 } 4261 }
4117 } 4262 }
4118 4263
4119 /* handle expander removal */ 4264 /* handle expander removal */
4120 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) 4265 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
4121 _scsih_expander_remove(ioc, parent_handle); 4266 sas_expander)
4267 _scsih_expander_remove(ioc, sas_address);
4122 4268
4123} 4269}
4124 4270
@@ -4170,6 +4316,12 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4170 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 4316 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
4171 reason_str = "internal async notification"; 4317 reason_str = "internal async notification";
4172 break; 4318 break;
4319 case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
4320 reason_str = "expander reduced functionality";
4321 break;
4322 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
4323 reason_str = "expander reduced functionality complete";
4324 break;
4173 default: 4325 default:
4174 reason_str = "unknown reason"; 4326 reason_str = "unknown reason";
4175 break; 4327 break;
@@ -4197,11 +4349,43 @@ static void
4197_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, 4349_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4198 struct fw_event_work *fw_event) 4350 struct fw_event_work *fw_event)
4199{ 4351{
4352 struct MPT2SAS_TARGET *target_priv_data;
4353 struct _sas_device *sas_device;
4354 __le64 sas_address;
4355 unsigned long flags;
4356 Mpi2EventDataSasDeviceStatusChange_t *event_data =
4357 fw_event->event_data;
4358
4200#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4359#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4201 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4360 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4202 _scsih_sas_device_status_change_event_debug(ioc, 4361 _scsih_sas_device_status_change_event_debug(ioc,
4203 fw_event->event_data); 4362 event_data);
4204#endif 4363#endif
4364
4365 if (!(event_data->ReasonCode ==
4366 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4367 event_data->ReasonCode ==
4368 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
4369 return;
4370
4371 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4372 sas_address = le64_to_cpu(event_data->SASAddress);
4373 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4374 sas_address);
4375 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4376
4377 if (!sas_device || !sas_device->starget)
4378 return;
4379
4380 target_priv_data = sas_device->starget->hostdata;
4381 if (!target_priv_data)
4382 return;
4383
4384 if (event_data->ReasonCode ==
4385 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
4386 target_priv_data->tm_busy = 1;
4387 else
4388 target_priv_data->tm_busy = 0;
4205} 4389}
4206 4390
4207#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4391#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4281,6 +4465,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4281#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4465#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4282 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; 4466 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4283#endif 4467#endif
4468 u16 ioc_status;
4284 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 4469 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4285 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 4470 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4286 event_data->PortWidth)); 4471 event_data->PortWidth));
@@ -4314,8 +4499,9 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4314 mpt2sas_scsih_issue_tm(ioc, handle, lun, 4499 mpt2sas_scsih_issue_tm(ioc, handle, lun,
4315 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); 4500 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
4316 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 4501 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4317 4502 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4318 if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) && 4503 & MPI2_IOCSTATUS_MASK;
4504 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
4319 (mpi_reply->ResponseCode == 4505 (mpi_reply->ResponseCode ==
4320 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || 4506 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4321 mpi_reply->ResponseCode == 4507 mpi_reply->ResponseCode ==
@@ -4570,7 +4756,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
4570 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4756 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4571 if (!sas_device) 4757 if (!sas_device)
4572 return; 4758 return;
4573 _scsih_remove_device(ioc, handle); 4759 _scsih_remove_device(ioc, sas_device);
4574} 4760}
4575 4761
4576/** 4762/**
@@ -4591,6 +4777,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4591 Mpi2ConfigReply_t mpi_reply; 4777 Mpi2ConfigReply_t mpi_reply;
4592 Mpi2SasDevicePage0_t sas_device_pg0; 4778 Mpi2SasDevicePage0_t sas_device_pg0;
4593 u32 ioc_status; 4779 u32 ioc_status;
4780 u64 sas_address;
4781 u16 parent_handle;
4594 4782
4595 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4783 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4596 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 4784 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -4615,9 +4803,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4615 return; 4803 return;
4616 } 4804 }
4617 4805
4618 mpt2sas_transport_update_links(ioc, 4806 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4619 le16_to_cpu(sas_device_pg0.ParentDevHandle), 4807 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4620 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 4808 mpt2sas_transport_update_links(ioc, sas_address, handle,
4809 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4621 4810
4622 _scsih_add_device(ioc, handle, 0, 1); 4811 _scsih_add_device(ioc, handle, 0, 1);
4623} 4812}
@@ -4857,7 +5046,7 @@ static void
4857_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, 5046_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4858 struct fw_event_work *fw_event) 5047 struct fw_event_work *fw_event)
4859{ 5048{
4860 u16 handle; 5049 u16 handle, parent_handle;
4861 u32 state; 5050 u32 state;
4862 struct _sas_device *sas_device; 5051 struct _sas_device *sas_device;
4863 unsigned long flags; 5052 unsigned long flags;
@@ -4865,6 +5054,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4865 Mpi2SasDevicePage0_t sas_device_pg0; 5054 Mpi2SasDevicePage0_t sas_device_pg0;
4866 u32 ioc_status; 5055 u32 ioc_status;
4867 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 5056 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
5057 u64 sas_address;
4868 5058
4869 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 5059 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4870 return; 5060 return;
@@ -4906,9 +5096,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4906 return; 5096 return;
4907 } 5097 }
4908 5098
4909 mpt2sas_transport_update_links(ioc, 5099 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
4910 le16_to_cpu(sas_device_pg0.ParentDevHandle), 5100 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
4911 handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); 5101 mpt2sas_transport_update_links(ioc, sas_address, handle,
5102 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
4912 5103
4913 _scsih_add_device(ioc, handle, 0, 1); 5104 _scsih_add_device(ioc, handle, 0, 1);
4914 5105
@@ -4948,11 +5139,17 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4948 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 5139 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
4949 reason_str = "consistency check"; 5140 reason_str = "consistency check";
4950 break; 5141 break;
4951 default: 5142 case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
4952 reason_str = "unknown reason"; 5143 reason_str = "background init";
5144 break;
5145 case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
5146 reason_str = "make data consistent";
4953 break; 5147 break;
4954 } 5148 }
4955 5149
5150 if (!reason_str)
5151 return;
5152
4956 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)" 5153 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
4957 "\thandle(0x%04x), percent complete(%d)\n", 5154 "\thandle(0x%04x), percent complete(%d)\n",
4958 ioc->name, reason_str, 5155 ioc->name, reason_str,
@@ -5252,18 +5449,23 @@ _scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5252{ 5449{
5253 struct _sas_node *sas_expander; 5450 struct _sas_node *sas_expander;
5254 unsigned long flags; 5451 unsigned long flags;
5452 int i;
5255 5453
5256 spin_lock_irqsave(&ioc->sas_node_lock, flags); 5454 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5257 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { 5455 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
5258 if (sas_expander->sas_address == sas_address) { 5456 if (sas_expander->sas_address != sas_address)
5259 sas_expander->responding = 1; 5457 continue;
5260 if (sas_expander->handle != handle) { 5458 sas_expander->responding = 1;
5261 printk(KERN_INFO "old handle(0x%04x)\n", 5459 if (sas_expander->handle == handle)
5262 sas_expander->handle);
5263 sas_expander->handle = handle;
5264 }
5265 goto out; 5460 goto out;
5266 } 5461 printk(KERN_INFO "\texpander(0x%016llx): handle changed"
5462 " from(0x%04x) to (0x%04x)!!!\n",
5463 (unsigned long long)sas_expander->sas_address,
5464 sas_expander->handle, handle);
5465 sas_expander->handle = handle;
5466 for (i = 0 ; i < sas_expander->num_phys ; i++)
5467 sas_expander->phy[i].handle = handle;
5468 goto out;
5267 } 5469 }
5268 out: 5470 out:
5269 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5471 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -5340,7 +5542,9 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5340 (unsigned long long) 5542 (unsigned long long)
5341 sas_device->enclosure_logical_id, 5543 sas_device->enclosure_logical_id,
5342 sas_device->slot); 5544 sas_device->slot);
5343 _scsih_remove_device(ioc, sas_device->handle); 5545 /* invalidate the device handle */
5546 sas_device->handle = 0;
5547 _scsih_remove_device(ioc, sas_device);
5344 } 5548 }
5345 5549
5346 list_for_each_entry_safe(raid_device, raid_device_next, 5550 list_for_each_entry_safe(raid_device, raid_device_next,
@@ -5366,7 +5570,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5366 sas_expander->responding = 0; 5570 sas_expander->responding = 0;
5367 continue; 5571 continue;
5368 } 5572 }
5369 _scsih_expander_remove(ioc, sas_expander->handle); 5573 _scsih_expander_remove(ioc, sas_expander->sas_address);
5370 goto retry_expander_search; 5574 goto retry_expander_search;
5371 } 5575 }
5372} 5576}
@@ -5406,7 +5610,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5406 case MPT2_IOC_DONE_RESET: 5610 case MPT2_IOC_DONE_RESET:
5407 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 5611 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5408 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 5612 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5409 _scsih_sas_host_refresh(ioc, 0); 5613 _scsih_sas_host_refresh(ioc);
5410 _scsih_search_responding_sas_devices(ioc); 5614 _scsih_search_responding_sas_devices(ioc);
5411 _scsih_search_responding_raid_devices(ioc); 5615 _scsih_search_responding_raid_devices(ioc);
5412 _scsih_search_responding_expanders(ioc); 5616 _scsih_search_responding_expanders(ioc);
@@ -5646,7 +5850,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5646 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5850 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5647 if (!sas_device) 5851 if (!sas_device)
5648 continue; 5852 continue;
5649 _scsih_remove_device(ioc, sas_device->handle); 5853 _scsih_remove_device(ioc, sas_device);
5650 if (ioc->shost_recovery) 5854 if (ioc->shost_recovery)
5651 return; 5855 return;
5652 goto retry_device_search; 5856 goto retry_device_search;
@@ -5669,7 +5873,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5669 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 5873 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5670 if (!expander_sibling) 5874 if (!expander_sibling)
5671 continue; 5875 continue;
5672 _scsih_expander_remove(ioc, expander_sibling->handle); 5876 _scsih_expander_remove(ioc,
5877 expander_sibling->sas_address);
5673 if (ioc->shost_recovery) 5878 if (ioc->shost_recovery)
5674 return; 5879 return;
5675 goto retry_expander_search; 5880 goto retry_expander_search;
@@ -5677,7 +5882,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5677 } 5882 }
5678 5883
5679 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 5884 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
5680 sas_expander->parent_handle); 5885 sas_expander->sas_address_parent);
5681 5886
5682 printk(MPT2SAS_INFO_FMT "expander_remove: handle" 5887 printk(MPT2SAS_INFO_FMT "expander_remove: handle"
5683 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, 5888 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
@@ -5690,9 +5895,99 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5690} 5895}
5691 5896
5692/** 5897/**
5898 * _scsih_ir_shutdown - IR shutdown notification
5899 * @ioc: per adapter object
5900 *
5901 * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
5902 * the host system is shutting down.
5903 *
5904 * Return nothing.
5905 */
5906static void
5907_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
5908{
5909 Mpi2RaidActionRequest_t *mpi_request;
5910 Mpi2RaidActionReply_t *mpi_reply;
5911 u16 smid;
5912
5913 /* is IR firmware build loaded ? */
5914 if (!ioc->ir_firmware)
5915 return;
5916
5917 /* are there any volumes ? */
5918 if (list_empty(&ioc->raid_device_list))
5919 return;
5920
5921 mutex_lock(&ioc->scsih_cmds.mutex);
5922
5923 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
5924 printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
5925 ioc->name, __func__);
5926 goto out;
5927 }
5928 ioc->scsih_cmds.status = MPT2_CMD_PENDING;
5929
5930 smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
5931 if (!smid) {
5932 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
5933 ioc->name, __func__);
5934 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
5935 goto out;
5936 }
5937
5938 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
5939 ioc->scsih_cmds.smid = smid;
5940 memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
5941
5942 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
5943 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
5944
5945 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
5946 init_completion(&ioc->scsih_cmds.done);
5947 mpt2sas_base_put_smid_default(ioc, smid);
5948 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
5949
5950 if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
5951 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
5952 ioc->name, __func__);
5953 goto out;
5954 }
5955
5956 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
5957 mpi_reply = ioc->scsih_cmds.reply;
5958
5959 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
5960 "ioc_status(0x%04x), loginfo(0x%08x)\n",
5961 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
5962 le32_to_cpu(mpi_reply->IOCLogInfo));
5963 }
5964
5965 out:
5966 ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
5967 mutex_unlock(&ioc->scsih_cmds.mutex);
5968}
5969
5970/**
5971 * _scsih_shutdown - routine call during system shutdown
5972 * @pdev: PCI device struct
5973 *
5974 * Return nothing.
5975 */
5976static void
5977_scsih_shutdown(struct pci_dev *pdev)
5978{
5979 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5980 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5981
5982 _scsih_ir_shutdown(ioc);
5983 mpt2sas_base_detach(ioc);
5984}
5985
5986/**
5693 * _scsih_remove - detach and remove add host 5987 * _scsih_remove - detach and remove add host
5694 * @pdev: PCI device struct 5988 * @pdev: PCI device struct
5695 * 5989 *
5990 * Routine called when unloading the driver.
5696 * Return nothing. 5991 * Return nothing.
5697 */ 5992 */
5698static void __devexit 5993static void __devexit
@@ -5726,7 +6021,7 @@ _scsih_remove(struct pci_dev *pdev)
5726 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 6021 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5727 mpt2sas_port->remote_identify.sas_address); 6022 mpt2sas_port->remote_identify.sas_address);
5728 if (sas_device) { 6023 if (sas_device) {
5729 _scsih_remove_device(ioc, sas_device->handle); 6024 _scsih_remove_device(ioc, sas_device);
5730 goto retry_again; 6025 goto retry_again;
5731 } 6026 }
5732 } else { 6027 } else {
@@ -5735,7 +6030,7 @@ _scsih_remove(struct pci_dev *pdev)
5735 mpt2sas_port->remote_identify.sas_address); 6030 mpt2sas_port->remote_identify.sas_address);
5736 if (expander_sibling) { 6031 if (expander_sibling) {
5737 _scsih_expander_remove(ioc, 6032 _scsih_expander_remove(ioc,
5738 expander_sibling->handle); 6033 expander_sibling->sas_address);
5739 goto retry_again; 6034 goto retry_again;
5740 } 6035 }
5741 } 6036 }
@@ -5749,7 +6044,7 @@ _scsih_remove(struct pci_dev *pdev)
5749 } 6044 }
5750 6045
5751 sas_remove_host(shost); 6046 sas_remove_host(shost);
5752 mpt2sas_base_detach(ioc); 6047 _scsih_shutdown(pdev);
5753 list_del(&ioc->list); 6048 list_del(&ioc->list);
5754 scsi_remove_host(shost); 6049 scsi_remove_host(shost);
5755 scsi_host_put(shost); 6050 scsi_host_put(shost);
@@ -5770,7 +6065,8 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5770 void *device; 6065 void *device;
5771 struct _sas_device *sas_device; 6066 struct _sas_device *sas_device;
5772 struct _raid_device *raid_device; 6067 struct _raid_device *raid_device;
5773 u16 handle, parent_handle; 6068 u16 handle;
6069 u64 sas_address_parent;
5774 u64 sas_address; 6070 u64 sas_address;
5775 unsigned long flags; 6071 unsigned long flags;
5776 int rc; 6072 int rc;
@@ -5799,17 +6095,17 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5799 } else { 6095 } else {
5800 sas_device = device; 6096 sas_device = device;
5801 handle = sas_device->handle; 6097 handle = sas_device->handle;
5802 parent_handle = sas_device->parent_handle; 6098 sas_address_parent = sas_device->sas_address_parent;
5803 sas_address = sas_device->sas_address; 6099 sas_address = sas_device->sas_address;
5804 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6100 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5805 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6101 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5806 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6102 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5807 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 6103 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5808 sas_device->parent_handle)) { 6104 sas_device->sas_address_parent)) {
5809 _scsih_sas_device_remove(ioc, sas_device); 6105 _scsih_sas_device_remove(ioc, sas_device);
5810 } else if (!sas_device->starget) { 6106 } else if (!sas_device->starget) {
5811 mpt2sas_transport_port_remove(ioc, sas_address, 6107 mpt2sas_transport_port_remove(ioc, sas_address,
5812 parent_handle); 6108 sas_address_parent);
5813 _scsih_sas_device_remove(ioc, sas_device); 6109 _scsih_sas_device_remove(ioc, sas_device);
5814 } 6110 }
5815 } 6111 }
@@ -5849,8 +6145,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5849{ 6145{
5850 struct _sas_device *sas_device, *next; 6146 struct _sas_device *sas_device, *next;
5851 unsigned long flags; 6147 unsigned long flags;
5852 u16 handle, parent_handle;
5853 u64 sas_address;
5854 6148
5855 /* SAS Device List */ 6149 /* SAS Device List */
5856 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 6150 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
@@ -5859,14 +6153,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5859 list_move_tail(&sas_device->list, &ioc->sas_device_list); 6153 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5860 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 6154 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5861 6155
5862 handle = sas_device->handle; 6156 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5863 parent_handle = sas_device->parent_handle; 6157 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); 6158 _scsih_sas_device_remove(ioc, sas_device);
5867 } else if (!sas_device->starget) { 6159 } else if (!sas_device->starget) {
5868 mpt2sas_transport_port_remove(ioc, sas_address, 6160 mpt2sas_transport_port_remove(ioc,
5869 parent_handle); 6161 sas_device->sas_address,
6162 sas_device->sas_address_parent);
5870 _scsih_sas_device_remove(ioc, sas_device); 6163 _scsih_sas_device_remove(ioc, sas_device);
5871 } 6164 }
5872 } 6165 }
@@ -5935,6 +6228,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5935 ioc->ctl_cb_idx = ctl_cb_idx; 6228 ioc->ctl_cb_idx = ctl_cb_idx;
5936 ioc->base_cb_idx = base_cb_idx; 6229 ioc->base_cb_idx = base_cb_idx;
5937 ioc->transport_cb_idx = transport_cb_idx; 6230 ioc->transport_cb_idx = transport_cb_idx;
6231 ioc->scsih_cb_idx = scsih_cb_idx;
5938 ioc->config_cb_idx = config_cb_idx; 6232 ioc->config_cb_idx = config_cb_idx;
5939 ioc->tm_tr_cb_idx = tm_tr_cb_idx; 6233 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
5940 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; 6234 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
@@ -6072,6 +6366,7 @@ static struct pci_driver scsih_driver = {
6072 .id_table = scsih_pci_table, 6366 .id_table = scsih_pci_table,
6073 .probe = _scsih_probe, 6367 .probe = _scsih_probe,
6074 .remove = __devexit_p(_scsih_remove), 6368 .remove = __devexit_p(_scsih_remove),
6369 .shutdown = _scsih_shutdown,
6075#ifdef CONFIG_PM 6370#ifdef CONFIG_PM
6076 .suspend = _scsih_suspend, 6371 .suspend = _scsih_suspend,
6077 .resume = _scsih_resume, 6372 .resume = _scsih_resume,
@@ -6113,6 +6408,9 @@ _scsih_init(void)
6113 transport_cb_idx = mpt2sas_base_register_callback_handler( 6408 transport_cb_idx = mpt2sas_base_register_callback_handler(
6114 mpt2sas_transport_done); 6409 mpt2sas_transport_done);
6115 6410
6411 /* scsih internal commands callback handler */
6412 scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
6413
6116 /* configuration page API internal commands callback handler */ 6414 /* configuration page API internal commands callback handler */
6117 config_cb_idx = mpt2sas_base_register_callback_handler( 6415 config_cb_idx = mpt2sas_base_register_callback_handler(
6118 mpt2sas_config_done); 6416 mpt2sas_config_done);
@@ -6152,6 +6450,7 @@ _scsih_exit(void)
6152 mpt2sas_base_release_callback_handler(tm_cb_idx); 6450 mpt2sas_base_release_callback_handler(tm_cb_idx);
6153 mpt2sas_base_release_callback_handler(base_cb_idx); 6451 mpt2sas_base_release_callback_handler(base_cb_idx);
6154 mpt2sas_base_release_callback_handler(transport_cb_idx); 6452 mpt2sas_base_release_callback_handler(transport_cb_idx);
6453 mpt2sas_base_release_callback_handler(scsih_cb_idx);
6155 mpt2sas_base_release_callback_handler(config_cb_idx); 6454 mpt2sas_base_release_callback_handler(config_cb_idx);
6156 mpt2sas_base_release_callback_handler(ctl_cb_idx); 6455 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6157 6456