diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 373 |
1 files changed, 216 insertions, 157 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 86ab32d7ab15..8822cda852ba 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -317,6 +317,47 @@ _scsih_is_boot_device(u64 sas_address, u64 device_name, | |||
317 | } | 317 | } |
318 | 318 | ||
319 | /** | 319 | /** |
320 | * _scsih_get_sas_address - set the sas_address for given device handle | ||
321 | * @handle: device handle | ||
322 | * @sas_address: sas address | ||
323 | * | ||
324 | * Returns 0 success, non-zero when failure | ||
325 | */ | ||
326 | static int | ||
327 | _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle, | ||
328 | u64 *sas_address) | ||
329 | { | ||
330 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
331 | Mpi2ConfigReply_t mpi_reply; | ||
332 | u32 ioc_status; | ||
333 | |||
334 | if (handle <= ioc->sas_hba.num_phys) { | ||
335 | *sas_address = ioc->sas_hba.sas_address; | ||
336 | return 0; | ||
337 | } else | ||
338 | *sas_address = 0; | ||
339 | |||
340 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | ||
341 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | ||
342 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
343 | ioc->name, __FILE__, __LINE__, __func__); | ||
344 | return -ENXIO; | ||
345 | } | ||
346 | |||
347 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
348 | MPI2_IOCSTATUS_MASK; | ||
349 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
350 | printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" | ||
351 | "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status, | ||
352 | __FILE__, __LINE__, __func__); | ||
353 | return -EIO; | ||
354 | } | ||
355 | |||
356 | *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | /** | ||
320 | * _scsih_determine_boot_device - determine boot device. | 361 | * _scsih_determine_boot_device - determine boot device. |
321 | * @ioc: per adapter object | 362 | * @ioc: per adapter object |
322 | * @device: either sas_device or raid_device object | 363 | * @device: either sas_device or raid_device object |
@@ -510,8 +551,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
510 | struct _sas_device *sas_device) | 551 | struct _sas_device *sas_device) |
511 | { | 552 | { |
512 | unsigned long flags; | 553 | unsigned long flags; |
513 | u16 handle, parent_handle; | ||
514 | u64 sas_address; | ||
515 | 554 | ||
516 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" | 555 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" |
517 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, | 556 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, |
@@ -521,10 +560,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
521 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | 560 | list_add_tail(&sas_device->list, &ioc->sas_device_list); |
522 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 561 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
523 | 562 | ||
524 | handle = sas_device->handle; | 563 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
525 | parent_handle = sas_device->parent_handle; | 564 | 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); | 565 | _scsih_sas_device_remove(ioc, sas_device); |
529 | } | 566 | } |
530 | 567 | ||
@@ -553,31 +590,6 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc, | |||
553 | } | 590 | } |
554 | 591 | ||
555 | /** | 592 | /** |
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 | */ | ||
564 | struct _sas_node * | ||
565 | mpt2sas_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 | 593 | * _scsih_raid_device_find_by_id - raid device search |
582 | * @ioc: per adapter object | 594 | * @ioc: per adapter object |
583 | * @id: sas device target id | 595 | * @id: sas device target id |
@@ -699,6 +711,31 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc, | |||
699 | } | 711 | } |
700 | 712 | ||
701 | /** | 713 | /** |
714 | * mpt2sas_scsih_expander_find_by_handle - expander device search | ||
715 | * @ioc: per adapter object | ||
716 | * @handle: expander handle (assigned by firmware) | ||
717 | * Context: Calling function should acquire ioc->sas_device_lock | ||
718 | * | ||
719 | * This searches for expander device based on handle, then returns the | ||
720 | * sas_node object. | ||
721 | */ | ||
722 | struct _sas_node * | ||
723 | mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
724 | { | ||
725 | struct _sas_node *sas_expander, *r; | ||
726 | |||
727 | r = NULL; | ||
728 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { | ||
729 | if (sas_expander->handle != handle) | ||
730 | continue; | ||
731 | r = sas_expander; | ||
732 | goto out; | ||
733 | } | ||
734 | out: | ||
735 | return r; | ||
736 | } | ||
737 | |||
738 | /** | ||
702 | * mpt2sas_scsih_expander_find_by_sas_address - expander device search | 739 | * mpt2sas_scsih_expander_find_by_sas_address - expander device search |
703 | * @ioc: per adapter object | 740 | * @ioc: per adapter object |
704 | * @sas_address: sas address | 741 | * @sas_address: sas address |
@@ -3344,7 +3381,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3344 | /** | 3381 | /** |
3345 | * _scsih_sas_host_refresh - refreshing sas host object contents | 3382 | * _scsih_sas_host_refresh - refreshing sas host object contents |
3346 | * @ioc: per adapter object | 3383 | * @ioc: per adapter object |
3347 | * @update: update link information | ||
3348 | * Context: user | 3384 | * Context: user |
3349 | * | 3385 | * |
3350 | * During port enable, fw will send topology events for every device. Its | 3386 | * During port enable, fw will send topology events for every device. Its |
@@ -3354,13 +3390,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3354 | * Return nothing. | 3390 | * Return nothing. |
3355 | */ | 3391 | */ |
3356 | static void | 3392 | static void |
3357 | _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) | 3393 | _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc) |
3358 | { | 3394 | { |
3359 | u16 sz; | 3395 | u16 sz; |
3360 | u16 ioc_status; | 3396 | u16 ioc_status; |
3361 | int i; | 3397 | int i; |
3362 | Mpi2ConfigReply_t mpi_reply; | 3398 | Mpi2ConfigReply_t mpi_reply; |
3363 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; | 3399 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; |
3400 | u16 attached_handle; | ||
3364 | 3401 | ||
3365 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 3402 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
3366 | "updating handles for sas_host(0x%016llx)\n", | 3403 | "updating handles for sas_host(0x%016llx)\n", |
@@ -3374,27 +3411,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update) | |||
3374 | ioc->name, __FILE__, __LINE__, __func__); | 3411 | ioc->name, __FILE__, __LINE__, __func__); |
3375 | return; | 3412 | return; |
3376 | } | 3413 | } |
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 | 3414 | ||
3415 | if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, | ||
3416 | sas_iounit_pg0, sz)) != 0) | ||
3417 | goto out; | ||
3418 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; | ||
3419 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | ||
3420 | goto out; | ||
3421 | for (i = 0; i < ioc->sas_hba.num_phys ; i++) { | ||
3422 | if (i == 0) | ||
3423 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> | ||
3424 | PhyData[0].ControllerDevHandle); | ||
3425 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; | ||
3426 | attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. | ||
3427 | AttachedDevHandle); | ||
3428 | mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, | ||
3429 | attached_handle, i, sas_iounit_pg0->PhyData[i]. | ||
3430 | NegotiatedLinkRate >> 4); | ||
3431 | } | ||
3398 | out: | 3432 | out: |
3399 | kfree(sas_iounit_pg0); | 3433 | kfree(sas_iounit_pg0); |
3400 | } | 3434 | } |
@@ -3507,19 +3541,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc) | |||
3507 | ioc->name, __FILE__, __LINE__, __func__); | 3541 | ioc->name, __FILE__, __LINE__, __func__); |
3508 | goto out; | 3542 | goto out; |
3509 | } | 3543 | } |
3510 | ioc->sas_hba.phy[i].handle = | 3544 | |
3511 | le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle); | 3545 | if (i == 0) |
3546 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> | ||
3547 | PhyData[0].ControllerDevHandle); | ||
3548 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; | ||
3512 | ioc->sas_hba.phy[i].phy_id = i; | 3549 | ioc->sas_hba.phy[i].phy_id = i; |
3513 | mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], | 3550 | mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], |
3514 | phy_pg0, ioc->sas_hba.parent_dev); | 3551 | phy_pg0, ioc->sas_hba.parent_dev); |
3515 | } | 3552 | } |
3516 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | 3553 | 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))) { | 3554 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) { |
3518 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3555 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
3519 | ioc->name, __FILE__, __LINE__, __func__); | 3556 | ioc->name, __FILE__, __LINE__, __func__); |
3520 | goto out; | 3557 | goto out; |
3521 | } | 3558 | } |
3522 | ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle); | ||
3523 | ioc->sas_hba.enclosure_handle = | 3559 | ioc->sas_hba.enclosure_handle = |
3524 | le16_to_cpu(sas_device_pg0.EnclosureHandle); | 3560 | le16_to_cpu(sas_device_pg0.EnclosureHandle); |
3525 | ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | 3561 | ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); |
@@ -3562,7 +3598,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3562 | Mpi2SasEnclosurePage0_t enclosure_pg0; | 3598 | Mpi2SasEnclosurePage0_t enclosure_pg0; |
3563 | u32 ioc_status; | 3599 | u32 ioc_status; |
3564 | u16 parent_handle; | 3600 | u16 parent_handle; |
3565 | __le64 sas_address; | 3601 | __le64 sas_address, sas_address_parent = 0; |
3566 | int i; | 3602 | int i; |
3567 | unsigned long flags; | 3603 | unsigned long flags; |
3568 | struct _sas_port *mpt2sas_port = NULL; | 3604 | struct _sas_port *mpt2sas_port = NULL; |
@@ -3591,10 +3627,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3591 | 3627 | ||
3592 | /* handle out of order topology events */ | 3628 | /* handle out of order topology events */ |
3593 | parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); | 3629 | parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); |
3594 | if (parent_handle >= ioc->sas_hba.num_phys) { | 3630 | if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent) |
3631 | != 0) { | ||
3632 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
3633 | ioc->name, __FILE__, __LINE__, __func__); | ||
3634 | return -1; | ||
3635 | } | ||
3636 | if (sas_address_parent != ioc->sas_hba.sas_address) { | ||
3595 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 3637 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
3596 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, | 3638 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, |
3597 | parent_handle); | 3639 | sas_address_parent); |
3598 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 3640 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
3599 | if (!sas_expander) { | 3641 | if (!sas_expander) { |
3600 | rc = _scsih_expander_add(ioc, parent_handle); | 3642 | rc = _scsih_expander_add(ioc, parent_handle); |
@@ -3622,14 +3664,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3622 | 3664 | ||
3623 | sas_expander->handle = handle; | 3665 | sas_expander->handle = handle; |
3624 | sas_expander->num_phys = expander_pg0.NumPhys; | 3666 | sas_expander->num_phys = expander_pg0.NumPhys; |
3625 | sas_expander->parent_handle = parent_handle; | 3667 | 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; | 3668 | sas_expander->sas_address = sas_address; |
3629 | 3669 | ||
3630 | printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," | 3670 | printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x)," |
3631 | " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, | 3671 | " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, |
3632 | handle, sas_expander->parent_handle, (unsigned long long) | 3672 | handle, parent_handle, (unsigned long long) |
3633 | sas_expander->sas_address, sas_expander->num_phys); | 3673 | sas_expander->sas_address, sas_expander->num_phys); |
3634 | 3674 | ||
3635 | if (!sas_expander->num_phys) | 3675 | if (!sas_expander->num_phys) |
@@ -3645,7 +3685,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3645 | 3685 | ||
3646 | INIT_LIST_HEAD(&sas_expander->sas_port_list); | 3686 | INIT_LIST_HEAD(&sas_expander->sas_port_list); |
3647 | mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, | 3687 | mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, |
3648 | sas_expander->parent_handle); | 3688 | sas_address_parent); |
3649 | if (!mpt2sas_port) { | 3689 | if (!mpt2sas_port) { |
3650 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3690 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
3651 | ioc->name, __FILE__, __LINE__, __func__); | 3691 | ioc->name, __FILE__, __LINE__, __func__); |
@@ -3691,7 +3731,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3691 | 3731 | ||
3692 | if (mpt2sas_port) | 3732 | if (mpt2sas_port) |
3693 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, | 3733 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
3694 | sas_expander->parent_handle); | 3734 | sas_address_parent); |
3695 | kfree(sas_expander); | 3735 | kfree(sas_expander); |
3696 | return rc; | 3736 | return rc; |
3697 | } | 3737 | } |
@@ -3699,12 +3739,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3699 | /** | 3739 | /** |
3700 | * _scsih_expander_remove - removing expander object | 3740 | * _scsih_expander_remove - removing expander object |
3701 | * @ioc: per adapter object | 3741 | * @ioc: per adapter object |
3702 | * @handle: expander handle | 3742 | * @sas_address: expander sas_address |
3703 | * | 3743 | * |
3704 | * Return nothing. | 3744 | * Return nothing. |
3705 | */ | 3745 | */ |
3706 | static void | 3746 | static void |
3707 | _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 3747 | _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) |
3708 | { | 3748 | { |
3709 | struct _sas_node *sas_expander; | 3749 | struct _sas_node *sas_expander; |
3710 | unsigned long flags; | 3750 | unsigned long flags; |
@@ -3713,7 +3753,8 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3713 | return; | 3753 | return; |
3714 | 3754 | ||
3715 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 3755 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
3716 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); | 3756 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, |
3757 | sas_address); | ||
3717 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 3758 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
3718 | _scsih_expander_node_remove(ioc, sas_expander); | 3759 | _scsih_expander_node_remove(ioc, sas_expander); |
3719 | } | 3760 | } |
@@ -3805,8 +3846,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
3805 | } | 3846 | } |
3806 | 3847 | ||
3807 | sas_device->handle = handle; | 3848 | sas_device->handle = handle; |
3808 | sas_device->parent_handle = | 3849 | if (_scsih_get_sas_address(ioc, le16_to_cpu |
3809 | le16_to_cpu(sas_device_pg0.ParentDevHandle); | 3850 | (sas_device_pg0.ParentDevHandle), |
3851 | &sas_device->sas_address_parent) != 0) | ||
3852 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
3853 | ioc->name, __FILE__, __LINE__, __func__); | ||
3810 | sas_device->enclosure_handle = | 3854 | sas_device->enclosure_handle = |
3811 | le16_to_cpu(sas_device_pg0.EnclosureHandle); | 3855 | le16_to_cpu(sas_device_pg0.EnclosureHandle); |
3812 | sas_device->slot = | 3856 | sas_device->slot = |
@@ -3836,43 +3880,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
3836 | /** | 3880 | /** |
3837 | * _scsih_remove_device - removing sas device object | 3881 | * _scsih_remove_device - removing sas device object |
3838 | * @ioc: per adapter object | 3882 | * @ioc: per adapter object |
3839 | * @handle: sas device handle | 3883 | * @sas_device: the sas_device object |
3840 | * | 3884 | * |
3841 | * Return nothing. | 3885 | * Return nothing. |
3842 | */ | 3886 | */ |
3843 | static void | 3887 | static void |
3844 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 3888 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device |
3889 | *sas_device) | ||
3845 | { | 3890 | { |
3846 | struct MPT2SAS_TARGET *sas_target_priv_data; | 3891 | struct MPT2SAS_TARGET *sas_target_priv_data; |
3847 | struct _sas_device *sas_device; | ||
3848 | unsigned long flags; | ||
3849 | Mpi2SasIoUnitControlReply_t mpi_reply; | 3892 | Mpi2SasIoUnitControlReply_t mpi_reply; |
3850 | Mpi2SasIoUnitControlRequest_t mpi_request; | 3893 | Mpi2SasIoUnitControlRequest_t mpi_request; |
3851 | u16 device_handle; | 3894 | u16 device_handle, handle; |
3852 | 3895 | ||
3853 | /* lookup sas_device */ | 3896 | 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; | 3897 | return; |
3859 | } | ||
3860 | 3898 | ||
3861 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle" | 3899 | handle = sas_device->handle; |
3862 | "(0x%04x)\n", ioc->name, __func__, handle)); | 3900 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," |
3901 | " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, | ||
3902 | (unsigned long long) sas_device->sas_address)); | ||
3863 | 3903 | ||
3864 | if (sas_device->starget && sas_device->starget->hostdata) { | 3904 | if (sas_device->starget && sas_device->starget->hostdata) { |
3865 | sas_target_priv_data = sas_device->starget->hostdata; | 3905 | sas_target_priv_data = sas_device->starget->hostdata; |
3866 | sas_target_priv_data->deleted = 1; | 3906 | sas_target_priv_data->deleted = 1; |
3867 | } | 3907 | } |
3868 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
3869 | 3908 | ||
3870 | if (ioc->remove_host) | 3909 | if (ioc->remove_host || ioc->shost_recovery || !handle) |
3871 | goto out; | 3910 | goto out; |
3872 | 3911 | ||
3873 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { | 3912 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { |
3874 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | 3913 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " |
3875 | "target_reset handle(0x%04x)\n", ioc->name, handle)); | 3914 | "target_reset handle(0x%04x)\n", ioc->name, |
3915 | handle)); | ||
3876 | goto skip_tr; | 3916 | goto skip_tr; |
3877 | } | 3917 | } |
3878 | 3918 | ||
@@ -3925,10 +3965,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3925 | _scsih_ublock_io_device(ioc, handle); | 3965 | _scsih_ublock_io_device(ioc, handle); |
3926 | 3966 | ||
3927 | mpt2sas_transport_port_remove(ioc, sas_device->sas_address, | 3967 | mpt2sas_transport_port_remove(ioc, sas_device->sas_address, |
3928 | sas_device->parent_handle); | 3968 | sas_device->sas_address_parent); |
3929 | 3969 | ||
3930 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" | 3970 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" |
3931 | "(0x%016llx)\n", ioc->name, sas_device->handle, | 3971 | "(0x%016llx)\n", ioc->name, handle, |
3932 | (unsigned long long) sas_device->sas_address); | 3972 | (unsigned long long) sas_device->sas_address); |
3933 | _scsih_sas_device_remove(ioc, sas_device); | 3973 | _scsih_sas_device_remove(ioc, sas_device); |
3934 | 3974 | ||
@@ -4031,8 +4071,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4031 | u16 reason_code; | 4071 | u16 reason_code; |
4032 | u8 phy_number; | 4072 | u8 phy_number; |
4033 | struct _sas_node *sas_expander; | 4073 | struct _sas_node *sas_expander; |
4074 | struct _sas_device *sas_device; | ||
4075 | u64 sas_address; | ||
4034 | unsigned long flags; | 4076 | unsigned long flags; |
4035 | u8 link_rate_; | 4077 | u8 link_rate; |
4036 | Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; | 4078 | Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; |
4037 | 4079 | ||
4038 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4080 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -4040,10 +4082,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4040 | _scsih_sas_topology_change_event_debug(ioc, event_data); | 4082 | _scsih_sas_topology_change_event_debug(ioc, event_data); |
4041 | #endif | 4083 | #endif |
4042 | 4084 | ||
4085 | if (ioc->shost_recovery) | ||
4086 | return; | ||
4087 | |||
4043 | if (!ioc->sas_hba.num_phys) | 4088 | if (!ioc->sas_hba.num_phys) |
4044 | _scsih_sas_host_add(ioc); | 4089 | _scsih_sas_host_add(ioc); |
4045 | else | 4090 | else |
4046 | _scsih_sas_host_refresh(ioc, 0); | 4091 | _scsih_sas_host_refresh(ioc); |
4047 | 4092 | ||
4048 | if (fw_event->ignore) { | 4093 | if (fw_event->ignore) { |
4049 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " | 4094 | dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " |
@@ -4058,6 +4103,17 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4058 | if (_scsih_expander_add(ioc, parent_handle) != 0) | 4103 | if (_scsih_expander_add(ioc, parent_handle) != 0) |
4059 | return; | 4104 | return; |
4060 | 4105 | ||
4106 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | ||
4107 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, | ||
4108 | parent_handle); | ||
4109 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | ||
4110 | if (sas_expander) | ||
4111 | sas_address = sas_expander->sas_address; | ||
4112 | else if (parent_handle < ioc->sas_hba.num_phys) | ||
4113 | sas_address = ioc->sas_hba.sas_address; | ||
4114 | else | ||
4115 | return; | ||
4116 | |||
4061 | /* handle siblings events */ | 4117 | /* handle siblings events */ |
4062 | for (i = 0; i < event_data->NumEntries; i++) { | 4118 | for (i = 0; i < event_data->NumEntries; i++) { |
4063 | if (fw_event->ignore) { | 4119 | if (fw_event->ignore) { |
@@ -4077,48 +4133,40 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4077 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 4133 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
4078 | if (!handle) | 4134 | if (!handle) |
4079 | continue; | 4135 | continue; |
4080 | link_rate_ = event_data->PHY[i].LinkRate >> 4; | 4136 | link_rate = event_data->PHY[i].LinkRate >> 4; |
4081 | switch (reason_code) { | 4137 | switch (reason_code) { |
4082 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: | 4138 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: |
4083 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: | 4139 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: |
4084 | if (!parent_handle) { | 4140 | |
4085 | if (phy_number < ioc->sas_hba.num_phys) | 4141 | mpt2sas_transport_update_links(ioc, sas_address, |
4086 | mpt2sas_transport_update_links( | 4142 | handle, phy_number, link_rate); |
4087 | ioc, | 4143 | |
4088 | ioc->sas_hba.phy[phy_number].handle, | 4144 | if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) |
4089 | handle, phy_number, link_rate_); | 4145 | break; |
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) { | 4146 | 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); | 4147 | _scsih_add_device(ioc, handle, phy_number, 0); |
4111 | } | 4148 | } |
4112 | break; | 4149 | break; |
4113 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: | 4150 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: |
4114 | _scsih_remove_device(ioc, handle); | 4151 | |
4152 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
4153 | sas_device = _scsih_sas_device_find_by_handle(ioc, | ||
4154 | handle); | ||
4155 | if (!sas_device) { | ||
4156 | spin_unlock_irqrestore(&ioc->sas_device_lock, | ||
4157 | flags); | ||
4158 | break; | ||
4159 | } | ||
4160 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4161 | _scsih_remove_device(ioc, sas_device); | ||
4115 | break; | 4162 | break; |
4116 | } | 4163 | } |
4117 | } | 4164 | } |
4118 | 4165 | ||
4119 | /* handle expander removal */ | 4166 | /* handle expander removal */ |
4120 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) | 4167 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && |
4121 | _scsih_expander_remove(ioc, parent_handle); | 4168 | sas_expander) |
4169 | _scsih_expander_remove(ioc, sas_address); | ||
4122 | 4170 | ||
4123 | } | 4171 | } |
4124 | 4172 | ||
@@ -4570,7 +4618,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc, | |||
4570 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4618 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4571 | if (!sas_device) | 4619 | if (!sas_device) |
4572 | return; | 4620 | return; |
4573 | _scsih_remove_device(ioc, handle); | 4621 | _scsih_remove_device(ioc, sas_device); |
4574 | } | 4622 | } |
4575 | 4623 | ||
4576 | /** | 4624 | /** |
@@ -4591,6 +4639,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
4591 | Mpi2ConfigReply_t mpi_reply; | 4639 | Mpi2ConfigReply_t mpi_reply; |
4592 | Mpi2SasDevicePage0_t sas_device_pg0; | 4640 | Mpi2SasDevicePage0_t sas_device_pg0; |
4593 | u32 ioc_status; | 4641 | u32 ioc_status; |
4642 | u64 sas_address; | ||
4643 | u16 parent_handle; | ||
4594 | 4644 | ||
4595 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4645 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4596 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4646 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
@@ -4615,9 +4665,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
4615 | return; | 4665 | return; |
4616 | } | 4666 | } |
4617 | 4667 | ||
4618 | mpt2sas_transport_update_links(ioc, | 4668 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
4619 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | 4669 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) |
4620 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | 4670 | mpt2sas_transport_update_links(ioc, sas_address, handle, |
4671 | sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4621 | 4672 | ||
4622 | _scsih_add_device(ioc, handle, 0, 1); | 4673 | _scsih_add_device(ioc, handle, 0, 1); |
4623 | } | 4674 | } |
@@ -4857,7 +4908,7 @@ static void | |||
4857 | _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | 4908 | _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, |
4858 | struct fw_event_work *fw_event) | 4909 | struct fw_event_work *fw_event) |
4859 | { | 4910 | { |
4860 | u16 handle; | 4911 | u16 handle, parent_handle; |
4861 | u32 state; | 4912 | u32 state; |
4862 | struct _sas_device *sas_device; | 4913 | struct _sas_device *sas_device; |
4863 | unsigned long flags; | 4914 | unsigned long flags; |
@@ -4865,6 +4916,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
4865 | Mpi2SasDevicePage0_t sas_device_pg0; | 4916 | Mpi2SasDevicePage0_t sas_device_pg0; |
4866 | u32 ioc_status; | 4917 | u32 ioc_status; |
4867 | Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; | 4918 | Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; |
4919 | u64 sas_address; | ||
4868 | 4920 | ||
4869 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) | 4921 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) |
4870 | return; | 4922 | return; |
@@ -4906,9 +4958,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
4906 | return; | 4958 | return; |
4907 | } | 4959 | } |
4908 | 4960 | ||
4909 | mpt2sas_transport_update_links(ioc, | 4961 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
4910 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | 4962 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) |
4911 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | 4963 | mpt2sas_transport_update_links(ioc, sas_address, handle, |
4964 | sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4912 | 4965 | ||
4913 | _scsih_add_device(ioc, handle, 0, 1); | 4966 | _scsih_add_device(ioc, handle, 0, 1); |
4914 | 4967 | ||
@@ -5252,18 +5305,23 @@ _scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5252 | { | 5305 | { |
5253 | struct _sas_node *sas_expander; | 5306 | struct _sas_node *sas_expander; |
5254 | unsigned long flags; | 5307 | unsigned long flags; |
5308 | int i; | ||
5255 | 5309 | ||
5256 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 5310 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
5257 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { | 5311 | list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { |
5258 | if (sas_expander->sas_address == sas_address) { | 5312 | if (sas_expander->sas_address != sas_address) |
5259 | sas_expander->responding = 1; | 5313 | continue; |
5260 | if (sas_expander->handle != handle) { | 5314 | sas_expander->responding = 1; |
5261 | printk(KERN_INFO "old handle(0x%04x)\n", | 5315 | if (sas_expander->handle == handle) |
5262 | sas_expander->handle); | ||
5263 | sas_expander->handle = handle; | ||
5264 | } | ||
5265 | goto out; | 5316 | goto out; |
5266 | } | 5317 | printk(KERN_INFO "\texpander(0x%016llx): handle changed" |
5318 | " from(0x%04x) to (0x%04x)!!!\n", | ||
5319 | (unsigned long long)sas_expander->sas_address, | ||
5320 | sas_expander->handle, handle); | ||
5321 | sas_expander->handle = handle; | ||
5322 | for (i = 0 ; i < sas_expander->num_phys ; i++) | ||
5323 | sas_expander->phy[i].handle = handle; | ||
5324 | goto out; | ||
5267 | } | 5325 | } |
5268 | out: | 5326 | out: |
5269 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 5327 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
@@ -5340,7 +5398,9 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5340 | (unsigned long long) | 5398 | (unsigned long long) |
5341 | sas_device->enclosure_logical_id, | 5399 | sas_device->enclosure_logical_id, |
5342 | sas_device->slot); | 5400 | sas_device->slot); |
5343 | _scsih_remove_device(ioc, sas_device->handle); | 5401 | /* invalidate the device handle */ |
5402 | sas_device->handle = 0; | ||
5403 | _scsih_remove_device(ioc, sas_device); | ||
5344 | } | 5404 | } |
5345 | 5405 | ||
5346 | list_for_each_entry_safe(raid_device, raid_device_next, | 5406 | list_for_each_entry_safe(raid_device, raid_device_next, |
@@ -5366,7 +5426,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5366 | sas_expander->responding = 0; | 5426 | sas_expander->responding = 0; |
5367 | continue; | 5427 | continue; |
5368 | } | 5428 | } |
5369 | _scsih_expander_remove(ioc, sas_expander->handle); | 5429 | _scsih_expander_remove(ioc, sas_expander->sas_address); |
5370 | goto retry_expander_search; | 5430 | goto retry_expander_search; |
5371 | } | 5431 | } |
5372 | } | 5432 | } |
@@ -5406,7 +5466,7 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
5406 | case MPT2_IOC_DONE_RESET: | 5466 | case MPT2_IOC_DONE_RESET: |
5407 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " | 5467 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " |
5408 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 5468 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
5409 | _scsih_sas_host_refresh(ioc, 0); | 5469 | _scsih_sas_host_refresh(ioc); |
5410 | _scsih_search_responding_sas_devices(ioc); | 5470 | _scsih_search_responding_sas_devices(ioc); |
5411 | _scsih_search_responding_raid_devices(ioc); | 5471 | _scsih_search_responding_raid_devices(ioc); |
5412 | _scsih_search_responding_expanders(ioc); | 5472 | _scsih_search_responding_expanders(ioc); |
@@ -5646,7 +5706,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5646 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5706 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5647 | if (!sas_device) | 5707 | if (!sas_device) |
5648 | continue; | 5708 | continue; |
5649 | _scsih_remove_device(ioc, sas_device->handle); | 5709 | _scsih_remove_device(ioc, sas_device); |
5650 | if (ioc->shost_recovery) | 5710 | if (ioc->shost_recovery) |
5651 | return; | 5711 | return; |
5652 | goto retry_device_search; | 5712 | goto retry_device_search; |
@@ -5669,7 +5729,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5669 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 5729 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
5670 | if (!expander_sibling) | 5730 | if (!expander_sibling) |
5671 | continue; | 5731 | continue; |
5672 | _scsih_expander_remove(ioc, expander_sibling->handle); | 5732 | _scsih_expander_remove(ioc, |
5733 | expander_sibling->sas_address); | ||
5673 | if (ioc->shost_recovery) | 5734 | if (ioc->shost_recovery) |
5674 | return; | 5735 | return; |
5675 | goto retry_expander_search; | 5736 | goto retry_expander_search; |
@@ -5677,7 +5738,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
5677 | } | 5738 | } |
5678 | 5739 | ||
5679 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, | 5740 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
5680 | sas_expander->parent_handle); | 5741 | sas_expander->sas_address_parent); |
5681 | 5742 | ||
5682 | printk(MPT2SAS_INFO_FMT "expander_remove: handle" | 5743 | printk(MPT2SAS_INFO_FMT "expander_remove: handle" |
5683 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, | 5744 | "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, |
@@ -5726,7 +5787,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
5726 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 5787 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
5727 | mpt2sas_port->remote_identify.sas_address); | 5788 | mpt2sas_port->remote_identify.sas_address); |
5728 | if (sas_device) { | 5789 | if (sas_device) { |
5729 | _scsih_remove_device(ioc, sas_device->handle); | 5790 | _scsih_remove_device(ioc, sas_device); |
5730 | goto retry_again; | 5791 | goto retry_again; |
5731 | } | 5792 | } |
5732 | } else { | 5793 | } else { |
@@ -5735,7 +5796,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
5735 | mpt2sas_port->remote_identify.sas_address); | 5796 | mpt2sas_port->remote_identify.sas_address); |
5736 | if (expander_sibling) { | 5797 | if (expander_sibling) { |
5737 | _scsih_expander_remove(ioc, | 5798 | _scsih_expander_remove(ioc, |
5738 | expander_sibling->handle); | 5799 | expander_sibling->sas_address); |
5739 | goto retry_again; | 5800 | goto retry_again; |
5740 | } | 5801 | } |
5741 | } | 5802 | } |
@@ -5770,7 +5831,8 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5770 | void *device; | 5831 | void *device; |
5771 | struct _sas_device *sas_device; | 5832 | struct _sas_device *sas_device; |
5772 | struct _raid_device *raid_device; | 5833 | struct _raid_device *raid_device; |
5773 | u16 handle, parent_handle; | 5834 | u16 handle; |
5835 | u64 sas_address_parent; | ||
5774 | u64 sas_address; | 5836 | u64 sas_address; |
5775 | unsigned long flags; | 5837 | unsigned long flags; |
5776 | int rc; | 5838 | int rc; |
@@ -5799,17 +5861,17 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
5799 | } else { | 5861 | } else { |
5800 | sas_device = device; | 5862 | sas_device = device; |
5801 | handle = sas_device->handle; | 5863 | handle = sas_device->handle; |
5802 | parent_handle = sas_device->parent_handle; | 5864 | sas_address_parent = sas_device->sas_address_parent; |
5803 | sas_address = sas_device->sas_address; | 5865 | sas_address = sas_device->sas_address; |
5804 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5866 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5805 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 5867 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
5806 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5868 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5807 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 5869 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
5808 | sas_device->parent_handle)) { | 5870 | sas_device->sas_address_parent)) { |
5809 | _scsih_sas_device_remove(ioc, sas_device); | 5871 | _scsih_sas_device_remove(ioc, sas_device); |
5810 | } else if (!sas_device->starget) { | 5872 | } else if (!sas_device->starget) { |
5811 | mpt2sas_transport_port_remove(ioc, sas_address, | 5873 | mpt2sas_transport_port_remove(ioc, sas_address, |
5812 | parent_handle); | 5874 | sas_address_parent); |
5813 | _scsih_sas_device_remove(ioc, sas_device); | 5875 | _scsih_sas_device_remove(ioc, sas_device); |
5814 | } | 5876 | } |
5815 | } | 5877 | } |
@@ -5849,8 +5911,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
5849 | { | 5911 | { |
5850 | struct _sas_device *sas_device, *next; | 5912 | struct _sas_device *sas_device, *next; |
5851 | unsigned long flags; | 5913 | unsigned long flags; |
5852 | u16 handle, parent_handle; | ||
5853 | u64 sas_address; | ||
5854 | 5914 | ||
5855 | /* SAS Device List */ | 5915 | /* SAS Device List */ |
5856 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, | 5916 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, |
@@ -5859,14 +5919,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
5859 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 5919 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
5860 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5920 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5861 | 5921 | ||
5862 | handle = sas_device->handle; | 5922 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
5863 | parent_handle = sas_device->parent_handle; | 5923 | 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); | 5924 | _scsih_sas_device_remove(ioc, sas_device); |
5867 | } else if (!sas_device->starget) { | 5925 | } else if (!sas_device->starget) { |
5868 | mpt2sas_transport_port_remove(ioc, sas_address, | 5926 | mpt2sas_transport_port_remove(ioc, |
5869 | parent_handle); | 5927 | sas_device->sas_address, |
5928 | sas_device->sas_address_parent); | ||
5870 | _scsih_sas_device_remove(ioc, sas_device); | 5929 | _scsih_sas_device_remove(ioc, sas_device); |
5871 | } | 5930 | } |
5872 | } | 5931 | } |