diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_discover.c')
-rw-r--r-- | drivers/scsi/libsas/sas_discover.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index fb7df7b75811..a65598b1e536 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
@@ -548,7 +548,7 @@ int sas_discover_sata(struct domain_device *dev) | |||
548 | 548 | ||
549 | res = sas_notify_lldd_dev_found(dev); | 549 | res = sas_notify_lldd_dev_found(dev); |
550 | if (res) | 550 | if (res) |
551 | return res; | 551 | goto out_err2; |
552 | 552 | ||
553 | switch (dev->dev_type) { | 553 | switch (dev->dev_type) { |
554 | case SATA_DEV: | 554 | case SATA_DEV: |
@@ -560,11 +560,23 @@ int sas_discover_sata(struct domain_device *dev) | |||
560 | default: | 560 | default: |
561 | break; | 561 | break; |
562 | } | 562 | } |
563 | if (res) | ||
564 | goto out_err; | ||
563 | 565 | ||
564 | sas_notify_lldd_dev_gone(dev); | 566 | sas_notify_lldd_dev_gone(dev); |
565 | if (!res) { | 567 | res = sas_notify_lldd_dev_found(dev); |
566 | sas_notify_lldd_dev_found(dev); | 568 | if (res) |
567 | } | 569 | goto out_err2; |
570 | |||
571 | res = sas_rphy_add(dev->rphy); | ||
572 | if (res) | ||
573 | goto out_err; | ||
574 | |||
575 | return res; | ||
576 | |||
577 | out_err: | ||
578 | sas_notify_lldd_dev_gone(dev); | ||
579 | out_err2: | ||
568 | return res; | 580 | return res; |
569 | } | 581 | } |
570 | 582 | ||
@@ -580,21 +592,17 @@ int sas_discover_end_dev(struct domain_device *dev) | |||
580 | 592 | ||
581 | res = sas_notify_lldd_dev_found(dev); | 593 | res = sas_notify_lldd_dev_found(dev); |
582 | if (res) | 594 | if (res) |
583 | return res; | 595 | goto out_err2; |
584 | 596 | ||
585 | res = sas_rphy_add(dev->rphy); | 597 | res = sas_rphy_add(dev->rphy); |
586 | if (res) | 598 | if (res) |
587 | goto out_err; | 599 | goto out_err; |
588 | 600 | ||
589 | /* do this to get the end device port attributes which will have | ||
590 | * been scanned in sas_rphy_add */ | ||
591 | sas_notify_lldd_dev_gone(dev); | ||
592 | sas_notify_lldd_dev_found(dev); | ||
593 | |||
594 | return 0; | 601 | return 0; |
595 | 602 | ||
596 | out_err: | 603 | out_err: |
597 | sas_notify_lldd_dev_gone(dev); | 604 | sas_notify_lldd_dev_gone(dev); |
605 | out_err2: | ||
598 | return res; | 606 | return res; |
599 | } | 607 | } |
600 | 608 | ||
@@ -649,6 +657,7 @@ void sas_unregister_domain_devices(struct asd_sas_port *port) | |||
649 | */ | 657 | */ |
650 | static void sas_discover_domain(struct work_struct *work) | 658 | static void sas_discover_domain(struct work_struct *work) |
651 | { | 659 | { |
660 | struct domain_device *dev; | ||
652 | int error = 0; | 661 | int error = 0; |
653 | struct sas_discovery_event *ev = | 662 | struct sas_discovery_event *ev = |
654 | container_of(work, struct sas_discovery_event, work); | 663 | container_of(work, struct sas_discovery_event, work); |
@@ -658,35 +667,42 @@ static void sas_discover_domain(struct work_struct *work) | |||
658 | &port->disc.pending); | 667 | &port->disc.pending); |
659 | 668 | ||
660 | if (port->port_dev) | 669 | if (port->port_dev) |
661 | return ; | 670 | return; |
662 | else { | 671 | |
663 | error = sas_get_port_device(port); | 672 | error = sas_get_port_device(port); |
664 | if (error) | 673 | if (error) |
665 | return; | 674 | return; |
666 | } | 675 | dev = port->port_dev; |
667 | 676 | ||
668 | SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, | 677 | SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, |
669 | current->pid); | 678 | current->pid); |
670 | 679 | ||
671 | switch (port->port_dev->dev_type) { | 680 | switch (dev->dev_type) { |
672 | case SAS_END_DEV: | 681 | case SAS_END_DEV: |
673 | error = sas_discover_end_dev(port->port_dev); | 682 | error = sas_discover_end_dev(dev); |
674 | break; | 683 | break; |
675 | case EDGE_DEV: | 684 | case EDGE_DEV: |
676 | case FANOUT_DEV: | 685 | case FANOUT_DEV: |
677 | error = sas_discover_root_expander(port->port_dev); | 686 | error = sas_discover_root_expander(dev); |
678 | break; | 687 | break; |
679 | case SATA_DEV: | 688 | case SATA_DEV: |
680 | case SATA_PM: | 689 | case SATA_PM: |
681 | error = sas_discover_sata(port->port_dev); | 690 | error = sas_discover_sata(dev); |
682 | break; | 691 | break; |
683 | default: | 692 | default: |
684 | SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type); | 693 | SAS_DPRINTK("unhandled device %d\n", dev->dev_type); |
685 | break; | 694 | break; |
686 | } | 695 | } |
687 | 696 | ||
688 | if (error) { | 697 | if (error) { |
689 | kfree(port->port_dev); /* not kobject_register-ed yet */ | 698 | sas_rphy_free(dev->rphy); |
699 | dev->rphy = NULL; | ||
700 | |||
701 | spin_lock(&port->dev_list_lock); | ||
702 | list_del_init(&dev->dev_list_node); | ||
703 | spin_unlock(&port->dev_list_lock); | ||
704 | |||
705 | kfree(dev); /* not kobject_register-ed yet */ | ||
690 | port->port_dev = NULL; | 706 | port->port_dev = NULL; |
691 | } | 707 | } |
692 | 708 | ||
@@ -726,7 +742,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) | |||
726 | BUG_ON(ev >= DISC_NUM_EVENTS); | 742 | BUG_ON(ev >= DISC_NUM_EVENTS); |
727 | 743 | ||
728 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, | 744 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, |
729 | &disc->disc_work[ev].work, port->ha->core.shost); | 745 | &disc->disc_work[ev].work, port->ha); |
730 | 746 | ||
731 | return 0; | 747 | return 0; |
732 | } | 748 | } |