linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
To: Ian Campbell <Ian.Campbell@citrix.com>
Cc: linux-ide@vger.kernel.org
Subject: Re: [PATCH] IDE: Unregister devices if initialization fails.
Date: Tue, 27 Jan 2009 17:41:44 +0100	[thread overview]
Message-ID: <200901271741.44704.bzolnier@gmail.com> (raw)
In-Reply-To: <1232715869-31039-1-git-send-email-Ian.Campbell@citrix.com>


Hi,

On Friday 23 January 2009, Ian Campbell wrote:
> On reboot the loop in device_shutdown gets confused by these devices
> and goes into an infinite loop. I think this is because they don't
> have dev->bus or dev->driver which is because hwif_register_devices
> doesn't get called if !hwif->present.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> ---
>  drivers/ide/ide-probe.c |   10 ++++++----
>  1 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
> index 312127e..120f65b 100644
> --- a/drivers/ide/ide-probe.c
> +++ b/drivers/ide/ide-probe.c
> @@ -1520,6 +1520,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
>  		if (hwif_init(hwif) == 0) {
>  			printk(KERN_INFO "%s: failed to initialize IDE "
>  					 "interface\n", hwif->name);
> +			device_unregister(&hwif->gendev);
> +			device_destroy(ide_port_class, MKDEV(0, 0));
>  			hwif->present = 0;

I've been wondering about this a bit and I think that we should just nuke
port from struct ide_host in such situation so I added ide_disable_port()
helper for this (+ fixed ide_register_port() handling while at it).

Could you please re-base your fix on top of attached patch?

Please also remove superflous device_destroy() call -- device_unregister()
should be enough and if it is not we need to fix ide_register_port() to
use unique dev_t instead of MKDEV(0, 0).

>  			continue;
>  		}
> @@ -1550,11 +1552,11 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
>  		if (hwif == NULL)
>  			continue;
>  
> -		ide_sysfs_register_port(hwif);
> -		ide_proc_register_port(hwif);
> -
> -		if (hwif->present)
> +		if (hwif->present) {
> +			ide_sysfs_register_port(hwif);
> +			ide_proc_register_port(hwif);
>  			ide_proc_port_register_devices(hwif);

This code have to stay unchanged for proper warm-plug support
(luckily after re-basing this chunk shouldn't be needed).

Here is the ide_disable_port() patch:

From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: fix ide_register_port() failure handling

* Factor out port freeing from ide_host_free() to ide_free_port().

* Add ide_disable_port() and use it on ide_register_port() failure.

Cc: Ian Campbell <Ian.Campbell@citrix.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-probe.c |   40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1466,6 +1466,30 @@ struct ide_host *ide_host_alloc(const st
 }
 EXPORT_SYMBOL_GPL(ide_host_alloc);
 
+static void ide_port_free(ide_hwif_t *hwif)
+{
+	ide_port_free_devices(hwif);
+	ide_free_port_slot(hwif->index);
+	kfree(hwif);
+}
+
+static void ide_disable_port(ide_hwif_t *hwif)
+{
+	struct ide_host *host = hwif->host;
+	int i;
+
+	printk(KERN_INFO "%s: disabling port\n", hwif->name);
+
+	for (i = 0; i < MAX_HOST_PORTS; i++) {
+		if (host->ports[i] == hwif) {
+			host->ports[i] = NULL;
+			host->n_ports--;
+		}
+	}
+
+	ide_port_free(hwif);
+}
+
 int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
 		      hw_regs_t **hws)
 {
@@ -1506,8 +1530,12 @@ int ide_host_register(struct ide_host *h
 			hwif->present = 1;
 
 		if (hwif->chipset != ide_4drives || !hwif->mate ||
-		    !hwif->mate->present)
-			ide_register_port(hwif);
+		    !hwif->mate->present) {
+			if (ide_register_port(hwif)) {
+				ide_disable_port(hwif);
+				continue;
+			}
+		}
 
 		if (hwif->present)
 			ide_port_tune_devices(hwif);
@@ -1659,12 +1687,8 @@ void ide_host_free(struct ide_host *host
 	int i;
 
 	ide_host_for_each_port(i, hwif, host) {
-		if (hwif == NULL)
-			continue;
-
-		ide_port_free_devices(hwif);
-		ide_free_port_slot(hwif->index);
-		kfree(hwif);
+		if (hwif)
+			ide_port_free(hwif);
 	}
 
 	kfree(host);

  reply	other threads:[~2009-01-27 16:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-23 13:04 [PATCH] IDE: Unregister devices if initialization fails Ian Campbell
2009-01-27 16:41 ` Bartlomiej Zolnierkiewicz [this message]
2009-01-30 17:19   ` Ian Campbell
2009-02-01 16:21     ` Bartlomiej Zolnierkiewicz
2009-02-02 10:09       ` Ian Campbell
2009-02-02 17:49         ` Bartlomiej Zolnierkiewicz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200901271741.44704.bzolnier@gmail.com \
    --to=bzolnier@gmail.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).