* [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug @ 2007-09-15 3:01 Matthew Garrett 2007-09-15 17:06 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-15 3:01 UTC (permalink / raw) To: linux-ide, linux-acpi Modern laptops with hotswap bays still tend to utilise a PATA interface on a SATA bridge, generally with the host controller in some legacy emulation mode rather than AHCI. This means that the existing hotplug code in libata is unable to work. The ACPI specification states that these devices can send notifications when hotswapped, which avoids the need to obtain notification from the controller. This patch uses the existing libata-acpi code and simply registers a notification in order to trigger a rescan whenever the firmware signals an event. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- I've tested this on the Dell I have here - the removal is a bit chatty (and it spends several seconds attempting to revalidate), but it destroys the device happily enough and handles reinsertion without complaining. diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c059f78..bc6bea6 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -66,6 +66,17 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + struct ata_eh_info *ehi = &ap->eh_info; + + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -97,6 +108,12 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->device->acpi_handle) + acpi_install_notify_handler (ap->device->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_notify, + ap); } } -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-15 3:01 [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug Matthew Garrett @ 2007-09-15 17:06 ` Matthew Garrett 2007-09-16 12:22 ` Tejun Heo 2007-09-20 22:04 ` Jeff Garzik 0 siblings, 2 replies; 26+ messages in thread From: Matthew Garrett @ 2007-09-15 17:06 UTC (permalink / raw) To: linux-ide, linux-acpi Modern laptops with hotswap bays still tend to utilise a PATA interface on a SATA bridge, generally with the host controller in some legacy emulation mode rather than AHCI. This means that the existing hotplug code in libata is unable to work. The ACPI specification states that these devices can send notifications when hotswapped, which avoids the need to obtain notification from the controller. This patch uses the existing libata-acpi code and simply registers a notification in order to trigger a rescan whenever the firmware signals an event. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- Testing on an HP with the hotplug device as the slave on a PATA channel flagged a bug - the notification needs to be tied to the channel handle as well as the device ones. With this version, I can happily hotswap the HP device. It ends up sitting for a few seconds while failing to revalidate, but then recovers with everything working fine. diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c059f78..99f3179 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -66,6 +66,17 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + struct ata_eh_info *ehi = &ap->eh_info; + + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -81,7 +92,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) */ void ata_acpi_associate(struct ata_host *host) { - int i; + int i, j; if (!is_pci_dev(host->dev) || libata_noacpi) return; @@ -97,6 +108,22 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_notify, + ap); + + for (j = 0; j < ATA_MAX_DEVICES; j++) { + struct ata_device *dev = &ap->device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (ap->device->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_notify, + ap); + } } } -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-15 17:06 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 Matthew Garrett @ 2007-09-16 12:22 ` Tejun Heo 2007-09-20 22:04 ` Jeff Garzik 1 sibling, 0 replies; 26+ messages in thread From: Tejun Heo @ 2007-09-16 12:22 UTC (permalink / raw) To: Matthew Garrett; +Cc: linux-ide, linux-acpi Matthew Garrett wrote: > +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) > +{ > + struct ata_port *ap = data; > + struct ata_eh_info *ehi = &ap->eh_info; > + > + ata_ehi_clear_desc(ehi); > + ata_ehi_push_desc(ehi, "ACPI event"); > + ata_ehi_hotplugged(ehi); > + ata_port_freeze(ap); You probably want to wrap the above inside ap->lock. -- tejun ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-15 17:06 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 Matthew Garrett 2007-09-16 12:22 ` Tejun Heo @ 2007-09-20 22:04 ` Jeff Garzik 2007-09-20 22:21 ` Matthew Garrett 1 sibling, 1 reply; 26+ messages in thread From: Jeff Garzik @ 2007-09-20 22:04 UTC (permalink / raw) To: Matthew Garrett; +Cc: linux-ide, linux-acpi, Tejun Heo, Andrew Morton Matthew Garrett wrote: > Modern laptops with hotswap bays still tend to utilise a PATA interface > on a SATA bridge, generally with the host controller in some legacy > emulation mode rather than AHCI. This means that the existing hotplug > code in libata is unable to work. The ACPI specification states that > these devices can send notifications when hotswapped, which avoids the > need to obtain notification from the controller. This patch uses the > existing libata-acpi code and simply registers a notification in order > to trigger a rescan whenever the firmware signals an event. > > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > Testing on an HP with the hotplug device as the slave on a PATA channel > flagged a bug - the notification needs to be tied to the channel handle > as well as the device ones. With this version, I can happily hotswap the > HP device. It ends up sitting for a few seconds while failing to > revalidate, but then recovers with everything working fine. the code looks correct. I have one main reservation. how can we be sure that this is active only where other hand-programmed hotplug code is absent? ACPI doesn't inherently know which of our controllers are already set up to do hotplug, so it seems like there is a possibility of conflict if both the firmware and the controller are chirping. If we can quell my fears in that area, I'm ok with the change. Jeff ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-20 22:04 ` Jeff Garzik @ 2007-09-20 22:21 ` Matthew Garrett 2007-09-21 2:35 ` Tejun Heo 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-20 22:21 UTC (permalink / raw) To: Jeff Garzik; +Cc: linux-ide, linux-acpi, Tejun Heo, Andrew Morton On Thu, Sep 20, 2007 at 06:04:22PM -0400, Jeff Garzik wrote: > the code looks correct. I have one main reservation. > > how can we be sure that this is active only where other hand-programmed > hotplug code is absent? Yes, that's difficult. As Tejun pointed out, there's missing locking here at the moment - if I add that, am I right in thinking that the worst case scenario is that the hotplugging path will be called twice? One option would be to limit this to PATA-style controllers - I'm not aware of any mobile hardware shipping with natively hotplug-capable controllers, so that would probably do for the moment. If (when) they move to AHCI, with luck the native hotplugging will work and we won't have to worry about this so much. The alternative would be to add a flag to the ap structure indicating whether the hotplugging is handled by the firmware or not. If we find a reference to a controller or port in the firmware tables, it probably indicates that the hardware has opinions about how this should be handled. We might be safer leaving it to the firmware in those cases, and using that flag to skip the controller-specific hotplug code. -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-20 22:21 ` Matthew Garrett @ 2007-09-21 2:35 ` Tejun Heo 2007-09-21 2:42 ` Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Tejun Heo @ 2007-09-21 2:35 UTC (permalink / raw) To: Matthew Garrett; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton Matthew Garrett wrote: > On Thu, Sep 20, 2007 at 06:04:22PM -0400, Jeff Garzik wrote: > >> the code looks correct. I have one main reservation. >> >> how can we be sure that this is active only where other hand-programmed >> hotplug code is absent? > > Yes, that's difficult. As Tejun pointed out, there's missing locking > here at the moment - if I add that, am I right in thinking that the > worst case scenario is that the hotplugging path will be called twice? Yeah, should be and libata EH won't have too much problem handling duplicate events. > One option would be to limit this to PATA-style controllers - I'm not > aware of any mobile hardware shipping with natively hotplug-capable > controllers, so that would probably do for the moment. If (when) they > move to AHCI, with luck the native hotplugging will work and we won't > have to worry about this so much. > > The alternative would be to add a flag to the ap structure indicating > whether the hotplugging is handled by the firmware or not. If we find a > reference to a controller or port in the firmware tables, it probably > indicates that the hardware has opinions about how this should be > handled. We might be safer leaving it to the firmware in those cases, > and using that flag to skip the controller-specific hotplug code. I was thinking the other way around. I'd rather depend on hardware provided events than firmware provided ones. How about flagging drivers which can do native hoplugging and using ACPI hotplugging only if the driver can't do it natively? Thanks. -- tejun ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 2:35 ` Tejun Heo @ 2007-09-21 2:42 ` Matthew Garrett 2007-09-21 2:53 ` Tejun Heo 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-21 2:42 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Fri, Sep 21, 2007 at 11:35:05AM +0900, Tejun Heo wrote: > Matthew Garrett wrote: > > The alternative would be to add a flag to the ap structure indicating > > whether the hotplugging is handled by the firmware or not. If we find a > > reference to a controller or port in the firmware tables, it probably > > indicates that the hardware has opinions about how this should be > > handled. We might be safer leaving it to the firmware in those cases, > > and using that flag to skip the controller-specific hotplug code. > > I was thinking the other way around. I'd rather depend on hardware > provided events than firmware provided ones. How about flagging drivers > which can do native hoplugging and using ACPI hotplugging only if the > driver can't do it natively? If the manufacturers have added firmware-level hotswap interrupts, then there's all sorts of insane ways they might have wired the bay up. I don't really trust them to have managed to do so without breaking native hotplug :) It doesn't really matter at the moment, though, since I haven't actually seen any examples of hardware using anything that can manage native hotplug. If anyone out there does have one, it would be nice to get some feedback about what it does. -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 2:42 ` Matthew Garrett @ 2007-09-21 2:53 ` Tejun Heo 2007-09-21 2:57 ` Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Tejun Heo @ 2007-09-21 2:53 UTC (permalink / raw) To: Matthew Garrett; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton Matthew Garrett wrote: > On Fri, Sep 21, 2007 at 11:35:05AM +0900, Tejun Heo wrote: >> Matthew Garrett wrote: >>> The alternative would be to add a flag to the ap structure indicating >>> whether the hotplugging is handled by the firmware or not. If we find a >>> reference to a controller or port in the firmware tables, it probably >>> indicates that the hardware has opinions about how this should be >>> handled. We might be safer leaving it to the firmware in those cases, >>> and using that flag to skip the controller-specific hotplug code. >> I was thinking the other way around. I'd rather depend on hardware >> provided events than firmware provided ones. How about flagging drivers >> which can do native hoplugging and using ACPI hotplugging only if the >> driver can't do it natively? > > If the manufacturers have added firmware-level hotswap interrupts, then > there's all sorts of insane ways they might have wired the bay up. I > don't really trust them to have managed to do so without breaking native > hotplug :) It doesn't really matter at the moment, though, since I > haven't actually seen any examples of hardware using anything that can > manage native hotplug. If anyone out there does have one, it would be > nice to get some feedback about what it does. Maybe just letting both events in is the best idea. It's not like two duplicate events are gonna break anything and I don't think many vendors are gonna implement separate mechanism when the default SATA phy based one works. -- tejun ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 2:53 ` Tejun Heo @ 2007-09-21 2:57 ` Matthew Garrett 2007-09-21 3:08 ` Tejun Heo 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-21 2:57 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Fri, Sep 21, 2007 at 11:53:33AM +0900, Tejun Heo wrote: > Maybe just letting both events in is the best idea. It's not like two > duplicate events are gonna break anything and I don't think many vendors > are gonna implement separate mechanism when the default SATA phy based > one works. Works for me. Unrelatedly, is it expected that the EH take some time attempting to revalidate the port before finally deciding that the drive has gone? I seem to lose 15 seconds or so to that, which is more irritating on PATA systems where it tends to block the channel. (Quite why HP put their hotswap optical drives on the same PATA channel as the internal drive is somewhat beyond me, but...) -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 2:57 ` Matthew Garrett @ 2007-09-21 3:08 ` Tejun Heo 2007-09-21 3:12 ` Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Tejun Heo @ 2007-09-21 3:08 UTC (permalink / raw) To: Matthew Garrett; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton Matthew Garrett wrote: > On Fri, Sep 21, 2007 at 11:53:33AM +0900, Tejun Heo wrote: > >> Maybe just letting both events in is the best idea. It's not like two >> duplicate events are gonna break anything and I don't think many vendors >> are gonna implement separate mechanism when the default SATA phy based >> one works. > > Works for me. Unrelatedly, is it expected that the EH take some time > attempting to revalidate the port before finally deciding that the drive > has gone? I seem to lose 15 seconds or so to that, which is more > irritating on PATA systems where it tends to block the channel. > > (Quite why HP put their hotswap optical drives on the same PATA channel > as the internal drive is somewhat beyond me, but...) Yeah, that's the intended behavior. SATA PHY link can break from time to time (have ever seen a SATA storage box going through ECC testing? PHY goes offline as soon as you begin to hit it with some EM pulses) and you don't really wanna lose your root partition over power fluctuation. I'm thinking about improving EH such that it doesn't hold up the bus for the whole period. It will be needed for PMP too. However, for now, that's the expected behavior. Thanks. -- tejun ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 3:08 ` Tejun Heo @ 2007-09-21 3:12 ` Matthew Garrett 2007-09-21 3:19 ` Tejun Heo 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-21 3:12 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Fri, Sep 21, 2007 at 12:08:07PM +0900, Tejun Heo wrote: > Yeah, that's the intended behavior. SATA PHY link can break from time > to time (have ever seen a SATA storage box going through ECC testing? > PHY goes offline as soon as you begin to hit it with some EM pulses) and > you don't really wanna lose your root partition over power fluctuation. In this case we explicitly know that it's in response to a hotplug event (well, either that or the firmware is on impressive crack). Would it be possible to communicate that in order to avoid the revalidation? -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 2007-09-21 3:12 ` Matthew Garrett @ 2007-09-21 3:19 ` Tejun Heo 2007-09-24 23:14 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Tejun Heo @ 2007-09-21 3:19 UTC (permalink / raw) To: Matthew Garrett; +Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton Matthew Garrett wrote: > On Fri, Sep 21, 2007 at 12:08:07PM +0900, Tejun Heo wrote: > >> Yeah, that's the intended behavior. SATA PHY link can break from time >> to time (have ever seen a SATA storage box going through ECC testing? >> PHY goes offline as soon as you begin to hit it with some EM pulses) and >> you don't really wanna lose your root partition over power fluctuation. > > In this case we explicitly know that it's in response to a hotplug event > (well, either that or the firmware is on impressive crack). Would it be > possible to communicate that in order to avoid the revalidation? No, I don't thinks so && I don't really think trusting firmware that much is a good idea. Also, it's much better to fix the problem in general than just fixing it for the firmware case which will be much less than the rest. -- tejun ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-09-21 3:19 ` Tejun Heo @ 2007-09-24 23:14 ` Matthew Garrett 2007-09-27 17:26 ` Kristen Carlson Accardi 2007-10-02 15:04 ` Jeff Garzik 0 siblings, 2 replies; 26+ messages in thread From: Matthew Garrett @ 2007-09-24 23:14 UTC (permalink / raw) To: Tejun Heo Cc: Jeff Garzik, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Modern laptops with hotswap bays still tend to utilise a PATA interface on a SATA bridge, generally with the host controller in some legacy emulation mode rather than AHCI. This means that the existing hotplug code in libata is unable to work. The ACPI specification states that these devices can send notifications when hotswapped, which avoids the need to obtain notification from the controller. This patch uses the existing libata-acpi code and simply registers a notification in order to trigger a rescan whenever the firmware signals an event. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- This makes two changes to the previous patch: 1) It implements the locking suggested by Tejun 2) It sends a uevent on the device kobject. I've implemented this because grabbing the notification handler means that the bay driver can no longer do it, so it's necessary to generate compatible events. If the event type is 3, it indicates that the user has merely requested an eject - the drive hasn't gone at this point. Sending the notification allows userspace to attempt to unmount the filesystems before sending a command to initiate the eject. I'm not especially happy about the chain used to get the scsi device kobject. Is there a cleaner way to do that? Other than that, I've now tested this on multiple systems (a 965-based Thinkpad, a 915-era Dell and even an HP with no SATA whatsoever) without any obvious breakage. diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c059f78..68bb7fa 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -14,6 +14,7 @@ #include <linux/acpi.h> #include <linux/libata.h> #include <linux/pci.h> +#include <scsi/scsi_device.h> #include "libata.h" #include <acpi/acpi_bus.h> @@ -66,6 +67,41 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + struct ata_eh_info *ehi = &ap->eh_info; + char event_string[12]; + char *envp[] = { event_string, NULL }; + struct kobject *kobj = NULL; + int i; + + if (ap->acpi_handle && handle == ap->acpi_handle) + kobj = &ap->dev->kobj; + else { + for (i = 0; i < ata_port_max_devices(ap); i++) { + struct ata_device *dev = &ap->device[i]; + if (dev->acpi_handle && handle == dev->acpi_handle) + kobj = &dev->sdev->sdev_gendev.kobj; + } + } + + if (event == 0 || event == 1) { + unsigned long flags; + spin_lock_irqsave(ap->lock, flags); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + spin_unlock_irqrestore(ap->lock, flags); + } + + if (kobj) { + sprintf(event_string, "BAY_EVENT=%d\n", event); + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); + } +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -81,7 +117,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) */ void ata_acpi_associate(struct ata_host *host) { - int i; + int i, j; if (!is_pci_dev(host->dev) || libata_noacpi) return; @@ -97,6 +133,22 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_notify, + ap); + + for (j = 0; j < ata_port_max_devices(ap); j++) { + struct ata_device *dev = &ap->device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_notify, + ap); + } } } -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-09-24 23:14 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 Matthew Garrett @ 2007-09-27 17:26 ` Kristen Carlson Accardi 2007-09-27 17:55 ` Matthew Garrett 2007-10-02 15:04 ` Jeff Garzik 1 sibling, 1 reply; 26+ messages in thread From: Kristen Carlson Accardi @ 2007-09-27 17:26 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Tue, 25 Sep 2007 00:14:36 +0100 Matthew Garrett <mjg59@srcf.ucam.org> wrote: > Modern laptops with hotswap bays still tend to utilise a PATA interface > on a SATA bridge, generally with the host controller in some legacy > emulation mode rather than AHCI. This means that the existing hotplug > code in libata is unable to work. The ACPI specification states that > these devices can send notifications when hotswapped, which avoids the > need to obtain notification from the controller. This patch uses the > existing libata-acpi code and simply registers a notification in order > to trigger a rescan whenever the firmware signals an event. > Hi Matthew, While I love the idea of integrating the Bay support with libata, and I think this is a good patch, I have 2 concerns which don't seem to be addressed here. 1. How does it handle things when you have a bay that is located behind a dock and the dock ejects? In the acpi bay driver, I use the mechanism that the dock driver exports to get undock notifications so that the bay can eject as well. 2. What if someone wants to use their bay to charge their battery? While I never bothered to implement this in acpi/bay.c, nothing ever prevented anyone from adding that support to the driver, where now it is prevented since this driver and another cannot coexist. The basic problem is that there's no way to have multiple drivers register a notifier for the same ACPI event on the same object. So, my solution to this in my acpi drivers was to export ways to share from the driver. Thanks, Kristen > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > This makes two changes to the previous patch: > > 1) It implements the locking suggested by Tejun > 2) It sends a uevent on the device kobject. I've implemented this > because grabbing the notification handler means that the bay driver can > no longer do it, so it's necessary to generate compatible events. If the > event type is 3, it indicates that the user has merely requested an > eject - the drive hasn't gone at this point. Sending the notification > allows userspace to attempt to unmount the filesystems before sending a > command to initiate the eject. > > I'm not especially happy about the chain used to get the scsi device > kobject. Is there a cleaner way to do that? Other than that, I've now > tested this on multiple systems (a 965-based Thinkpad, a 915-era Dell > and even an HP with no SATA whatsoever) without any obvious breakage. > > diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c > index c059f78..68bb7fa 100644 > --- a/drivers/ata/libata-acpi.c > +++ b/drivers/ata/libata-acpi.c > @@ -14,6 +14,7 @@ > #include <linux/acpi.h> > #include <linux/libata.h> > #include <linux/pci.h> > +#include <scsi/scsi_device.h> > #include "libata.h" > > #include <acpi/acpi_bus.h> > @@ -66,6 +67,41 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) > } > } > > +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) > +{ > + struct ata_port *ap = data; > + struct ata_eh_info *ehi = &ap->eh_info; > + char event_string[12]; > + char *envp[] = { event_string, NULL }; > + struct kobject *kobj = NULL; > + int i; > + > + if (ap->acpi_handle && handle == ap->acpi_handle) > + kobj = &ap->dev->kobj; > + else { > + for (i = 0; i < ata_port_max_devices(ap); i++) { > + struct ata_device *dev = &ap->device[i]; > + if (dev->acpi_handle && handle == dev->acpi_handle) > + kobj = &dev->sdev->sdev_gendev.kobj; > + } > + } > + > + if (event == 0 || event == 1) { > + unsigned long flags; > + spin_lock_irqsave(ap->lock, flags); > + ata_ehi_clear_desc(ehi); > + ata_ehi_push_desc(ehi, "ACPI event"); > + ata_ehi_hotplugged(ehi); > + ata_port_freeze(ap); > + spin_unlock_irqrestore(ap->lock, flags); > + } > + > + if (kobj) { > + sprintf(event_string, "BAY_EVENT=%d\n", event); > + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); > + } > +} > + > /** > * ata_acpi_associate - associate ATA host with ACPI objects > * @host: target ATA host > @@ -81,7 +117,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) > */ > void ata_acpi_associate(struct ata_host *host) > { > - int i; > + int i, j; > > if (!is_pci_dev(host->dev) || libata_noacpi) > return; > @@ -97,6 +133,22 @@ void ata_acpi_associate(struct ata_host *host) > ata_acpi_associate_sata_port(ap); > else > ata_acpi_associate_ide_port(ap); > + > + if (ap->acpi_handle) > + acpi_install_notify_handler (ap->acpi_handle, > + ACPI_SYSTEM_NOTIFY, > + ata_acpi_notify, > + ap); > + > + for (j = 0; j < ata_port_max_devices(ap); j++) { > + struct ata_device *dev = &ap->device[j]; > + > + if (dev->acpi_handle) > + acpi_install_notify_handler (dev->acpi_handle, > + ACPI_SYSTEM_NOTIFY, > + ata_acpi_notify, > + ap); > + } > } > } > > -- > Matthew Garrett | mjg59@srcf.ucam.org > ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-09-27 17:26 ` Kristen Carlson Accardi @ 2007-09-27 17:55 ` Matthew Garrett 2007-09-27 20:39 ` Henrique de Moraes Holschuh 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-09-27 17:55 UTC (permalink / raw) To: Kristen Carlson Accardi Cc: Tejun Heo, Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Thu, Sep 27, 2007 at 10:26:59AM -0700, Kristen Carlson Accardi wrote: > 1. How does it handle things when you have a bay that is located behind > a dock and the dock ejects? In the acpi bay driver, I use the mechanism > that the dock driver exports to get undock notifications so that the bay > can eject as well. Hm. I'd been working on the assumption that ejecting the doc would trigger the bay notifications as well, but I've got no hardware here with those capabilities so it's kind of hard to check... > 2. What if someone wants to use their bay to charge their battery? While > I never bothered to implement this in acpi/bay.c, nothing ever prevented > anyone from adding that support to the driver, where now it is prevented > since this driver and another cannot coexist. The spec seems to imply that even if the drive hotswap bay and the battery bay are physically the same, they're logically distinct. 10.2.1 specifies that the battery bay should always be considered present, and that any insertion notification will be generated from the battery bay rather than the drive bay (so Notify (BAT1, 0x81) rather than Notify (_SB.MISC.OTHR.BONG.PRIM.SLAV, 0x81)). My code will only grab the latter notification, not the former. I /suspect/ that _STA on the bay device won't return true if there's a battery in there, and so we aren't expected to call the _EJ0 method if the user wants to remove a battery. But I'm also lacking hardware to test this one, so it's possible that I'm utterly wrong :) -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-09-27 17:55 ` Matthew Garrett @ 2007-09-27 20:39 ` Henrique de Moraes Holschuh 0 siblings, 0 replies; 26+ messages in thread From: Henrique de Moraes Holschuh @ 2007-09-27 20:39 UTC (permalink / raw) To: Matthew Garrett Cc: Kristen Carlson Accardi, Tejun Heo, Jeff Garzik, linux-ide, linux-acpi, Andrew Morton On Thu, 27 Sep 2007, Matthew Garrett wrote: > The spec seems to imply that even if the drive hotswap bay and the > battery bay are physically the same, they're logically distinct. 10.2.1 That holds true for thinkpads up to the T43, at least. I don't know about the newer ones. You get bay ejects/inserts notifications from the device node corresponding to what was inserted/removed from the multi-purpose bay. > I /suspect/ that _STA on the bay device won't return true if there's a > battery in there, and so we aren't expected to call the _EJ0 method if Correct, on thinkpads up to the T43 at least. -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-09-24 23:14 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 Matthew Garrett 2007-09-27 17:26 ` Kristen Carlson Accardi @ 2007-10-02 15:04 ` Jeff Garzik 2007-10-02 18:46 ` Matthew Garrett 2007-10-02 18:49 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 Matthew Garrett 1 sibling, 2 replies; 26+ messages in thread From: Jeff Garzik @ 2007-10-02 15:04 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Matthew Garrett wrote: > Modern laptops with hotswap bays still tend to utilise a PATA interface > on a SATA bridge, generally with the host controller in some legacy > emulation mode rather than AHCI. This means that the existing hotplug > code in libata is unable to work. The ACPI specification states that > these devices can send notifications when hotswapped, which avoids the > need to obtain notification from the controller. This patch uses the > existing libata-acpi code and simply registers a notification in order > to trigger a rescan whenever the firmware signals an event. > > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > This makes two changes to the previous patch: > > 1) It implements the locking suggested by Tejun > 2) It sends a uevent on the device kobject. I've implemented this > because grabbing the notification handler means that the bay driver can > no longer do it, so it's necessary to generate compatible events. If the > event type is 3, it indicates that the user has merely requested an > eject - the drive hasn't gone at this point. Sending the notification > allows userspace to attempt to unmount the filesystems before sending a > command to initiate the eject. > > I'm not especially happy about the chain used to get the scsi device > kobject. Is there a cleaner way to do that? Other than that, I've now > tested this on multiple systems (a 965-based Thinkpad, a 915-era Dell > and even an HP with no SATA whatsoever) without any obvious breakage. > > diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c > index c059f78..68bb7fa 100644 > --- a/drivers/ata/libata-acpi.c > +++ b/drivers/ata/libata-acpi.c > @@ -14,6 +14,7 @@ > #include <linux/acpi.h> > #include <linux/libata.h> > #include <linux/pci.h> > +#include <scsi/scsi_device.h> > #include "libata.h" > > #include <acpi/acpi_bus.h> > @@ -66,6 +67,41 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) > } > } > > +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data) > +{ > + struct ata_port *ap = data; > + struct ata_eh_info *ehi = &ap->eh_info; > + char event_string[12]; > + char *envp[] = { event_string, NULL }; > + struct kobject *kobj = NULL; > + int i; > + > + if (ap->acpi_handle && handle == ap->acpi_handle) > + kobj = &ap->dev->kobj; > + else { > + for (i = 0; i < ata_port_max_devices(ap); i++) { > + struct ata_device *dev = &ap->device[i]; > + if (dev->acpi_handle && handle == dev->acpi_handle) > + kobj = &dev->sdev->sdev_gendev.kobj; > + } > + } > + > + if (event == 0 || event == 1) { > + unsigned long flags; > + spin_lock_irqsave(ap->lock, flags); > + ata_ehi_clear_desc(ehi); > + ata_ehi_push_desc(ehi, "ACPI event"); > + ata_ehi_hotplugged(ehi); > + ata_port_freeze(ap); > + spin_unlock_irqrestore(ap->lock, flags); > + } > + > + if (kobj) { > + sprintf(event_string, "BAY_EVENT=%d\n", event); > + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); > + } > +} > + > /** > * ata_acpi_associate - associate ATA host with ACPI objects > * @host: target ATA host > @@ -81,7 +117,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) > */ > void ata_acpi_associate(struct ata_host *host) > { > - int i; > + int i, j; > > if (!is_pci_dev(host->dev) || libata_noacpi) > return; > @@ -97,6 +133,22 @@ void ata_acpi_associate(struct ata_host *host) > ata_acpi_associate_sata_port(ap); > else > ata_acpi_associate_ide_port(ap); > + > + if (ap->acpi_handle) > + acpi_install_notify_handler (ap->acpi_handle, > + ACPI_SYSTEM_NOTIFY, > + ata_acpi_notify, > + ap); > + > + for (j = 0; j < ata_port_max_devices(ap); j++) { > + struct ata_device *dev = &ap->device[j]; > + > + if (dev->acpi_handle) > + acpi_install_notify_handler (dev->acpi_handle, > + ACPI_SYSTEM_NOTIFY, > + ata_acpi_notify, > + ap); Mostly OK. Notes: 1) Check dev->sdev for NULL 2) remove the unnecessary ata_device loop. If you know the ata_device pointer, you should not throw it away and then do a search to find it again. You need two functions, ata_acpi_ap_notify() and ata_acpi_dev_notify(). Pass 'ap' to the former, and 'dev' to the latter. Both functions should marshal their arguments, then call a common function (presumably what 95% of current ata_acpi_notify does). 3) Won't this result in a single hotplug event calling ata_ehi_hotplugged() multiple times -- once for the port, and once for each device attached to the port? ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 2007-10-02 15:04 ` Jeff Garzik @ 2007-10-02 18:46 ` Matthew Garrett 2007-10-02 18:49 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 Matthew Garrett 1 sibling, 0 replies; 26+ messages in thread From: Matthew Garrett @ 2007-10-02 18:46 UTC (permalink / raw) To: Jeff Garzik Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi On Tue, Oct 02, 2007 at 11:04:41AM -0400, Jeff Garzik wrote: > 1) Check dev->sdev for NULL Ok. > 2) remove the unnecessary ata_device loop. If you know the ata_device > pointer, you should not throw it away and then do a search to find it again. > > You need two functions, ata_acpi_ap_notify() and ata_acpi_dev_notify(). > Pass 'ap' to the former, and 'dev' to the latter. > > Both functions should marshal their arguments, then call a common > function (presumably what 95% of current ata_acpi_notify does). Sure. > 3) Won't this result in a single hotplug event calling > ata_ehi_hotplugged() multiple times -- once for the port, and once for > each device attached to the port? No - the platform will either send an event for the port or for an individual device. It'll never simultaneously send one for both the port and a device. Semantically the one from the port is a "check all children" request and the one from the device a "check this individual device", but I believe these are both equivalent in the current hotswap implementation. -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 15:04 ` Jeff Garzik 2007-10-02 18:46 ` Matthew Garrett @ 2007-10-02 18:49 ` Matthew Garrett 2007-10-02 18:55 ` Jeff Garzik 1 sibling, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-10-02 18:49 UTC (permalink / raw) To: Jeff Garzik Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Modern laptops with hotswap bays still tend to utilise a PATA interface on a SATA bridge, generally with the host controller in some legacy emulation mode rather than AHCI. This means that the existing hotplug code in libata is unable to work. The ACPI specification states that these devices can send notifications when hotswapped, which avoids the need to obtain notification from the controller. This patch uses the existing libata-acpi code and simply registers a notification in order to trigger a rescan whenever the firmware signals an event. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- This incorporates Jeff's feedback. sdev is checked for NULL, and different notifications are registered for ap-level and dev-level handlers. The core code is split out into a helper function called by both of these. The other change is the removal of the extraneous newline from the end of the notification event, to match the upstream change in the bay driver. diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c059f78..4d8f1ba 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -14,6 +14,7 @@ #include <linux/acpi.h> #include <linux/libata.h> #include <linux/pci.h> +#include <scsi/scsi_device.h> #include "libata.h" #include <acpi/acpi_bus.h> @@ -66,6 +67,47 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, + u32 event) +{ + char event_string[12]; + char *envp[] = { event_string, NULL }; + struct ata_eh_info *ehi = &ap->eh_info; + + if (event == 0 || event == 1) { + unsigned long flags; + spin_lock_irqsave(ap->lock, flags); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + spin_unlock_irqrestore(ap->lock, flags); + } + + if (kobj) { + sprintf(event_string, "BAY_EVENT=%d", event); + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); + } +} + +static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_device *dev = data; + struct kobject *kobj = NULL; + + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + + ata_acpi_handle_hotplug (dev->ap, kobj, event); +} + +static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + + ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event); +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -81,7 +123,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) */ void ata_acpi_associate(struct ata_host *host) { - int i; + int i, j; if (!is_pci_dev(host->dev) || libata_noacpi) return; @@ -97,6 +139,22 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_ap_notify, + ap); + + for (j = 0; j < ata_port_max_devices(ap); j++) { + struct ata_device *dev = &ap->device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_dev_notify, + dev); + } } } -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 18:49 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 Matthew Garrett @ 2007-10-02 18:55 ` Jeff Garzik 2007-10-02 20:38 ` Jeff Garzik 0 siblings, 1 reply; 26+ messages in thread From: Jeff Garzik @ 2007-10-02 18:55 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Matthew Garrett wrote: > Modern laptops with hotswap bays still tend to utilise a PATA interface > on a SATA bridge, generally with the host controller in some legacy > emulation mode rather than AHCI. This means that the existing hotplug > code in libata is unable to work. The ACPI specification states that > these devices can send notifications when hotswapped, which avoids the > need to obtain notification from the controller. This patch uses the > existing libata-acpi code and simply registers a notification in order > to trigger a rescan whenever the firmware signals an event. > > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > This incorporates Jeff's feedback. sdev is checked for NULL, and > different notifications are registered for ap-level and dev-level > handlers. The core code is split out into a helper function called by > both of these. The other change is the removal of the extraneous newline > from the end of the notification event, to match the upstream change in > the bay driver. applied ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 18:55 ` Jeff Garzik @ 2007-10-02 20:38 ` Jeff Garzik 2007-10-02 20:42 ` Matthew Garrett 2007-10-02 21:20 ` Matthew Garrett 0 siblings, 2 replies; 26+ messages in thread From: Jeff Garzik @ 2007-10-02 20:38 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Jeff Garzik wrote: > Matthew Garrett wrote: >> Modern laptops with hotswap bays still tend to utilise a PATA >> interface on a SATA bridge, generally with the host controller in some >> legacy emulation mode rather than AHCI. This means that the existing >> hotplug code in libata is unable to work. The ACPI specification >> states that these devices can send notifications when hotswapped, >> which avoids the need to obtain notification from the controller. This >> patch uses the existing libata-acpi code and simply registers a >> notification in order to trigger a rescan whenever the firmware >> signals an event. >> >> Signed-off-by: Matthew Garrett >> <mjg59@srcf.ucam.org> >> --- >> >> This incorporates Jeff's feedback. sdev is checked for NULL, and >> different notifications are registered for ap-level and dev-level >> handlers. The core code is split out into a helper function called by >> both of these. The other change is the removal of the extraneous >> newline from the end of the notification event, to match the upstream >> change in the bay driver. > > applied Come on, dude! This doesn't even build: UPD include/linux/compile.h drivers/ata/libata-acpi.c: In function ‘ata_acpi_handle_hotplug’: drivers/ata/libata-acpi.c:104: error: ‘struct ata_port’ has no member named ‘eh_info’ drivers/ata/libata-acpi.c: In function ‘ata_acpi_dev_notify’: drivers/ata/libata-acpi.c:130: error: ‘struct ata_device’ has no member named ‘ap’ drivers/ata/libata-acpi.c: In function ‘ata_acpi_associate’: drivers/ata/libata-acpi.c:178: error: implicit declaration of function ‘ata_port_max_devices’ drivers/ata/libata-acpi.c:179: error: ‘struct ata_port’ has no member named ‘device’ make[2]: *** [drivers/ata/libata-acpi.o] Error 1 - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 20:38 ` Jeff Garzik @ 2007-10-02 20:42 ` Matthew Garrett 2007-10-02 21:20 ` Matthew Garrett 1 sibling, 0 replies; 26+ messages in thread From: Matthew Garrett @ 2007-10-02 20:42 UTC (permalink / raw) To: Jeff Garzik Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi On Tue, Oct 02, 2007 at 04:38:19PM -0400, Jeff Garzik wrote: > Come on, dude! This doesn't even build: Crap, sorry, I've pulled that from the wrong tree. I'll grab you a working one now. -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 20:38 ` Jeff Garzik 2007-10-02 20:42 ` Matthew Garrett @ 2007-10-02 21:20 ` Matthew Garrett 2007-10-02 21:23 ` Jeff Garzik 1 sibling, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-10-02 21:20 UTC (permalink / raw) To: Jeff Garzik Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Fix libata-acpi.c build failure. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- Sorry, I'd diffed the original against libata-dev master rather than ALL. This tidies up the changes. diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 6896831..5ebbf16 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -101,7 +101,7 @@ static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, { char event_string[12]; char *envp[] = { event_string, NULL }; - struct ata_eh_info *ehi = &ap->eh_info; + struct ata_eh_info *ehi = &ap->link.eh_info; if (event == 0 || event == 1) { unsigned long flags; @@ -127,7 +127,7 @@ static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) if (dev->sdev) kobj = &dev->sdev->sdev_gendev.kobj; - ata_acpi_handle_hotplug (dev->ap, kobj, event); + ata_acpi_handle_hotplug (dev->link->ap, kobj, event); } static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) @@ -175,8 +175,8 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_ap_notify, ap); - for (j = 0; j < ata_port_max_devices(ap); j++) { - struct ata_device *dev = &ap->device[j]; + for (j = 0; j < ata_link_max_devices(&ap->link); j++) { + struct ata_device *dev = &ap->link.device[j]; if (dev->acpi_handle) acpi_install_notify_handler (dev->acpi_handle, -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 2007-10-02 21:20 ` Matthew Garrett @ 2007-10-02 21:23 ` Jeff Garzik 2007-10-03 0:24 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 Matthew Garrett 0 siblings, 1 reply; 26+ messages in thread From: Jeff Garzik @ 2007-10-02 21:23 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Matthew Garrett wrote: > Fix libata-acpi.c build failure. > > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > Sorry, I'd diffed the original against libata-dev master rather than > ALL. This tidies up the changes. I had to yank the patch. For bisect-ability, we really really want to avoid pushing patches upstream that don't build; so, please resend a fixed version. BTW, you generally want to diff against libata-dev.git#upstream. 'upstream' branch is always what is queued for the next kernel release. 'ALL' is a meta-branch that includes #upstream, but also other stuff we want in -mm for testing. Jeff ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 2007-10-02 21:23 ` Jeff Garzik @ 2007-10-03 0:24 ` Matthew Garrett 2007-10-03 20:27 ` Jeff Garzik 0 siblings, 1 reply; 26+ messages in thread From: Matthew Garrett @ 2007-10-03 0:24 UTC (permalink / raw) To: Jeff Garzik Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Modern laptops with hotswap bays still tend to utilise a PATA interface on a SATA bridge, generally with the host controller in some legacy emulation mode rather than AHCI. This means that the existing hotplug code in libata is unable to work. The ACPI specification states that these devices can send notifications when hotswapped, which avoids the need to obtain notification from the controller. This patch uses the existing libata-acpi code and simply registers a notification in order to trigger a rescan whenever the firmware signals an event. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> --- Diffed against #upstream. Fairly sure I've got it right this time... diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index a276c06..5ebbf16 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -14,6 +14,7 @@ #include <linux/acpi.h> #include <linux/libata.h> #include <linux/pci.h> +#include <scsi/scsi_device.h> #include "libata.h" #include <acpi/acpi_bus.h> @@ -95,6 +96,47 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, + u32 event) +{ + char event_string[12]; + char *envp[] = { event_string, NULL }; + struct ata_eh_info *ehi = &ap->link.eh_info; + + if (event == 0 || event == 1) { + unsigned long flags; + spin_lock_irqsave(ap->lock, flags); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + spin_unlock_irqrestore(ap->lock, flags); + } + + if (kobj) { + sprintf(event_string, "BAY_EVENT=%d", event); + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); + } +} + +static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_device *dev = data; + struct kobject *kobj = NULL; + + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + + ata_acpi_handle_hotplug (dev->link->ap, kobj, event); +} + +static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + + ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event); +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -110,7 +152,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) */ void ata_acpi_associate(struct ata_host *host) { - int i; + int i, j; if (!is_pci_dev(host->dev) || libata_noacpi) return; @@ -126,6 +168,22 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_ap_notify, + ap); + + for (j = 0; j < ata_link_max_devices(&ap->link); j++) { + struct ata_device *dev = &ap->link.device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_dev_notify, + dev); + } } } -- Matthew Garrett | mjg59@srcf.ucam.org ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 2007-10-03 0:24 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 Matthew Garrett @ 2007-10-03 20:27 ` Jeff Garzik 0 siblings, 0 replies; 26+ messages in thread From: Jeff Garzik @ 2007-10-03 20:27 UTC (permalink / raw) To: Matthew Garrett Cc: Tejun Heo, linux-ide, linux-acpi, Andrew Morton, kristen.c.accardi Matthew Garrett wrote: > Modern laptops with hotswap bays still tend to utilise a PATA interface > on a SATA bridge, generally with the host controller in some legacy > emulation mode rather than AHCI. This means that the existing hotplug > code in libata is unable to work. The ACPI specification states that > these devices can send notifications when hotswapped, which avoids the > need to obtain notification from the controller. This patch uses the > existing libata-acpi code and simply registers a notification in order > to trigger a rescan whenever the firmware signals an event. > > Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> > > --- > > Diffed against #upstream. Fairly sure I've got it right this time... indeed you did sir :) applied, thanks ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2007-10-03 20:27 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-09-15 3:01 [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug Matthew Garrett 2007-09-15 17:06 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 Matthew Garrett 2007-09-16 12:22 ` Tejun Heo 2007-09-20 22:04 ` Jeff Garzik 2007-09-20 22:21 ` Matthew Garrett 2007-09-21 2:35 ` Tejun Heo 2007-09-21 2:42 ` Matthew Garrett 2007-09-21 2:53 ` Tejun Heo 2007-09-21 2:57 ` Matthew Garrett 2007-09-21 3:08 ` Tejun Heo 2007-09-21 3:12 ` Matthew Garrett 2007-09-21 3:19 ` Tejun Heo 2007-09-24 23:14 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 Matthew Garrett 2007-09-27 17:26 ` Kristen Carlson Accardi 2007-09-27 17:55 ` Matthew Garrett 2007-09-27 20:39 ` Henrique de Moraes Holschuh 2007-10-02 15:04 ` Jeff Garzik 2007-10-02 18:46 ` Matthew Garrett 2007-10-02 18:49 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 Matthew Garrett 2007-10-02 18:55 ` Jeff Garzik 2007-10-02 20:38 ` Jeff Garzik 2007-10-02 20:42 ` Matthew Garrett 2007-10-02 21:20 ` Matthew Garrett 2007-10-02 21:23 ` Jeff Garzik 2007-10-03 0:24 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 Matthew Garrett 2007-10-03 20:27 ` Jeff Garzik
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).