* [PATCH] shutdown processing
@ 2006-02-15 19:46 Randy Dunlap
2006-02-16 8:58 ` Stefan Richter
0 siblings, 1 reply; 6+ messages in thread
From: Randy Dunlap @ 2006-02-15 19:46 UTC (permalink / raw)
To: scsi; +Cc: ide
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add ability for SCSI drivers to invoke a shutdown method.
This allows drivers to make drives safe for shutdown/poweroff,
for example. Some drives need this to prevent possible problems.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
drivers/scsi/ahci.c | 1 +
drivers/scsi/ata_piix.c | 1 +
drivers/scsi/libata-core.c | 23 +++++++++++++++++++++++
drivers/scsi/libata-scsi.c | 8 ++++++++
drivers/scsi/scsi_sysfs.c | 16 ++++++++++++++++
include/linux/libata.h | 2 ++
include/scsi/scsi_host.h | 1 +
7 files changed, 52 insertions(+)
--- linux-2616-rc3-standby.orig/drivers/scsi/libata-scsi.c
+++ linux-2616-rc3-standby/drivers/scsi/libata-scsi.c
@@ -412,6 +412,14 @@ int ata_scsi_device_suspend(struct scsi_
return ata_device_suspend(ap, dev);
}
+int ata_scsi_device_shutdown(struct scsi_device *sdev)
+{
+ struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+ struct ata_device *dev = &ap->device[sdev->id];
+
+ return ata_device_shutdown(ap, dev);
+}
+
/**
* ata_to_sense_error - convert ATA error to SCSI error
* @id: ATA device number
--- linux-2616-rc3-standby.orig/drivers/scsi/libata-core.c
+++ linux-2616-rc3-standby/drivers/scsi/libata-core.c
@@ -4315,6 +4315,27 @@ int ata_device_suspend(struct ata_port *
return 0;
}
+/**
+ * ata_device_shutdown - send Standby Immediate command to drive
+ * @ap: target ata_port
+ * @dev: target device on the ata_port
+ *
+ * This command makes it safe to power-off a drive.
+ * Otherwise the heads may be flying at the wrong place
+ * when the power is removed.
+ */
+int ata_device_shutdown(struct ata_port *ap, struct ata_device *dev)
+{
+
+ if (!ata_dev_present(dev))
+ return 0;
+
+ ata_standby_drive(ap, dev);
+ ap->flags |= ATA_FLAG_SUSPENDED;
+
+ return 0;
+}
+
int ata_port_start (struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
@@ -5190,5 +5211,7 @@ EXPORT_SYMBOL_GPL(ata_pci_device_resume)
EXPORT_SYMBOL_GPL(ata_device_suspend);
EXPORT_SYMBOL_GPL(ata_device_resume);
+EXPORT_SYMBOL_GPL(ata_device_shutdown);
EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
+EXPORT_SYMBOL_GPL(ata_scsi_device_shutdown);
--- linux-2616-rc3-standby.orig/include/linux/libata.h
+++ linux-2616-rc3-standby/include/linux/libata.h
@@ -454,8 +454,10 @@ extern int ata_scsi_release(struct Scsi_
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
extern int ata_scsi_device_resume(struct scsi_device *);
extern int ata_scsi_device_suspend(struct scsi_device *);
+extern int ata_scsi_device_shutdown(struct scsi_device *);
extern int ata_device_resume(struct ata_port *, struct ata_device *);
extern int ata_device_suspend(struct ata_port *, struct ata_device *);
+extern int ata_device_shutdown(struct ata_port *, struct ata_device *);
extern int ata_ratelimit(void);
/*
--- linux-2616-rc3-standby.orig/drivers/scsi/scsi_sysfs.c
+++ linux-2616-rc3-standby/drivers/scsi/scsi_sysfs.c
@@ -295,11 +295,27 @@ static int scsi_bus_resume(struct device
return err;
}
+static void scsi_bus_shutdown(struct device * dev)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_host_template *sht = sdev->host->hostt;
+ int err;
+
+ err = scsi_device_quiesce(sdev);
+ if (err)
+ printk(KERN_DEBUG "%s: error (0x%x) during shutdown\n",
+ __FUNCTION__, err);
+
+ if (sht->shutdown)
+ sht->shutdown(sdev);
+}
+
struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
.suspend = scsi_bus_suspend,
.resume = scsi_bus_resume,
+ .shutdown = scsi_bus_shutdown,
};
int scsi_sysfs_register(void)
--- linux-2616-rc3-standby.orig/include/scsi/scsi_host.h
+++ linux-2616-rc3-standby/include/scsi/scsi_host.h
@@ -301,6 +301,7 @@ struct scsi_host_template {
*/
int (*resume)(struct scsi_device *);
int (*suspend)(struct scsi_device *);
+ int (*shutdown)(struct scsi_device *);
/*
* Name of proc directory
--- linux-2616-rc3-standby.orig/drivers/scsi/ahci.c
+++ linux-2616-rc3-standby/drivers/scsi/ahci.c
@@ -214,6 +214,7 @@ static struct scsi_host_template ahci_sh
.dma_boundary = AHCI_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
+ .shutdown = ata_scsi_device_shutdown,
};
static const struct ata_port_operations ahci_ops = {
--- linux-2616-rc3-standby.orig/drivers/scsi/ata_piix.c
+++ linux-2616-rc3-standby/drivers/scsi/ata_piix.c
@@ -192,6 +192,7 @@ static struct scsi_host_template piix_sh
.bios_param = ata_std_bios_param,
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+ .shutdown = ata_scsi_device_shutdown,
};
static const struct ata_port_operations piix_pata_ops = {
---
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] shutdown processing
2006-02-15 19:46 [PATCH] shutdown processing Randy Dunlap
@ 2006-02-16 8:58 ` Stefan Richter
2006-02-16 18:40 ` Randy Dunlap
0 siblings, 1 reply; 6+ messages in thread
From: Stefan Richter @ 2006-02-16 8:58 UTC (permalink / raw)
To: Randy Dunlap; +Cc: scsi, ide
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add ability for SCSI drivers to invoke a shutdown method.
> This allows drivers to make drives safe for shutdown/poweroff,
> for example. Some drives need this to prevent possible problems.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Why are you calling these from SCSI? Wouldn't ahci_pci_driver.remove()
and piix_pci_driver.remove() be a proper place to perform what you are
doing in ata_device_shutdown?
[...]
> EXPORT_SYMBOL_GPL(ata_device_suspend);
> EXPORT_SYMBOL_GPL(ata_device_resume);
> +EXPORT_SYMBOL_GPL(ata_device_shutdown);
> EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
> EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
> +EXPORT_SYMBOL_GPL(ata_scsi_device_shutdown);
[...]
Side note: If you would prepare the host template in libata, you
wouldn't need to export these and other symbols. As was AFAIR discussed
by other people before, libata could certainly hide scsi_host_template
from ATA drivers entirely.
--
Stefan Richter
-=====-=-==- --=- =----
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] shutdown processing
2006-02-16 8:58 ` Stefan Richter
@ 2006-02-16 18:40 ` Randy Dunlap
2006-02-16 18:56 ` Stefan Richter
0 siblings, 1 reply; 6+ messages in thread
From: Randy Dunlap @ 2006-02-16 18:40 UTC (permalink / raw)
To: Stefan Richter; +Cc: linux-scsi, linux-ide
On Thu, 16 Feb 2006 09:58:33 +0100
Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
> Randy Dunlap wrote:
> > From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> >
> > Add ability for SCSI drivers to invoke a shutdown method.
> > This allows drivers to make drives safe for shutdown/poweroff,
> > for example. Some drives need this to prevent possible problems.
> >
> > Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Why are you calling these from SCSI? Wouldn't ahci_pci_driver.remove()
> and piix_pci_driver.remove() be a proper place to perform what you are
> doing in ata_device_shutdown?
Mostly to have the scsi_device pointers available.
I'll try your suggestion.
> [...]
> > EXPORT_SYMBOL_GPL(ata_device_suspend);
> > EXPORT_SYMBOL_GPL(ata_device_resume);
> > +EXPORT_SYMBOL_GPL(ata_device_shutdown);
> > EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
> > EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
> > +EXPORT_SYMBOL_GPL(ata_scsi_device_shutdown);
> [...]
>
> Side note: If you would prepare the host template in libata, you
> wouldn't need to export these and other symbols. As was AFAIR discussed
> by other people before, libata could certainly hide scsi_host_template
> from ATA drivers entirely.
OK. Thanks for your review and comments.
---
~Randy
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] shutdown processing
2006-02-16 18:40 ` Randy Dunlap
@ 2006-02-16 18:56 ` Stefan Richter
2006-02-16 19:12 ` Randy Dunlap
0 siblings, 1 reply; 6+ messages in thread
From: Stefan Richter @ 2006-02-16 18:56 UTC (permalink / raw)
To: Randy Dunlap; +Cc: linux-scsi, linux-ide
Randy Dunlap wrote:
> On Thu, 16 Feb 2006 09:58:33 +0100
> Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
>>Why are you calling these from SCSI? Wouldn't ahci_pci_driver.remove()
>>and piix_pci_driver.remove() be a proper place to perform what you are
>>doing in ata_device_shutdown?
>
> Mostly to have the scsi_device pointers available.
Note that roughly as long a scsi_device exists, SCSI high-level drivers
expect to be able to send commands to them. In particular, when
scsi_remove_device is called, (or scsi_remove_host, which calls
scsi_remove_device for all still existing devices of a host), the SCSI
high-level drivers' shutdwon methods get executed. Some of them send
SCSI commands. The upshot is, a SCSI low-level driver has to be able to
handle newly enqueued command while it is calling
scsi_remove_{device,host}. Moreover it must not block a SCSI host at
this moment.
IOW the most natural order for layers to shut down would be first SCSI,
then ATA. (But then, I don't really comprehend whether your shutdown
code would actually collide with that of the SCSI subsystem at all.)
--
Stefan Richter
-=====-=-==- --=- =----
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] shutdown processing
2006-02-16 18:56 ` Stefan Richter
@ 2006-02-16 19:12 ` Randy Dunlap
2006-02-17 19:15 ` Stefan Richter
0 siblings, 1 reply; 6+ messages in thread
From: Randy Dunlap @ 2006-02-16 19:12 UTC (permalink / raw)
To: Stefan Richter; +Cc: linux-scsi, linux-ide
On Thu, 16 Feb 2006 19:56:52 +0100
Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
> Randy Dunlap wrote:
> > On Thu, 16 Feb 2006 09:58:33 +0100
> > Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
> >>Why are you calling these from SCSI? Wouldn't ahci_pci_driver.remove()
> >>and piix_pci_driver.remove() be a proper place to perform what you are
> >>doing in ata_device_shutdown?
> >
> > Mostly to have the scsi_device pointers available.
>
> Note that roughly as long a scsi_device exists, SCSI high-level drivers
> expect to be able to send commands to them. In particular, when
> scsi_remove_device is called, (or scsi_remove_host, which calls
> scsi_remove_device for all still existing devices of a host), the SCSI
> high-level drivers' shutdwon methods get executed. Some of them send
> SCSI commands. The upshot is, a SCSI low-level driver has to be able to
> handle newly enqueued command while it is calling
> scsi_remove_{device,host}. Moreover it must not block a SCSI host at
> this moment.
>
> IOW the most natural order for layers to shut down would be first SCSI,
> then ATA. (But then, I don't really comprehend whether your shutdown
> code would actually collide with that of the SCSI subsystem at all.)
OK, now it seems like you just told me why I shouldn't use
the pci_driver.remove() interface. But thanks for your comments,
I do appreciate them and will dig deeper [into a twisty maze :].
anyone else care to comment on this?
---
~Randy
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] shutdown processing
2006-02-16 19:12 ` Randy Dunlap
@ 2006-02-17 19:15 ` Stefan Richter
0 siblings, 0 replies; 6+ messages in thread
From: Stefan Richter @ 2006-02-17 19:15 UTC (permalink / raw)
To: Randy Dunlap, Jeff Garzik; +Cc: linux-scsi, linux-ide
Randy Dunlap wrote:
> On Thu, 16 Feb 2006 19:56:52 +0100
> Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
...
>>Note that roughly as long a scsi_device exists, SCSI high-level drivers
>>expect to be able to send commands to them.
...
> OK, now it seems like you just told me why I shouldn't use
> the pci_driver.remove() interface.
:-) Really? Depends on what you are trying to solve. From what I
understood, the function you require does not interact with a scsi_device.
You could also have a look into scsi_host_template.slave_destroy. This
is called from SCSI core when a scsi_device is being removed. In
particular, it is called _after_ the upper SCSI layers finished all
their business with your device.
BTW, ata_scsi_release looks suspicious WRT what I said above. I see
ap->ops->port_disable(ap);
ata_host_remove(ap, 0);
there. Since libata apparently never uses scsi_remove_device,
ata_host_remove's call to scsi_remove_host will call scsi_remove_device
which will cause SCSI high-level drivers to run their shutdown methods.
It looks wrong to me to place something like ata_port_disable before
that, judging from what the comment at the definition of
ata_port_disable says.
Another suspicious code: ahci_remove_one calls free_irq before
ata_scsi_release.
I never looked at this code before, never even used it --- am I missing
something fundamental?
--
Stefan Richter
-=====-=-==- --=- =---=
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-02-17 19:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-15 19:46 [PATCH] shutdown processing Randy Dunlap
2006-02-16 8:58 ` Stefan Richter
2006-02-16 18:40 ` Randy Dunlap
2006-02-16 18:56 ` Stefan Richter
2006-02-16 19:12 ` Randy Dunlap
2006-02-17 19:15 ` Stefan Richter
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).