* 2.6.25 semantic change in bay handling?
@ 2008-05-05 22:33 Matthew Garrett
2008-05-06 8:13 ` Holger Macht
0 siblings, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-05 22:33 UTC (permalink / raw)
To: linux-ide; +Cc: tejun, Holger Macht, Jeff Garzik
48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
detached if an acpi eject request is received. In 2.6.24 and earlier, an
eject request merely sent an event to userland which could then cleanly
unmount the device and let the user know when it was safe to remove the
drive. Removing the device would then send another acpi request that
triggered the actual hotplug and bus rescan.
This seems like a regression - it's no longer possible to ensure that a
bay device is cleanly unmounted. Was this really the desired behaviour?
It should be noted that not all hardware sends the eject request at all
(Thinkpads do, but Dell and HP laptops don't), so we can't depend on
receiving this when dealing with a bay event.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-05 22:33 2.6.25 semantic change in bay handling? Matthew Garrett
@ 2008-05-06 8:13 ` Holger Macht
2008-05-06 8:21 ` Matthew Garrett
2008-05-06 8:40 ` 2.6.25 semantic change in bay handling? Holger Macht
0 siblings, 2 replies; 28+ messages in thread
From: Holger Macht @ 2008-05-06 8:13 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-ide, tejun, Jeff Garzik
On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
> 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
> detached if an acpi eject request is received. In 2.6.24 and earlier, an
> eject request merely sent an event to userland which could then cleanly
> unmount the device and let the user know when it was safe to remove the
> drive. Removing the device would then send another acpi request that
> triggered the actual hotplug and bus rescan.
What second acpi request are you referring to?
> This seems like a regression - it's no longer possible to ensure that a
> bay device is cleanly unmounted. Was this really the desired behaviour?
I'm thinking about his for several days now and looking for a proper
solution how to ensure that userland has the possibility to cleanly
unmount a device. But it's definitely no regression. Before...systems with
a bay in a dock stations simply froze hard in certain circumstances. It
was pure luck that it worked for one major kernel version or so.
The only sane way for me seems that userland has to be involved before
actually triggering any event or removing any device. Something like
"savely remove this piece of hardware".
For this to archive, we would need another sysfs entry flagging a bay
device as "on dock station", so that userland knows what to unmount/eject
before a dock event. Userspace relying on the bay event on the device is
not a proper solution. The device may have been gone before userland
finishes his work, or as you mention, there's no bay event.
> It should be noted that not all hardware sends the eject request at all
> (Thinkpads do, but Dell and HP laptops don't), so we can't depend on
> receiving this when dealing with a bay event.
I don't think we depend on the event. If the device gets removed without
an appropriate event, the behaviour should be the same as before. If not,
that wasn't the intentional behaviour.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:13 ` Holger Macht
@ 2008-05-06 8:21 ` Matthew Garrett
2008-05-06 8:40 ` Tejun Heo
2008-05-06 8:40 ` 2.6.25 semantic change in bay handling? Holger Macht
1 sibling, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 8:21 UTC (permalink / raw)
To: linux-ide, htejun, Jeff Garzik
On Tue, May 06, 2008 at 10:13:47AM +0200, Holger Macht wrote:
> On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
> > 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
> > detached if an acpi eject request is received. In 2.6.24 and earlier, an
> > eject request merely sent an event to userland which could then cleanly
> > unmount the device and let the user know when it was safe to remove the
> > drive. Removing the device would then send another acpi request that
> > triggered the actual hotplug and bus rescan.
>
> What second acpi request are you referring to?
For bay devices, the sequence is an optional eject request (before
removal, and not implemented on all hardware) followed by either a bus
or device check request (after removal).
> > This seems like a regression - it's no longer possible to ensure that a
> > bay device is cleanly unmounted. Was this really the desired behaviour?
>
> I'm thinking about his for several days now and looking for a proper
> solution how to ensure that userland has the possibility to cleanly
> unmount a device. But it's definitely no regression. Before...systems with
> a bay in a dock stations simply froze hard in certain circumstances. It
> was pure luck that it worked for one major kernel version or so.
Ah. I think the issue here is that you're trying to treat bays in docks
in the same way as internal bays. These should probably be different
callbacks.
> The only sane way for me seems that userland has to be involved before
> actually triggering any event or removing any device. Something like
> "savely remove this piece of hardware".
That's what the eject request is for.
> For this to archive, we would need another sysfs entry flagging a bay
> device as "on dock station", so that userland knows what to unmount/eject
> before a dock event. Userspace relying on the bay event on the device is
> not a proper solution. The device may have been gone before userland
> finishes his work, or as you mention, there's no bay event.
Yes. The user can, of course, do bad things. That doesn't mean we should
avoid the opportunity to cleanly unmount filesystems when the user
doesn't behave pathologically.
> > It should be noted that not all hardware sends the eject request at all
> > (Thinkpads do, but Dell and HP laptops don't), so we can't depend on
> > receiving this when dealing with a bay event.
>
> I don't think we depend on the event. If the device gets removed without
> an appropriate event, the behaviour should be the same as before. If not,
> that wasn't the intentional behaviour.
What ought to be possible for dock devices is something like "Receive
eject request, clean up anything that has to be done in kernel, allow
userspace to intervene and tidy up its side of things, let userspace
signal completion, complete the undocking sequence". For internal bays,
we certainly shouldn't be detaching the device when all we've received
is an eject request.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:13 ` Holger Macht
2008-05-06 8:21 ` Matthew Garrett
@ 2008-05-06 8:40 ` Holger Macht
1 sibling, 0 replies; 28+ messages in thread
From: Holger Macht @ 2008-05-06 8:40 UTC (permalink / raw)
To: Matthew Garrett, linux-ide, tejun, Jeff Garzik
On Tue 06. May - 10:13:47, Holger Macht wrote:
> On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
> > 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
> > detached if an acpi eject request is received. In 2.6.24 and earlier, an
> > eject request merely sent an event to userland which could then cleanly
> > unmount the device and let the user know when it was safe to remove the
> > drive. Removing the device would then send another acpi request that
> > triggered the actual hotplug and bus rescan.
>
> What second acpi request are you referring to?
>
> > This seems like a regression - it's no longer possible to ensure that a
> > bay device is cleanly unmounted. Was this really the desired behaviour?
>
> I'm thinking about his for several days now and looking for a proper
> solution how to ensure that userland has the possibility to cleanly
> unmount a device. But it's definitely no regression. Before...systems with
> a bay in a dock stations simply froze hard in certain circumstances. It
> was pure luck that it worked for one major kernel version or so.
>
> The only sane way for me seems that userland has to be involved before
> actually triggering any event or removing any device. Something like
> "savely remove this piece of hardware".
>
> For this to archive, we would need another sysfs entry flagging a bay
> device as "on dock station", so that userland knows what to unmount/eject
> before a dock event. Userspace relying on the bay event on the device is
> not a proper solution. The device may have been gone before userland
> finishes his work, or as you mention, there's no bay event.
>
> > It should be noted that not all hardware sends the eject request at all
> > (Thinkpads do, but Dell and HP laptops don't), so we can't depend on
> > receiving this when dealing with a bay event.
>
> I don't think we depend on the event. If the device gets removed without
> an appropriate event, the behaviour should be the same as before. If not,
> that wasn't the intentional behaviour.
AFAICT!
I just saw that the initial mail was not explicitly meant for me and the
patches regarding bay devices I've sent a couple of weeks ago.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:21 ` Matthew Garrett
@ 2008-05-06 8:40 ` Tejun Heo
2008-05-06 8:46 ` Matthew Garrett
2008-05-06 9:26 ` Holger Macht
0 siblings, 2 replies; 28+ messages in thread
From: Tejun Heo @ 2008-05-06 8:40 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-ide, Jeff Garzik, hmacht
(cc'ing Holger Macht, copying whole body for him)
Hello, guys.
Matthew Garrett wrote:
> On Tue, May 06, 2008 at 10:13:47AM +0200, Holger Macht wrote:
>> On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
>>> 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
That should be 233f112042d0b50170212dbff99c3b34b8773cd3, right?
>>> detached if an acpi eject request is received. In 2.6.24 and earlier, an
>>> eject request merely sent an event to userland which could then cleanly
>>> unmount the device and let the user know when it was safe to remove the
>>> drive. Removing the device would then send another acpi request that
>>> triggered the actual hotplug and bus rescan.
>> What second acpi request are you referring to?
>
> For bay devices, the sequence is an optional eject request (before
> removal, and not implemented on all hardware) followed by either a bus
> or device check request (after removal).
>
>>> This seems like a regression - it's no longer possible to ensure that a
>>> bay device is cleanly unmounted. Was this really the desired behaviour?
>> I'm thinking about his for several days now and looking for a proper
>> solution how to ensure that userland has the possibility to cleanly
>> unmount a device. But it's definitely no regression. Before...systems with
>> a bay in a dock stations simply froze hard in certain circumstances. It
>> was pure luck that it worked for one major kernel version or so.
>
> Ah. I think the issue here is that you're trying to treat bays in docks
> in the same way as internal bays. These should probably be different
> callbacks.
>
>> The only sane way for me seems that userland has to be involved before
>> actually triggering any event or removing any device. Something like
>> "savely remove this piece of hardware".
>
> That's what the eject request is for.
>
>> For this to archive, we would need another sysfs entry flagging a bay
>> device as "on dock station", so that userland knows what to unmount/eject
>> before a dock event. Userspace relying on the bay event on the device is
>> not a proper solution. The device may have been gone before userland
>> finishes his work, or as you mention, there's no bay event.
>
> Yes. The user can, of course, do bad things. That doesn't mean we should
> avoid the opportunity to cleanly unmount filesystems when the user
> doesn't behave pathologically.
>
>>> It should be noted that not all hardware sends the eject request at all
>>> (Thinkpads do, but Dell and HP laptops don't), so we can't depend on
>>> receiving this when dealing with a bay event.
>> I don't think we depend on the event. If the device gets removed without
>> an appropriate event, the behaviour should be the same as before. If not,
>> that wasn't the intentional behaviour.
>
> What ought to be possible for dock devices is something like "Receive
> eject request, clean up anything that has to be done in kernel, allow
> userspace to intervene and tidy up its side of things, let userspace
> signal completion, complete the undocking sequence". For internal bays,
> we certainly shouldn't be detaching the device when all we've received
> is an eject request.
>
The original change was from Holder Macht and IIRC it was to avoid
machine hard lock up on certain laptops which happens when libata EH
goes out to find out what happened when it receives bus/device check
after removal. Maybe what should be done instead is that eject request
doesn't do anything but tells acpid to unmount and delete the block
device by echoing 1 to sysfs delete node.
Hmmm... It would be perfect if we can tell whether DEVICE/BUS CHECK is
in which direction (device coming or going away).
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:40 ` Tejun Heo
@ 2008-05-06 8:46 ` Matthew Garrett
2008-05-06 8:53 ` Tejun Heo
2008-05-06 9:29 ` Holger Macht
2008-05-06 9:26 ` Holger Macht
1 sibling, 2 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 8:46 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, Jeff Garzik, hmacht
On Tue, May 06, 2008 at 05:40:39PM +0900, Tejun Heo wrote:
> >>On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
> >>>48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
>
> That should be 233f112042d0b50170212dbff99c3b34b8773cd3, right?
Yeah, my mistake.
> The original change was from Holder Macht and IIRC it was to avoid
> machine hard lock up on certain laptops which happens when libata EH
> goes out to find out what happened when it receives bus/device check
> after removal. Maybe what should be done instead is that eject request
> doesn't do anything but tells acpid to unmount and delete the block
> device by echoing 1 to sysfs delete node.
>From my point of view that's fine, but I'd be more interested to know
about the case Holger was having trouble with. For internal bays, at
least, we can't guarantee that we'll get an eject request before the
device is removed - if that leads to hangs, we probably need to work out
a way of being more robust here.
> Hmmm... It would be perfect if we can tell whether DEVICE/BUS CHECK is
> in which direction (device coming or going away).
Yeah, but I can't see an easy way of doing that. It's not enough to keep
track of the current state and assume that it's either an insertion or
removal as a result - some machines fire bus checks on resume, even if
the bay device hasn't been changed.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:46 ` Matthew Garrett
@ 2008-05-06 8:53 ` Tejun Heo
2008-05-06 9:17 ` Matthew Garrett
2008-05-06 9:29 ` Holger Macht
1 sibling, 1 reply; 28+ messages in thread
From: Tejun Heo @ 2008-05-06 8:53 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-ide, Jeff Garzik, hmacht
Matthew Garrett wrote:
> On Tue, May 06, 2008 at 05:40:39PM +0900, Tejun Heo wrote:
>>>> On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
>>>>> 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
>> That should be 233f112042d0b50170212dbff99c3b34b8773cd3, right?
>
> Yeah, my mistake.
>
>> The original change was from Holder Macht and IIRC it was to avoid
>> machine hard lock up on certain laptops which happens when libata EH
>> goes out to find out what happened when it receives bus/device check
>> after removal. Maybe what should be done instead is that eject request
>> doesn't do anything but tells acpid to unmount and delete the block
>> device by echoing 1 to sysfs delete node.
>
> From my point of view that's fine, but I'd be more interested to know
> about the case Holger was having trouble with. For internal bays, at
> least, we can't guarantee that we'll get an eject request before the
> device is removed - if that leads to hangs, we probably need to work out
> a way of being more robust here.
>
>> Hmmm... It would be perfect if we can tell whether DEVICE/BUS CHECK is
>> in which direction (device coming or going away).
>
> Yeah, but I can't see an easy way of doing that. It's not enough to keep
> track of the current state and assume that it's either an insertion or
> removal as a result - some machines fire bus checks on resume, even if
> the bay device hasn't been changed.
All we need is separate out the ejection case out. For suspend, resume,
attach or whatever can be handled the same way. The problem occurs
because some controllers get very unhappy when certain registers are
accessed when there's no device attached to it.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:53 ` Tejun Heo
@ 2008-05-06 9:17 ` Matthew Garrett
2008-05-06 11:21 ` Holger Macht
` (2 more replies)
0 siblings, 3 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 9:17 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, Jeff Garzik, hmacht
On Tue, May 06, 2008 at 05:53:17PM +0900, Tejun Heo wrote:
> Matthew Garrett wrote:
> >Yeah, but I can't see an easy way of doing that. It's not enough to keep
> >track of the current state and assume that it's either an insertion or
> >removal as a result - some machines fire bus checks on resume, even if
> >the bay device hasn't been changed.
>
> All we need is separate out the ejection case out. For suspend, resume,
> attach or whatever can be handled the same way. The problem occurs
> because some controllers get very unhappy when certain registers are
> accessed when there's no device attached to it.
Ok. What we probably ought to be doing then is checking the _STA method
on the bay when we receive a bus check. That should be sufficient for
determining whether the device is actually there (if so, perform a
hotplug) or not (flag the device as detached, don't probe). I don't have
the hardware here right now, but something like...
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 8c1cfc6..f1d5c87 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -126,37 +126,49 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
struct ata_eh_info *ehi;
struct kobject *kobj = NULL;
int wait = 0;
- unsigned long flags;
+ unsigned long flags, sta;
+ acpi_status status;
+ acpi_handle handle;
if (!ap)
ap = dev->link->ap;
ehi = &ap->link.eh_info;
+ if (dev)
+ handle = dev->acpi_handle;
+ else
+ handle = ap->handle;
+
spin_lock_irqsave(ap->lock, flags);
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (!ACPI_SUCCESS(status)) {
+ printk(KERN_ERR "Unable to evaluate bay status\n");
+ break;
+ }
ata_ehi_push_desc(ehi, "ACPI event");
- ata_ehi_hotplugged(ehi);
- ata_port_freeze(ap);
- break;
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- ata_ehi_push_desc(ehi, "ACPI event");
- if (dev)
- dev->flags |= ATA_DFLAG_DETACH;
- else {
- struct ata_link *tlink;
- struct ata_device *tdev;
-
- ata_port_for_each_link(tlink, ap)
- ata_link_for_each_dev(tdev, tlink)
+ if (sta) {
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
+ } else {
+ /* The device has gone - unplug it */
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap)
+ ata_link_for_each_dev(tdev, tlink)
tdev->flags |= ATA_DFLAG_DETACH;
+ }
+ wait = 1;
+ ata_port_freeze(ap);
+ ata_port_schedule_eh(ap);
}
-
- ata_port_schedule_eh(ap);
- wait = 1;
break;
}
Might work. Possibly. I'll be able to test on real hardware sometime
next week, but I don't have access to an ACPI dock with an internal bay.
I'm not sure how that case would be handled off-hand.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:40 ` Tejun Heo
2008-05-06 8:46 ` Matthew Garrett
@ 2008-05-06 9:26 ` Holger Macht
2008-05-06 9:36 ` Matthew Garrett
1 sibling, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-06 9:26 UTC (permalink / raw)
To: Tejun Heo; +Cc: Matthew Garrett, linux-ide, Jeff Garzik
On Di 06. Mai - 17:40:39, Tejun Heo wrote:
> (cc'ing Holger Macht, copying whole body for him)
>
> Hello, guys.
>
> Matthew Garrett wrote:
>> On Tue, May 06, 2008 at 10:13:47AM +0200, Holger Macht wrote:
>>> On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
>>>> 48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
>
> That should be 233f112042d0b50170212dbff99c3b34b8773cd3, right?
>
>>>> detached if an acpi eject request is received. In 2.6.24 and earlier, an
>>>> eject request merely sent an event to userland which could then cleanly
>>>> unmount the device and let the user know when it was safe to remove the
>>>> drive. Removing the device would then send another acpi request that
>>>> triggered the actual hotplug and bus rescan.
>>> What second acpi request are you referring to?
>>
>> For bay devices, the sequence is an optional eject request (before
>> removal, and not implemented on all hardware) followed by either a bus or
>> device check request (after removal).
>>
>>>> This seems like a regression - it's no longer possible to ensure that a
>>>> bay device is cleanly unmounted. Was this really the desired behaviour?
>>> I'm thinking about his for several days now and looking for a proper
>>> solution how to ensure that userland has the possibility to cleanly
>>> unmount a device. But it's definitely no regression. Before...systems with
>>> a bay in a dock stations simply froze hard in certain circumstances. It
>>> was pure luck that it worked for one major kernel version or so.
>>
>> Ah. I think the issue here is that you're trying to treat bays in docks in
>> the same way as internal bays. These should probably be different
>> callbacks.
Right, another solution I'm thinking of is to just handle those bays in
the docks differently. Going back to the old bahaviour, thus letting full
control to userland about deleting a bay device.
For the dockstation case, we have to detach a bay on the dock
immediately. Otherwise userland might call into a dead interface. You can
differentiate already through the dock driver, having different callbacks
for "dock notification" and the acpi notification for the bay device.
>>
>>> The only sane way for me seems that userland has to be involved before
>>> actually triggering any event or removing any device. Something like
>>> "savely remove this piece of hardware".
>>
>> That's what the eject request is for.
No. The moment when the bay event is generated, the moment the user pushes
the lever on the bay, the user might immediately pull out the device,
letting no chance for cleaning up...There must be an event before the user
touches anything, to have the time to unmount etc. and then tell "now it's
save to remove the bay device". This would also solve the "there's no bay
event" case.
>>
>>> For this to archive, we would need another sysfs entry flagging a bay
>>> device as "on dock station", so that userland knows what to unmount/eject
>>> before a dock event. Userspace relying on the bay event on the device is
>>> not a proper solution. The device may have been gone before userland
>>> finishes his work, or as you mention, there's no bay event.
>>
>> Yes. The user can, of course, do bad things. That doesn't mean we should
>> avoid the opportunity to cleanly unmount filesystems when the user doesn't
>> behave pathologically.
Agreed.
>>
>>>> It should be noted that not all hardware sends the eject request at all
>>>> (Thinkpads do, but Dell and HP laptops don't), so we can't depend on
>>>> receiving this when dealing with a bay event.
>>> I don't think we depend on the event. If the device gets removed without
>>> an appropriate event, the behaviour should be the same as before. If not,
>>> that wasn't the intentional behaviour.
>>
>> What ought to be possible for dock devices is something like "Receive
>> eject request, clean up anything that has to be done in kernel, allow
>> userspace to intervene and tidy up its side of things, let userspace
>> signal completion, complete the undocking sequence". For internal bays, we
>> certainly shouldn't be detaching the device when all we've received is an
>> eject request.
When the bay is inside the dock, it should be save to immediately remove
the device. Userspace is in control of sending the dock event whenever it
likes to, being able to unmount filesystems etc. before generating the
event. Userland just needs to know which bays are in the dock.
> The original change was from Holder Macht and IIRC it was to avoid machine
> hard lock up on certain laptops which happens when libata EH goes out to
> find out what happened when it receives bus/device check after removal.
> Maybe what should be done instead is that eject request doesn't do anything
> but tells acpid to unmount and delete the block device by echoing 1 to
> sysfs delete node.
If that's acceptable, I'm ok with letting full control to userspace.
Regards,
Holger
> Hmmm... It would be perfect if we can tell whether DEVICE/BUS CHECK is in
> which direction (device coming or going away).
>
> Thanks.
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 8:46 ` Matthew Garrett
2008-05-06 8:53 ` Tejun Heo
@ 2008-05-06 9:29 ` Holger Macht
2008-05-06 9:39 ` Matthew Garrett
1 sibling, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-06 9:29 UTC (permalink / raw)
To: Matthew Garrett; +Cc: Tejun Heo, linux-ide, Jeff Garzik
On Di 06. Mai - 09:46:25, Matthew Garrett wrote:
> On Tue, May 06, 2008 at 05:40:39PM +0900, Tejun Heo wrote:
> > >>On Mo 05. Mai - 23:33:57, Matthew Garrett wrote:
> > >>>48feb3c419508487becfb9ea3afcc54c3eac6d80 appears to flag a device as
> >
> > That should be 233f112042d0b50170212dbff99c3b34b8773cd3, right?
>
> Yeah, my mistake.
>
> > The original change was from Holder Macht and IIRC it was to avoid
> > machine hard lock up on certain laptops which happens when libata EH
> > goes out to find out what happened when it receives bus/device check
> > after removal. Maybe what should be done instead is that eject request
> > doesn't do anything but tells acpid to unmount and delete the block
> > device by echoing 1 to sysfs delete node.
>
> From my point of view that's fine, but I'd be more interested to know
> about the case Holger was having trouble with. For internal bays, at
> least, we can't guarantee that we'll get an eject request before the
> device is removed - if that leads to hangs, we probably need to work out
> a way of being more robust here.
Right, so you never can rely on receiving a BAY_EVENT. Why not just
disregard this case and looking for a common solution?
Regards,
Holger
> > Hmmm... It would be perfect if we can tell whether DEVICE/BUS CHECK is
> > in which direction (device coming or going away).
>
> Yeah, but I can't see an easy way of doing that. It's not enough to keep
> track of the current state and assume that it's either an insertion or
> removal as a result - some machines fire bus checks on resume, even if
> the bay device hasn't been changed.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 9:26 ` Holger Macht
@ 2008-05-06 9:36 ` Matthew Garrett
2008-05-19 16:29 ` [PATCH] Fixups to ATA ACPI hotplug Matthew Garrett
0 siblings, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 9:36 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik
On Tue, May 06, 2008 at 11:26:53AM +0200, Holger Macht wrote:
> No. The moment when the bay event is generated, the moment the user pushes
> the lever on the bay, the user might immediately pull out the device,
> letting no chance for cleaning up...There must be an event before the user
> touches anything, to have the time to unmount etc. and then tell "now it's
> save to remove the bay device". This would also solve the "there's no bay
> event" case.
Hm. The hardware I have here has a separate "eject request" button and
"physical eject" button. Hitting the former sends the request to the OS,
and the light then pulses until the OS confirms that the dock can be
removed. If the user removes the dock before this happens, that's user
error. Unfortunately, the hardware in question doesn't contain a bay.
The only dock I have with no request button doesn't present as an ACPI
dock to begin with. Do Thinkpad docks differ from this?
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 9:29 ` Holger Macht
@ 2008-05-06 9:39 ` Matthew Garrett
0 siblings, 0 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 9:39 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik
On Tue, May 06, 2008 at 11:29:35AM +0200, Holger Macht wrote:
> Right, so you never can rely on receiving a BAY_EVENT. Why not just
> disregard this case and looking for a common solution?
Oh, I agree - we need to solve this in any case. But for hardware where
there is a separate request event before the device is pulled, users
already have scripts that prompt them to unmount hardware. These worked
in <2.6.25, but they're broken now. It'd be nice to get them working
again.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 9:17 ` Matthew Garrett
@ 2008-05-06 11:21 ` Holger Macht
2008-05-06 11:31 ` Matthew Garrett
2008-05-06 17:27 ` Holger Macht
2008-05-06 18:36 ` Holger Macht
2 siblings, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-06 11:21 UTC (permalink / raw)
To: Matthew Garrett; +Cc: Tejun Heo, linux-ide, Jeff Garzik
Hi,
(Can you please keep me CC'ed, I'm not on linux-ide)
Quoting your mail from the archives:
>> Right, so you never can rely on receiving a BAY_EVENT. Why not just
>> disregard this case and looking for a common solution?
> Oh, I agree - we need to solve this in any case. But for hardware where
> there is a separate request event before the device is pulled, users
> already have scripts that prompt them to unmount hardware. These worked
> in <2.6.25, but they're broken now. It'd be nice to get them working
> again.
Yes, the scripts were broken for the advantage to not freeze some devices ;-)
But I agree, we need such a possibility.
>> No. The moment when the bay event is generated, the moment the user pushes
>> the lever on the bay, the user might immediately pull out the device,
>> letting no chance for cleaning up...There must be an event before the user
>> touches anything, to have the time to unmount etc. and then tell "now it's
>> save to remove the bay device". This would also solve the "there's no bay
>> event" case.
> Hm. The hardware I have here has a separate "eject request" button and
> "physical eject" button. Hitting the former sends the request to the OS,
> and the light then pulses until the OS confirms that the dock can be
> removed. If the user removes the dock before this happens, that's user
> error.
Not by default. The dock driver immediately undocks unless
immediate_undock parameter is set to 0. Any access to the bay inside the
dock afterwards might freeze the system.
Actually I was talking about the "bay not in the dock"-case here.
Unfortunately, the hardware in question doesn't contain a bay.
> The only dock I have with no request button doesn't present as an ACPI
> dock to begin with. Do Thinkpad docks differ from this?
There are those which do simple PCI hotplugging without the involvement of
ACPI (many/all HPs AFAIK) and those which present themselves as a
dockstation through ACPI (those with a _DCK method). The thinkpad X60 dock
I have here has the request button, too.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 11:21 ` Holger Macht
@ 2008-05-06 11:31 ` Matthew Garrett
0 siblings, 0 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 11:31 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik
On Tue, May 06, 2008 at 01:21:45PM +0200, Holger Macht wrote:
> Not by default. The dock driver immediately undocks unless
> immediate_undock parameter is set to 0. Any access to the bay inside the
> dock afterwards might freeze the system.
>
> Actually I was talking about the "bay not in the dock"-case here.
In that case, the effect differs depending on the hardware. In the ideal
universe, Thinkpad users flick out the eject lever and wait for a
confirmation that they can pull out the drive. Dell and HP users have to
request a safe remove in advance.
> There are those which do simple PCI hotplugging without the involvement of
> ACPI (many/all HPs AFAIK) and those which present themselves as a
> dockstation through ACPI (those with a _DCK method). The thinkpad X60 dock
> I have here has the request button, too.
Right. In that case, it needs to be possible for userspace to indicate
that the eject request should not automatically destroy the device.
Actually removing the dock should do so in all circumstances.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 9:17 ` Matthew Garrett
2008-05-06 11:21 ` Holger Macht
@ 2008-05-06 17:27 ` Holger Macht
2008-05-06 17:48 ` Matthew Garrett
2008-05-06 18:36 ` Holger Macht
2 siblings, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-06 17:27 UTC (permalink / raw)
To: Matthew Garrett; +Cc: Tejun Heo, linux-ide, Jeff Garzik
( I still had to poll linux-ide archives... )
>> Not by default. The dock driver immediately undocks unless
>> immediate_undock parameter is set to 0. Any access to the bay inside the
>> dock afterwards might freeze the system.
>>
>> Actually I was talking about the "bay not in the dock"-case here.
> In that case, the effect differs depending on the hardware. In the ideal
> universe, Thinkpad users flick out the eject lever and wait for a
> confirmation that they can pull out the drive. Dell and HP users have to
> request a safe remove in advance.
If you need to make clear that the user has to wait for a notification
before he removes the device, you could just make him clear that he has to
request a safe remove in advance.
But yes, I see your point.
>> There are those which do simple PCI hotplugging without the involvement of
>> ACPI (many/all HPs AFAIK) and those which present themselves as a
>> dockstation through ACPI (those with a _DCK method). The thinkpad X60 dock
>> I have here has the request button, too.
> Right. In that case, it needs to be possible for userspace to indicate
> that the eject request should not automatically destroy the device.
> Actually removing the dock should do so in all circumstances.
That's what I'm trying to say.
Just to make clear that we agree on the design, if so, I'll try to provide
a patch:
1. Dock event: libata immediately detaches the device
(libata will need another sysfs flag is_on_dock userspace can query)
2. Bay event: libata signals a BAY_EVENT through uevent, userspace writes
1 to /sys/.../device/delete
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 17:27 ` Holger Macht
@ 2008-05-06 17:48 ` Matthew Garrett
0 siblings, 0 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 17:48 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik
On Tue, May 06, 2008 at 07:27:43PM +0200, Holger Macht wrote:
> Just to make clear that we agree on the design, if so, I'll try to provide
> a patch:
>
> 1. Dock event: libata immediately detaches the device
>
> (libata will need another sysfs flag is_on_dock userspace can query)
Hm. I'm not absolutely certain about this. Do we get a bus check
notification after the dock has been removed? If so, I think it ought to
be handled the same way as the internal bay (ie, signal userspace and
let it clean up and destroy the device - if it fails to do so, then
destroy the device when the dock is actually removed, by catching the
bus/device check, calling the _STA method on the bay and destroying the
device if it's present)
> 2. Bay event: libata signals a BAY_EVENT through uevent, userspace writes
> 1 to /sys/.../device/delete
In the case of an eject request, yes. In the case of a bus or device
check, we should call _STA and then delete/hotplug the device as
appropriate.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 9:17 ` Matthew Garrett
2008-05-06 11:21 ` Holger Macht
2008-05-06 17:27 ` Holger Macht
@ 2008-05-06 18:36 ` Holger Macht
2008-05-06 18:48 ` Matthew Garrett
2 siblings, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-06 18:36 UTC (permalink / raw)
To: Matthew Garrett; +Cc: Tejun Heo, linux-ide, Jeff Garzik
Hi Matthew,
( Please TO or CC hmacht@suse.de ! )
>> Just to make clear that we agree on the design, if so, I'll try to provide
>> a patch:
>>
>> 1. Dock event: libata immediately detaches the device
>>
>> (libata will need another sysfs flag is_on_dock userspace can query)
> Hm. I'm not absolutely certain about this. Do we get a bus check
> notification after the dock has been removed? If so, I think it ought to
> be handled the same way as the internal bay (ie, signal userspace and
> let it clean up and destroy the device - if it fails to do so, then
> destroy the device when the dock is actually removed, by catching the
> bus/device check, calling the _STA method on the bay and destroying the
> device if it's present)
libata is notified through the dock driver when a dock event occurs, just
before the dock driver undocks, giving no time to userspace to clean
up. libata doesn't receive an additional acpi bay event.
>> 2. Bay event: libata signals a BAY_EVENT through uevent, userspace writes
>> 1 to /sys/.../device/delete
> In the case of an eject request, yes. In the case of a bus or device
> check, we should call _STA and then delete/hotplug the device as
> appropriate.
Yes.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 18:36 ` Holger Macht
@ 2008-05-06 18:48 ` Matthew Garrett
2008-05-06 22:06 ` Holger Macht
0 siblings, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-06 18:48 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik; +Cc: hmact
On Tue, May 06, 2008 at 08:36:12PM +0200, Holger Macht wrote:
> Hi Matthew,
>
> ( Please TO or CC hmacht@suse.de ! )
Then stop setting Mail-Followup-To: :)
> > Hm. I'm not absolutely certain about this. Do we get a bus check
> > notification after the dock has been removed? If so, I think it ought to
> > be handled the same way as the internal bay (ie, signal userspace and
> > let it clean up and destroy the device - if it fails to do so, then
> > destroy the device when the dock is actually removed, by catching the
> > bus/device check, calling the _STA method on the bay and destroying the
> > device if it's present)
>
> libata is notified through the dock driver when a dock event occurs, just
> before the dock driver undocks, giving no time to userspace to clean
> up. libata doesn't receive an additional acpi bay event.
That's the current situation, I'm not sure it's ideal. But I'll skip
worrying about that until I've actually got some hardware to work out
how to do it properly :)
> >> 2. Bay event: libata signals a BAY_EVENT through uevent, userspace writes
> >> 1 to /sys/.../device/delete
>
> > In the case of an eject request, yes. In the case of a bus or device
> > check, we should call _STA and then delete/hotplug the device as
> > appropriate.
>
> Yes.
Excellent. I /think/ the patch I sent earlier basically does this -
you'll want to register a separate callback for the dock event in that
case, though.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: 2.6.25 semantic change in bay handling?
2008-05-06 18:48 ` Matthew Garrett
@ 2008-05-06 22:06 ` Holger Macht
0 siblings, 0 replies; 28+ messages in thread
From: Holger Macht @ 2008-05-06 22:06 UTC (permalink / raw)
To: Matthew Garrett; +Cc: Tejun Heo, linux-ide, Jeff Garzik, hmact
On Di 06. Mai - 19:48:28, Matthew Garrett wrote:
> On Tue, May 06, 2008 at 08:36:12PM +0200, Holger Macht wrote:
> > Hi Matthew,
> >
> > ( Please TO or CC hmacht@suse.de ! )
>
> Then stop setting Mail-Followup-To: :)
>
> > > Hm. I'm not absolutely certain about this. Do we get a bus check
> > > notification after the dock has been removed? If so, I think it ought to
> > > be handled the same way as the internal bay (ie, signal userspace and
> > > let it clean up and destroy the device - if it fails to do so, then
> > > destroy the device when the dock is actually removed, by catching the
> > > bus/device check, calling the _STA method on the bay and destroying the
> > > device if it's present)
> >
> > libata is notified through the dock driver when a dock event occurs, just
> > before the dock driver undocks, giving no time to userspace to clean
> > up. libata doesn't receive an additional acpi bay event.
>
> That's the current situation, I'm not sure it's ideal. But I'll skip
What exactly do you think is not ideal?
> worrying about that until I've actually got some hardware to work out
> how to do it properly :)
Maybe this is what you're thinking of?:
http://marc.info/?l=linux-acpi&m=121009411900390&w=2
>
> > >> 2. Bay event: libata signals a BAY_EVENT through uevent, userspace writes
> > >> 1 to /sys/.../device/delete
> >
> > > In the case of an eject request, yes. In the case of a bus or device
> > > check, we should call _STA and then delete/hotplug the device as
> > > appropriate.
> >
> > Yes.
>
> Excellent. I /think/ the patch I sent earlier basically does this -
> you'll want to register a separate callback for the dock event in that
> case, though.
I'll take a look the following days, thanks.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH] Fixups to ATA ACPI hotplug
2008-05-06 9:36 ` Matthew Garrett
@ 2008-05-19 16:29 ` Matthew Garrett
2008-05-20 7:44 ` Holger Macht
2008-05-20 8:49 ` Holger Macht
0 siblings, 2 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-19 16:29 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik; +Cc: linux-acpi, linux-kernel, hmacht
The libata-acpi.c code currently accepts hotplug messages from both the
port and the device. This does not match the behaviour of the bay
driver, and may result in confusion when two hotplug requests are
received for the same device. This patch limits the hotplug notification
to removable ACPI devices, which in turn allows it to use the _STA
method to determine whether the device has been removed or inserted.
On removal, devices are marked as detached. On insertion, a hotplug scan
is started. This should avoid lockups caused by the ata layer attempting
to scan devices which have been removed. The uevent sending is moved
outside the spinlock in order to avoid a warning generated by it firing
when interrupts are disabled.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
Holger, I'm pretty sure that this deals with the docking station removal
case, but don't have the hardware to test. If EJECT_REQUEST is genuinely
the only notification we receive (ie, no BUS_CHECK or DEVICE_CHECK) then
we'll need to add a separate callback for docking.
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 70b77e0..865a552 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -118,8 +118,8 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}
-static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
- u32 event)
+static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
+ *dev, u32 event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
@@ -127,39 +127,67 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
struct kobject *kobj = NULL;
int wait = 0;
unsigned long flags;
-
+ acpi_handle handle, tmphandle;
+ unsigned long sta;
+ acpi_status status;
+
if (!ap)
ap = dev->link->ap;
ehi = &ap->link.eh_info;
spin_lock_irqsave(ap->lock, flags);
+ if (dev)
+ handle = dev->acpi_handle;
+ else
+ handle = ap->acpi_handle;
+
+ status = acpi_get_handle(handle, "_EJ0", &tmphandle);
+ if (ACPI_FAILURE(status)) {
+ /* This device is not ejectable */
+ spin_unlock_irqrestore(ap->lock, flags);
+ return;
+ }
+
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (ACPI_FAILURE(status)) {
+ printk ("Unable to determine bay status\n");
+ spin_unlock_irqrestore(ap->lock, flags);
+ return;
+ }
+
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event");
- ata_ehi_hotplugged(ehi);
- ata_port_freeze(ap);
- break;
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- ata_ehi_push_desc(ehi, "ACPI event");
- if (dev)
- dev->flags |= ATA_DFLAG_DETACH;
- else {
- struct ata_link *tlink;
- struct ata_device *tdev;
-
- ata_port_for_each_link(tlink, ap)
- ata_link_for_each_dev(tdev, tlink)
- tdev->flags |= ATA_DFLAG_DETACH;
+ if (!sta) {
+ /* Device has been unplugged */
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap) {
+ ata_link_for_each_dev(tdev, tlink) {
+ tdev->flags |=
+ ATA_DFLAG_DETACH;
+ }
+ }
+ }
+ ata_port_schedule_eh(ap);
+ wait = 1;
+ } else {
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
}
-
- ata_port_schedule_eh(ap);
- wait = 1;
- break;
}
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ if (wait)
+ ata_port_wait_eh(ap);
+
if (dev) {
if (dev->sdev)
kobj = &dev->sdev->sdev_gendev.kobj;
@@ -170,11 +198,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
}
-
- spin_unlock_irqrestore(ap->lock, flags);
-
- if (wait)
- ata_port_wait_eh(ap);
}
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-19 16:29 ` [PATCH] Fixups to ATA ACPI hotplug Matthew Garrett
@ 2008-05-20 7:44 ` Holger Macht
2008-05-20 10:20 ` Matthew Garrett
2008-05-20 8:49 ` Holger Macht
1 sibling, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-20 7:44 UTC (permalink / raw)
To: Matthew Garrett
Cc: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Mon 19. May - 17:29:34, Matthew Garrett wrote:
> The libata-acpi.c code currently accepts hotplug messages from both the
> port and the device. This does not match the behaviour of the bay
> driver, and may result in confusion when two hotplug requests are
> received for the same device. This patch limits the hotplug notification
> to removable ACPI devices, which in turn allows it to use the _STA
> method to determine whether the device has been removed or inserted.
> On removal, devices are marked as detached. On insertion, a hotplug scan
> is started. This should avoid lockups caused by the ata layer attempting
> to scan devices which have been removed. The uevent sending is moved
> outside the spinlock in order to avoid a warning generated by it firing
> when interrupts are disabled.
Ok, it seems we're currently doing the same work two times. I've also got
a patch for this. Already tested, so please have a look if this would also
match your requirements:
Handle bay devices in dock stations
* Differentiate between bay devices in dock stations and others:
- When an ACPI_NOTIFY_EJECT_REQUEST appears, just signal uevent to
userspace (that is when the optional eject button on a bay device is
pressed/pulled) giving the possibility to unmount file systems and to
clean up. Also, only send uevent in case we get an
ACPI_NOTIFY_EJECT_REQUEST without doing anything else. In other cases,
you'll get an add/remove event because libata attaches/detaches the
device.
- In case of a dock event, which in turn signals an
ACPI_NOTIFY_EJECT_REQUEST, immediately detach the device, because it
may already have been gone
* In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
the device has been plugged or unplugged. If plugged, hotplug it, if
unplugged, just signal event to userspace
(initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
Signed-off-by: Holger Macht <hmacht@suse.de>
---
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 70b77e0..62d94e4 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -118,77 +118,118 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}
+static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
+{
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap)
+ ata_link_for_each_dev(tdev, tlink)
+ tdev->flags |= ATA_DFLAG_DETACH;
+ }
+
+ ata_port_freeze(ap);
+ ata_port_schedule_eh(ap);
+}
+
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
- u32 event)
+ u32 event, int is_dock_event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
struct ata_eh_info *ehi;
struct kobject *kobj = NULL;
int wait = 0;
- unsigned long flags;
+ unsigned long flags, sta;
+ acpi_status status;
+ acpi_handle handle;
if (!ap)
ap = dev->link->ap;
ehi = &ap->link.eh_info;
+ if (dev) {
+ if (dev->sdev)
+ kobj = &dev->sdev->sdev_gendev.kobj;
+ handle = dev->acpi_handle;
+ } else {
+ kobj = &ap->dev->kobj;
+ handle = ap->acpi_handle;
+ }
+
+ if (kobj && !is_dock_event) {
+ sprintf(event_string, "BAY_EVENT=%d", event);
+ kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
+ }
+
spin_lock_irqsave(ap->lock, flags);
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event");
- ata_ehi_hotplugged(ehi);
- ata_port_freeze(ap);
- break;
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (!ACPI_SUCCESS(status)) {
+ printk(KERN_INFO "Unable to evaluate bay status\n");
+ break;
+ }
+
+ if (sta) {
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
+ } else {
+ /* The device has gone - unplug it */
+ ata_acpi_detach_device(ap, dev);
+ wait = 1;
+ }
+ break;
case ACPI_NOTIFY_EJECT_REQUEST:
ata_ehi_push_desc(ehi, "ACPI event");
- if (dev)
- dev->flags |= ATA_DFLAG_DETACH;
- else {
- struct ata_link *tlink;
- struct ata_device *tdev;
-
- ata_port_for_each_link(tlink, ap)
- ata_link_for_each_dev(tdev, tlink)
- tdev->flags |= ATA_DFLAG_DETACH;
- }
+ if (!is_dock_event)
+ break;
- ata_port_schedule_eh(ap);
+ /* undock event - immediate unplug */
+ ata_acpi_detach_device(ap, dev);
wait = 1;
break;
}
- if (dev) {
- if (dev->sdev)
- kobj = &dev->sdev->sdev_gendev.kobj;
- } else
- kobj = &ap->dev->kobj;
-
- if (kobj) {
- sprintf(event_string, "BAY_EVENT=%d", event);
- kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
- }
-
spin_unlock_irqrestore(ap->lock, flags);
if (wait)
ata_port_wait_eh(ap);
}
+static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_device *dev = data;
+
+ ata_acpi_handle_hotplug(NULL, dev, event, 1);
+}
+
+static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_port *ap = data;
+
+ ata_acpi_handle_hotplug(ap, NULL, event, 1);
+}
+
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_device *dev = data;
- ata_acpi_handle_hotplug(NULL, dev, event);
+ ata_acpi_handle_hotplug(NULL, dev, event, 0);
}
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_port *ap = data;
- ata_acpi_handle_hotplug(ap, NULL, event);
+ ata_acpi_handle_hotplug(ap, NULL, event, 0);
}
/**
@@ -229,7 +270,7 @@ void ata_acpi_associate(struct ata_host *host)
ata_acpi_ap_notify, ap);
/* we might be on a docking station */
register_hotplug_dock_device(ap->acpi_handle,
- ata_acpi_ap_notify, ap);
+ ata_acpi_ap_notify_dock, ap);
}
for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -241,7 +282,7 @@ void ata_acpi_associate(struct ata_host *host)
ata_acpi_dev_notify, dev);
/* we might be on a docking station */
register_hotplug_dock_device(dev->acpi_handle,
- ata_acpi_dev_notify, dev);
+ ata_acpi_dev_notify_dock, dev);
}
}
}
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-19 16:29 ` [PATCH] Fixups to ATA ACPI hotplug Matthew Garrett
2008-05-20 7:44 ` Holger Macht
@ 2008-05-20 8:49 ` Holger Macht
1 sibling, 0 replies; 28+ messages in thread
From: Holger Macht @ 2008-05-20 8:49 UTC (permalink / raw)
To: Matthew Garrett
Cc: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Mon 19. May - 17:29:34, Matthew Garrett wrote:
> The libata-acpi.c code currently accepts hotplug messages from both the
> port and the device. This does not match the behaviour of the bay
> driver, and may result in confusion when two hotplug requests are
> received for the same device. This patch limits the hotplug notification
> to removable ACPI devices, which in turn allows it to use the _STA
> method to determine whether the device has been removed or inserted.
> On removal, devices are marked as detached. On insertion, a hotplug scan
> is started. This should avoid lockups caused by the ata layer attempting
> to scan devices which have been removed. The uevent sending is moved
> outside the spinlock in order to avoid a warning generated by it firing
> when interrupts are disabled.
>
> Signed-off-by: Matthew Garrett <mjg@redhat.com>
>
> ---
>
> Holger, I'm pretty sure that this deals with the docking station removal
> case, but don't have the hardware to test. If EJECT_REQUEST is genuinely
I tried it, it doesn't.
Undock --> some userspace app accesses the device --> hard lockup
> the only notification we receive (ie, no BUS_CHECK or DEVICE_CHECK) then
> we'll need to add a separate callback for docking.
Yes, see my patch.
Regards,
Holger
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 7:44 ` Holger Macht
@ 2008-05-20 10:20 ` Matthew Garrett
2008-05-20 13:18 ` Holger Macht
0 siblings, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-20 10:20 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Tue, May 20, 2008 at 09:44:42AM +0200, Holger Macht wrote:
> * In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
> the device has been plugged or unplugged. If plugged, hotplug it, if
> unplugged, just signal event to userspace
> (initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
The only issue I can see is that this one doesn't check _EJ0. Unless
that's done, you'll (on some hardware) evaluate _STA on the bay itself
rather than the device within the bay, which leads to confusion as to
whether the device has been inserted. Other than that, looks good.
Jeff's sent my patch to Linus, so can you redo this on top and I'll sign
it off?
Thanks,
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 10:20 ` Matthew Garrett
@ 2008-05-20 13:18 ` Holger Macht
2008-05-20 13:22 ` Matthew Garrett
0 siblings, 1 reply; 28+ messages in thread
From: Holger Macht @ 2008-05-20 13:18 UTC (permalink / raw)
To: Matthew Garrett
Cc: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Tue 20. May - 11:20:38, Matthew Garrett wrote:
> On Tue, May 20, 2008 at 09:44:42AM +0200, Holger Macht wrote:
>
> > * In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
> > the device has been plugged or unplugged. If plugged, hotplug it, if
> > unplugged, just signal event to userspace
> > (initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
>
> The only issue I can see is that this one doesn't check _EJ0. Unless
> that's done, you'll (on some hardware) evaluate _STA on the bay itself
> rather than the device within the bay, which leads to confusion as to
> whether the device has been inserted. Other than that, looks good.
> Jeff's sent my patch to Linus, so can you redo this on top and I'll sign
> it off?
Handle bay devices in dock stations
* Differentiate between bay devices in dock stations and others:
- When an ACPI_NOTIFY_EJECT_REQUEST appears, just signal uevent to
userspace (that is when the optional eject button on a bay device is
pressed/pulled) giving the possibility to unmount file systems and to
clean up. Also, only send uevent in case we get an EJECT_REQUEST
without doing anything else. In other cases, you'll get an add/remove
event because libata attaches/detaches the device.
- In case of a dock event, which in turn signals an
ACPI_NOTIFY_EJECT_REQUEST, immediately detach the device, because it
may already have been gone
* In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
the device has been plugged or unplugged. If plugged, hotplug it, if
unplugged, just signal event to userspace
(initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
Signed-off-by: Holger Macht <hmacht@suse.de>
---
--- linux-2.6.25/drivers/ata/libata-acpi.c.orig 2008-05-20 13:25:50.000000000 +0200
+++ linux-2.6.25/drivers/ata/libata-acpi.c 2008-05-20 15:12:03.000000000 +0200
@@ -118,8 +118,25 @@ static void ata_acpi_associate_ide_port(
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}
+static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
+{
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap)
+ ata_link_for_each_dev(tdev, tlink)
+ tdev->flags |= ATA_DFLAG_DETACH;
+ }
+
+ ata_port_freeze(ap);
+ ata_port_schedule_eh(ap);
+}
+
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
- *dev, u32 event)
+ *dev, u32 event, int is_dock_event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
@@ -135,83 +152,92 @@ static void ata_acpi_handle_hotplug(stru
ap = dev->link->ap;
ehi = &ap->link.eh_info;
- spin_lock_irqsave(ap->lock, flags);
-
- if (dev)
+ if (dev) {
+ if (dev->sdev)
+ kobj = &dev->sdev->sdev_gendev.kobj;
handle = dev->acpi_handle;
- else
+ } else {
+ kobj = &ap->dev->kobj;
handle = ap->acpi_handle;
-
- status = acpi_get_handle(handle, "_EJ0", &tmphandle);
- if (ACPI_FAILURE(status)) {
- /* This device is not ejectable */
- spin_unlock_irqrestore(ap->lock, flags);
- return;
}
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- if (ACPI_FAILURE(status)) {
- printk ("Unable to determine bay status\n");
- spin_unlock_irqrestore(ap->lock, flags);
- return;
+ if (kobj && !is_dock_event) {
+ sprintf(event_string, "BAY_EVENT=%d", event);
+ kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
}
+ spin_lock_irqsave(ap->lock, flags);
+
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event");
- if (!sta) {
- /* Device has been unplugged */
- if (dev)
- dev->flags |= ATA_DFLAG_DETACH;
- else {
- struct ata_link *tlink;
- struct ata_device *tdev;
-
- ata_port_for_each_link(tlink, ap) {
- ata_link_for_each_dev(tdev, tlink) {
- tdev->flags |=
- ATA_DFLAG_DETACH;
- }
- }
- }
- ata_port_schedule_eh(ap);
- wait = 1;
- } else {
+
+ status = acpi_get_handle(handle, "_EJ0", &tmphandle);
+ if (ACPI_FAILURE(status)) {
+ /* This device is not ejectable */
+ break;
+ }
+
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Unable to determine bay status\n");
+ break;
+ }
+
+ if (sta) {
ata_ehi_hotplugged(ehi);
ata_port_freeze(ap);
+ } else {
+ /* The device has gone - unplug it */
+ ata_acpi_detach_device(ap, dev);
+ wait = 1;
}
+ break;
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ ata_ehi_push_desc(ehi, "ACPI event");
+
+ if (!is_dock_event)
+ break;
+
+ /* undock event - immediate unplug */
+ ata_acpi_detach_device(ap, dev);
+ wait = 1;
+ break;
}
spin_unlock_irqrestore(ap->lock, flags);
if (wait)
ata_port_wait_eh(ap);
+}
- if (dev) {
- if (dev->sdev)
- kobj = &dev->sdev->sdev_gendev.kobj;
- } else
- kobj = &ap->dev->kobj;
+static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_device *dev = data;
- if (kobj) {
- sprintf(event_string, "BAY_EVENT=%d", event);
- kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
- }
+ ata_acpi_handle_hotplug(NULL, dev, event, 1);
+}
+
+static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_port *ap = data;
+
+ ata_acpi_handle_hotplug(ap, NULL, event, 1);
}
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_device *dev = data;
- ata_acpi_handle_hotplug(NULL, dev, event);
+ ata_acpi_handle_hotplug(NULL, dev, event, 0);
}
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_port *ap = data;
- ata_acpi_handle_hotplug(ap, NULL, event);
+ ata_acpi_handle_hotplug(ap, NULL, event, 0);
}
/**
@@ -252,7 +278,7 @@ void ata_acpi_associate(struct ata_host
ata_acpi_ap_notify, ap);
/* we might be on a docking station */
register_hotplug_dock_device(ap->acpi_handle,
- ata_acpi_ap_notify, ap);
+ ata_acpi_ap_notify_dock, ap);
}
for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -264,7 +290,7 @@ void ata_acpi_associate(struct ata_host
ata_acpi_dev_notify, dev);
/* we might be on a docking station */
register_hotplug_dock_device(dev->acpi_handle,
- ata_acpi_dev_notify, dev);
+ ata_acpi_dev_notify_dock, dev);
}
}
}
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 13:18 ` Holger Macht
@ 2008-05-20 13:22 ` Matthew Garrett
2008-05-20 13:58 ` Holger Macht
0 siblings, 1 reply; 28+ messages in thread
From: Matthew Garrett @ 2008-05-20 13:22 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Tue, May 20, 2008 at 03:18:32PM +0200, Holger Macht wrote:
> + if (kobj && !is_dock_event) {
> + sprintf(event_string, "BAY_EVENT=%d", event);
> + kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
I think we want to do the _EJ0 checking before this, otherwise we'll
generate two uevents for the same removal on some hardware. Otherwise,
looks good.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 13:22 ` Matthew Garrett
@ 2008-05-20 13:58 ` Holger Macht
2008-05-20 14:00 ` Matthew Garrett
2008-05-21 22:26 ` Andrew Morton
0 siblings, 2 replies; 28+ messages in thread
From: Holger Macht @ 2008-05-20 13:58 UTC (permalink / raw)
To: Matthew Garrett
Cc: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Tue 20. May - 14:22:17, Matthew Garrett wrote:
> On Tue, May 20, 2008 at 03:18:32PM +0200, Holger Macht wrote:
>
> > + if (kobj && !is_dock_event) {
> > + sprintf(event_string, "BAY_EVENT=%d", event);
> > + kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
>
> I think we want to do the _EJ0 checking before this, otherwise we'll
> generate two uevents for the same removal on some hardware. Otherwise,
> looks good.
So once again:
Handle bay devices in dock stations
* Differentiate between bay devices in dock stations and others:
- When an ACPI_NOTIFY_EJECT_REQUEST appears, just signal uevent to
userspace (that is when the optional eject button on a bay device is
pressed/pulled) giving the possibility to unmount file systems and to
clean up. Also, only send uevent in case we get an EJECT_REQUEST
without doing anything else. In other cases, you'll get an add/remove
event because libata attaches/detaches the device.
- In case of a dock event, which in turn signals an
ACPI_NOTIFY_EJECT_REQUEST, immediately detach the device, because it
may already have been gone
* In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
the device has been plugged or unplugged. If plugged, hotplug it, if
unplugged, just signal event to userspace
(initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
Signed-off-by: Holger Macht <hmacht@suse.de>
---
--- linux-2.6.25/drivers/ata/libata-acpi.c.orig 2008-05-20 13:25:50.000000000 +0200
+++ linux-2.6.25/drivers/ata/libata-acpi.c 2008-05-20 15:56:38.000000000 +0200
@@ -118,8 +118,25 @@ static void ata_acpi_associate_ide_port(
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}
+static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
+{
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap)
+ ata_link_for_each_dev(tdev, tlink)
+ tdev->flags |= ATA_DFLAG_DETACH;
+ }
+
+ ata_port_freeze(ap);
+ ata_port_schedule_eh(ap);
+}
+
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
- *dev, u32 event)
+ *dev, u32 event, int is_dock_event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
@@ -135,83 +152,92 @@ static void ata_acpi_handle_hotplug(stru
ap = dev->link->ap;
ehi = &ap->link.eh_info;
- spin_lock_irqsave(ap->lock, flags);
-
- if (dev)
+ if (dev) {
+ if (dev->sdev)
+ kobj = &dev->sdev->sdev_gendev.kobj;
handle = dev->acpi_handle;
- else
+ } else {
+ kobj = &ap->dev->kobj;
handle = ap->acpi_handle;
+ }
status = acpi_get_handle(handle, "_EJ0", &tmphandle);
if (ACPI_FAILURE(status)) {
- /* This device is not ejectable */
- spin_unlock_irqrestore(ap->lock, flags);
+ /* This device does not support hotplug */
return;
}
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- if (ACPI_FAILURE(status)) {
- printk ("Unable to determine bay status\n");
- spin_unlock_irqrestore(ap->lock, flags);
- return;
+ if (kobj && !is_dock_event) {
+ sprintf(event_string, "BAY_EVENT=%d", event);
+ kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
}
+ spin_lock_irqsave(ap->lock, flags);
+
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event");
- if (!sta) {
- /* Device has been unplugged */
- if (dev)
- dev->flags |= ATA_DFLAG_DETACH;
- else {
- struct ata_link *tlink;
- struct ata_device *tdev;
-
- ata_port_for_each_link(tlink, ap) {
- ata_link_for_each_dev(tdev, tlink) {
- tdev->flags |=
- ATA_DFLAG_DETACH;
- }
- }
- }
- ata_port_schedule_eh(ap);
- wait = 1;
- } else {
+
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Unable to determine bay status\n");
+ break;
+ }
+
+ if (sta) {
ata_ehi_hotplugged(ehi);
ata_port_freeze(ap);
+ } else {
+ /* The device has gone - unplug it */
+ ata_acpi_detach_device(ap, dev);
+ wait = 1;
}
+ break;
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ ata_ehi_push_desc(ehi, "ACPI event");
+
+ if (!is_dock_event)
+ break;
+
+ /* undock event - immediate unplug */
+ ata_acpi_detach_device(ap, dev);
+ wait = 1;
+ break;
}
spin_unlock_irqrestore(ap->lock, flags);
if (wait)
ata_port_wait_eh(ap);
+}
- if (dev) {
- if (dev->sdev)
- kobj = &dev->sdev->sdev_gendev.kobj;
- } else
- kobj = &ap->dev->kobj;
+static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_device *dev = data;
- if (kobj) {
- sprintf(event_string, "BAY_EVENT=%d", event);
- kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
- }
+ ata_acpi_handle_hotplug(NULL, dev, event, 1);
+}
+
+static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
+{
+ struct ata_port *ap = data;
+
+ ata_acpi_handle_hotplug(ap, NULL, event, 1);
}
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_device *dev = data;
- ata_acpi_handle_hotplug(NULL, dev, event);
+ ata_acpi_handle_hotplug(NULL, dev, event, 0);
}
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_port *ap = data;
- ata_acpi_handle_hotplug(ap, NULL, event);
+ ata_acpi_handle_hotplug(ap, NULL, event, 0);
}
/**
@@ -252,7 +278,7 @@ void ata_acpi_associate(struct ata_host
ata_acpi_ap_notify, ap);
/* we might be on a docking station */
register_hotplug_dock_device(ap->acpi_handle,
- ata_acpi_ap_notify, ap);
+ ata_acpi_ap_notify_dock, ap);
}
for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -264,7 +290,7 @@ void ata_acpi_associate(struct ata_host
ata_acpi_dev_notify, dev);
/* we might be on a docking station */
register_hotplug_dock_device(dev->acpi_handle,
- ata_acpi_dev_notify, dev);
+ ata_acpi_dev_notify_dock, dev);
}
}
}
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 13:58 ` Holger Macht
@ 2008-05-20 14:00 ` Matthew Garrett
2008-05-21 22:26 ` Andrew Morton
1 sibling, 0 replies; 28+ messages in thread
From: Matthew Garrett @ 2008-05-20 14:00 UTC (permalink / raw)
To: Tejun Heo, linux-ide, Jeff Garzik, linux-acpi, linux-kernel
On Tue, May 20, 2008 at 03:58:30PM +0200, Holger Macht wrote:
> Handle bay devices in dock stations
>
> * Differentiate between bay devices in dock stations and others:
>
> - When an ACPI_NOTIFY_EJECT_REQUEST appears, just signal uevent to
> userspace (that is when the optional eject button on a bay device is
> pressed/pulled) giving the possibility to unmount file systems and to
> clean up. Also, only send uevent in case we get an EJECT_REQUEST
> without doing anything else. In other cases, you'll get an add/remove
> event because libata attaches/detaches the device.
>
> - In case of a dock event, which in turn signals an
> ACPI_NOTIFY_EJECT_REQUEST, immediately detach the device, because it
> may already have been gone
>
> * In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
> the device has been plugged or unplugged. If plugged, hotplug it, if
> unplugged, just signal event to userspace
> (initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
>
> Signed-off-by: Holger Macht <hmacht@suse.de>
As long as this fixes the hang on dock removal, this looks good to me.
Acked-by: Matthew Garrett <mjg@redhat.com>
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH] Fixups to ATA ACPI hotplug
2008-05-20 13:58 ` Holger Macht
2008-05-20 14:00 ` Matthew Garrett
@ 2008-05-21 22:26 ` Andrew Morton
1 sibling, 0 replies; 28+ messages in thread
From: Andrew Morton @ 2008-05-21 22:26 UTC (permalink / raw)
To: Holger Macht; +Cc: mjg59, htejun, linux-ide, jeff, linux-acpi, linux-kernel
On Tue, 20 May 2008 15:58:30 +0200
Holger Macht <hmacht@suse.de> wrote:
> On Tue 20. May - 14:22:17, Matthew Garrett wrote:
> > On Tue, May 20, 2008 at 03:18:32PM +0200, Holger Macht wrote:
> >
> > > + if (kobj && !is_dock_event) {
> > > + sprintf(event_string, "BAY_EVENT=%d", event);
> > > + kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
> >
> > I think we want to do the _EJ0 checking before this, otherwise we'll
> > generate two uevents for the same removal on some hardware. Otherwise,
> > looks good.
>
> So once again:
>
> Handle bay devices in dock stations
>
> * Differentiate between bay devices in dock stations and others:
>
> - When an ACPI_NOTIFY_EJECT_REQUEST appears, just signal uevent to
> userspace (that is when the optional eject button on a bay device is
> pressed/pulled) giving the possibility to unmount file systems and to
> clean up. Also, only send uevent in case we get an EJECT_REQUEST
> without doing anything else. In other cases, you'll get an add/remove
> event because libata attaches/detaches the device.
>
> - In case of a dock event, which in turn signals an
> ACPI_NOTIFY_EJECT_REQUEST, immediately detach the device, because it
> may already have been gone
>
> * In case of an ACPI_NOTIFY_DEVICE/BUS_CHECK, evaluate _STA to check if
> the device has been plugged or unplugged. If plugged, hotplug it, if
> unplugged, just signal event to userspace
> (initial patch by Matthew Garrett <mjg59@srcf.ucam.org>)
>
> Signed-off-by: Holger Macht <hmacht@suse.de>
> ---
>
> --- linux-2.6.25/drivers/ata/libata-acpi.c.orig 2008-05-20 13:25:50.000000000 +0200
> +++ linux-2.6.25/drivers/ata/libata-acpi.c 2008-05-20 15:56:38.000000000 +0200
> @@ -118,8 +118,25 @@ static void ata_acpi_associate_ide_port(
> ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
> }
>
> +static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
> +{
> + if (dev)
> + dev->flags |= ATA_DFLAG_DETACH;
> + else {
> + struct ata_link *tlink;
> + struct ata_device *tdev;
> +
> + ata_port_for_each_link(tlink, ap)
> + ata_link_for_each_dev(tdev, tlink)
> + tdev->flags |= ATA_DFLAG_DETACH;
Looks odd. I guess this:
--- a/drivers/ata/libata-acpi.c~ata-acpi-hotplug-handle-bay-devices-in-dock-stations-cleanup
+++ a/drivers/ata/libata-acpi.c
@@ -128,7 +128,7 @@ static void ata_acpi_detach_device(struc
ata_port_for_each_link(tlink, ap)
ata_link_for_each_dev(tdev, tlink)
- tdev->flags |= ATA_DFLAG_DETACH;
+ tdev->flags |= ATA_DFLAG_DETACH;
}
ata_port_freeze(ap);
_
was intended.
> + }
> +
> + ata_port_freeze(ap);
> + ata_port_schedule_eh(ap);
> +}
> +
> static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
> - *dev, u32 event)
> + *dev, u32 event, int is_dock_event)
> {
> char event_string[12];
> char *envp[] = { event_string, NULL };
> @@ -135,83 +152,92 @@ static void ata_acpi_handle_hotplug(stru
> ap = dev->link->ap;
> ehi = &ap->link.eh_info;
>
> - spin_lock_irqsave(ap->lock, flags);
> -
> - if (dev)
> + if (dev) {
> + if (dev->sdev)
> + kobj = &dev->sdev->sdev_gendev.kobj;
> handle = dev->acpi_handle;
> - else
> + } else {
> + kobj = &ap->dev->kobj;
> handle = ap->acpi_handle;
> + }
>
> status = acpi_get_handle(handle, "_EJ0", &tmphandle);
> if (ACPI_FAILURE(status)) {
> - /* This device is not ejectable */
> - spin_unlock_irqrestore(ap->lock, flags);
> + /* This device does not support hotplug */
> return;
> }
>
> - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
> - if (ACPI_FAILURE(status)) {
> - printk ("Unable to determine bay status\n");
> - spin_unlock_irqrestore(ap->lock, flags);
> - return;
> + if (kobj && !is_dock_event) {
> + sprintf(event_string, "BAY_EVENT=%d", event);
> + kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
> }
>
> + spin_lock_irqsave(ap->lock, flags);
Wow, lots of stuff happening under spinlock here, but it all looks OK to me.
> switch (event) {
> case ACPI_NOTIFY_BUS_CHECK:
> case ACPI_NOTIFY_DEVICE_CHECK:
> ata_ehi_push_desc(ehi, "ACPI event");
> - if (!sta) {
> - /* Device has been unplugged */
> - if (dev)
> - dev->flags |= ATA_DFLAG_DETACH;
> - else {
> - struct ata_link *tlink;
> - struct ata_device *tdev;
> -
> - ata_port_for_each_link(tlink, ap) {
> - ata_link_for_each_dev(tdev, tlink) {
> - tdev->flags |=
> - ATA_DFLAG_DETACH;
> - }
> - }
The old code was less odd ;)
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2008-05-21 22:26 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-05 22:33 2.6.25 semantic change in bay handling? Matthew Garrett
2008-05-06 8:13 ` Holger Macht
2008-05-06 8:21 ` Matthew Garrett
2008-05-06 8:40 ` Tejun Heo
2008-05-06 8:46 ` Matthew Garrett
2008-05-06 8:53 ` Tejun Heo
2008-05-06 9:17 ` Matthew Garrett
2008-05-06 11:21 ` Holger Macht
2008-05-06 11:31 ` Matthew Garrett
2008-05-06 17:27 ` Holger Macht
2008-05-06 17:48 ` Matthew Garrett
2008-05-06 18:36 ` Holger Macht
2008-05-06 18:48 ` Matthew Garrett
2008-05-06 22:06 ` Holger Macht
2008-05-06 9:29 ` Holger Macht
2008-05-06 9:39 ` Matthew Garrett
2008-05-06 9:26 ` Holger Macht
2008-05-06 9:36 ` Matthew Garrett
2008-05-19 16:29 ` [PATCH] Fixups to ATA ACPI hotplug Matthew Garrett
2008-05-20 7:44 ` Holger Macht
2008-05-20 10:20 ` Matthew Garrett
2008-05-20 13:18 ` Holger Macht
2008-05-20 13:22 ` Matthew Garrett
2008-05-20 13:58 ` Holger Macht
2008-05-20 14:00 ` Matthew Garrett
2008-05-21 22:26 ` Andrew Morton
2008-05-20 8:49 ` Holger Macht
2008-05-06 8:40 ` 2.6.25 semantic change in bay handling? Holger Macht
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).