From cb2cd19bfbb7ca9e17d1b5eacf94a3a73d02697e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 1 Aug 2009 00:41:22 +0000 Subject: [PATCH] --- yaml --- r: 161037 b: refs/heads/master c: 43d8eb9cfd0aea93be32181c64e18191b69c211c h: refs/heads/master i: 161035: bd9aa1c2b75a36d43f7a10dd9585b2c25c265d5c v: v3 --- [refs] | 2 +- trunk/drivers/misc/enclosure.c | 22 ++++++++++++++-------- trunk/drivers/scsi/ses.c | 33 ++++++++++++++++++++++++++------- trunk/include/linux/enclosure.h | 2 +- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/[refs] b/[refs] index f4402732c9eb..b4bfb69bf914 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 163f52b6cf3a639df6a72c7937e0eb88b20f1ef3 +refs/heads/master: 43d8eb9cfd0aea93be32181c64e18191b69c211c diff --git a/trunk/drivers/misc/enclosure.c b/trunk/drivers/misc/enclosure.c index 789d12128c24..850706a5e553 100644 --- a/trunk/drivers/misc/enclosure.c +++ b/trunk/drivers/misc/enclosure.c @@ -332,19 +332,25 @@ EXPORT_SYMBOL_GPL(enclosure_add_device); * Returns zero on success or an error. * */ -int enclosure_remove_device(struct enclosure_device *edev, int component) +int enclosure_remove_device(struct enclosure_device *edev, struct device *dev) { struct enclosure_component *cdev; + int i; - if (!edev || component >= edev->components) + if (!edev || !dev) return -EINVAL; - cdev = &edev->component[component]; - - device_del(&cdev->cdev); - put_device(cdev->dev); - cdev->dev = NULL; - return device_add(&cdev->cdev); + for (i = 0; i < edev->components; i++) { + cdev = &edev->component[i]; + if (cdev->dev == dev) { + enclosure_remove_links(cdev); + device_del(&cdev->cdev); + put_device(dev); + cdev->dev = NULL; + return device_add(&cdev->cdev); + } + } + return -ENODEV; } EXPORT_SYMBOL_GPL(enclosure_remove_device); diff --git a/trunk/drivers/scsi/ses.c b/trunk/drivers/scsi/ses.c index e1b8c828f03a..be593c8525b5 100644 --- a/trunk/drivers/scsi/ses.c +++ b/trunk/drivers/scsi/ses.c @@ -616,18 +616,26 @@ static int ses_remove(struct device *dev) return 0; } -static void ses_intf_remove(struct device *cdev, - struct class_interface *intf) +static void ses_intf_remove_component(struct scsi_device *sdev) +{ + struct enclosure_device *edev, *prev = NULL; + + while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) { + prev = edev; + if (!enclosure_remove_device(edev, &sdev->sdev_gendev)) + break; + } + if (edev) + put_device(&edev->edev); +} + +static void ses_intf_remove_enclosure(struct scsi_device *sdev) { - struct scsi_device *sdev = to_scsi_device(cdev->parent); struct enclosure_device *edev; struct ses_device *ses_dev; - if (!scsi_device_enclosure(sdev)) - return; - /* exact match to this enclosure */ - edev = enclosure_find(cdev->parent, NULL); + edev = enclosure_find(&sdev->sdev_gendev, NULL); if (!edev) return; @@ -645,6 +653,17 @@ static void ses_intf_remove(struct device *cdev, enclosure_unregister(edev); } +static void ses_intf_remove(struct device *cdev, + struct class_interface *intf) +{ + struct scsi_device *sdev = to_scsi_device(cdev->parent); + + if (!scsi_device_enclosure(sdev)) + ses_intf_remove_component(sdev); + else + ses_intf_remove_enclosure(sdev); +} + static struct class_interface ses_interface = { .add_dev = ses_intf_add, .remove_dev = ses_intf_remove, diff --git a/trunk/include/linux/enclosure.h b/trunk/include/linux/enclosure.h index d77811e9ed84..90d1c2184112 100644 --- a/trunk/include/linux/enclosure.h +++ b/trunk/include/linux/enclosure.h @@ -122,7 +122,7 @@ enclosure_component_register(struct enclosure_device *, unsigned int, enum enclosure_component_type, const char *); int enclosure_add_device(struct enclosure_device *enclosure, int component, struct device *dev); -int enclosure_remove_device(struct enclosure_device *enclosure, int component); +int enclosure_remove_device(struct enclosure_device *, struct device *); struct enclosure_device *enclosure_find(struct device *dev, struct enclosure_device *start); int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *),