diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-09-23 07:51:29 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-10-29 13:03:08 -0400 |
commit | c5e039be7e81168a9156e801cfef2adae72e775b (patch) | |
tree | dd190bc63c177cf3f20728bc661df4c24a2c763d /drivers/scsi/mpt2sas/mpt2sas_scsih.c | |
parent | 8d5eb435c3523b15f67c35a5d4defa8d1757f9bd (diff) |
[SCSI] mpt2sas: Driver will use sas address instead of handle as a lookup
The device driver was not handling updating device handles in all cases
across diag resets. To fix this issue, the driver is converted to using sas
address instead of handle as a lookup reference to the parent expander or
sas_host. Also, for both expanders and sas host, the phy handle will be one
unique handle. In the sas host case, the phy handle can be different for
every phy, so the change is to set the handle to the handle of the first
phy; every phy will be one single sas address(phy 0) instead of a different
sas address for every phy(previous implementation). So making one consistent
sas address for all the direct attachedports to the sas host, will make it
better user experience when using udev /dev/disk/by-path dev nodes
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: Eric Moore <Eric.moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
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 | } |