aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2007-01-11 17:14:49 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-01-13 15:23:36 -0500
commit8880839815265ccc0edaff52ba08d750eea57acb (patch)
treeb98c920cb0cc5bdd90cd3cbf66d4d6a075e37922 /drivers/scsi/libsas
parentbefede3dabd204e9c546cbfbe391b29286c57da2 (diff)
[SCSI] libsas: Clean up rphys/port dev list after a discovery error.
sas_get_port_device assigns a rphy to a domain device in anticipation of finding a disk. When a discovery error occurs in sas_discover_{sata,sas,expander}*, however, we need to clean up that rphy and the port device list so that we don't GPF. In addition, we need to check the result of the second sas_notify_lldd_dev_found. This patch seems ok on a x260, x366 and x206m. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_discover.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index fb7df7b75811..21f538e4a0b5 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,25 @@ 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
577out_err:
578 sas_notify_lldd_dev_gone(dev);
579out_err2:
580 sas_rphy_free(dev->rphy);
581 dev->rphy = NULL;
568 return res; 582 return res;
569} 583}
570 584
@@ -580,7 +594,7 @@ int sas_discover_end_dev(struct domain_device *dev)
580 594
581 res = sas_notify_lldd_dev_found(dev); 595 res = sas_notify_lldd_dev_found(dev);
582 if (res) 596 if (res)
583 return res; 597 goto out_err2;
584 598
585 res = sas_rphy_add(dev->rphy); 599 res = sas_rphy_add(dev->rphy);
586 if (res) 600 if (res)
@@ -589,12 +603,21 @@ int sas_discover_end_dev(struct domain_device *dev)
589 /* do this to get the end device port attributes which will have 603 /* do this to get the end device port attributes which will have
590 * been scanned in sas_rphy_add */ 604 * been scanned in sas_rphy_add */
591 sas_notify_lldd_dev_gone(dev); 605 sas_notify_lldd_dev_gone(dev);
592 sas_notify_lldd_dev_found(dev); 606 res = sas_notify_lldd_dev_found(dev);
607 if (res)
608 goto out_err3;
593 609
594 return 0; 610 return 0;
595 611
596out_err: 612out_err:
597 sas_notify_lldd_dev_gone(dev); 613 sas_notify_lldd_dev_gone(dev);
614out_err2:
615 sas_rphy_free(dev->rphy);
616 dev->rphy = NULL;
617 return res;
618out_err3:
619 sas_rphy_delete(dev->rphy);
620 dev->rphy = NULL;
598 return res; 621 return res;
599} 622}
600 623
@@ -686,6 +709,10 @@ static void sas_discover_domain(struct work_struct *work)
686 } 709 }
687 710
688 if (error) { 711 if (error) {
712 spin_lock(&port->dev_list_lock);
713 list_del_init(&port->port_dev->dev_list_node);
714 spin_unlock(&port->dev_list_lock);
715
689 kfree(port->port_dev); /* not kobject_register-ed yet */ 716 kfree(port->port_dev); /* not kobject_register-ed yet */
690 port->port_dev = NULL; 717 port->port_dev = NULL;
691 } 718 }