* [PATCH 1/3] sd: fix return value of sd_sync_cache()
@ 2007-03-20 15:07 Tejun Heo
2007-03-20 15:13 ` [PATCH 2/3] sd: implement START/STOP management Tejun Heo
0 siblings, 1 reply; 27+ messages in thread
From: Tejun Heo @ 2007-03-20 15:07 UTC (permalink / raw)
To: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
sd_sync_cache() should return -errno on error, fix it.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/sd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: work/drivers/scsi/sd.c
===================================================================
--- work.orig/drivers/scsi/sd.c
+++ work/drivers/scsi/sd.c
@@ -817,7 +817,9 @@ static int sd_sync_cache(struct scsi_dev
scsi_print_sense_hdr("sd", &sshdr);
}
- return res;
+ if (res)
+ return -EIO;
+ return 0;
}
static int sd_issue_flush(struct device *dev, sector_t *error_sector)
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 2/3] sd: implement START/STOP management
2007-03-20 15:07 [PATCH 1/3] sd: fix return value of sd_sync_cache() Tejun Heo
@ 2007-03-20 15:13 ` Tejun Heo
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
` (2 more replies)
0 siblings, 3 replies; 27+ messages in thread
From: Tejun Heo @ 2007-03-20 15:13 UTC (permalink / raw)
To: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
Implement SBC START/STOP management. sdev->mange_start_stop is added.
When it's set to one, sd STOPs the device on suspend and shutdown and
STARTs it on resume. sdev->manage_start_stop defaults is in sdev
instead of scsi_disk cdev to allow ->slave_config() override the
default configuration but is exported under scsi_disk sysfs node as
sdev->allow_restart is.
When manage_start_stop is zero (the default value), this patch doesn't
introduce any behavior change.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/scsi_sysfs.c | 31 +++++++++++--
drivers/scsi/sd.c | 102 +++++++++++++++++++++++++++++++++++++++++++++
include/scsi/scsi_device.h | 1
3 files changed, 130 insertions(+), 4 deletions(-)
Index: work/drivers/scsi/sd.c
===================================================================
--- work.orig/drivers/scsi/sd.c
+++ work/drivers/scsi/sd.c
@@ -142,6 +142,8 @@ static void sd_rw_intr(struct scsi_cmnd
static int sd_probe(struct device *);
static int sd_remove(struct device *);
static void sd_shutdown(struct device *dev);
+static int sd_suspend(struct device *dev, pm_message_t state);
+static int sd_resume(struct device *dev);
static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
static int sd_issue_flush(struct device *, sector_t *);
@@ -206,6 +208,20 @@ static ssize_t sd_store_cache_type(struc
return count;
}
+static ssize_t sd_store_manage_start_stop(struct class_device *cdev,
+ const char *buf, size_t count)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(cdev);
+ struct scsi_device *sdp = sdkp->device;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ sdp->manage_start_stop = simple_strtoul(buf, NULL, 10);
+
+ return count;
+}
+
static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
size_t count)
{
@@ -238,6 +254,14 @@ static ssize_t sd_show_fua(struct class_
return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
}
+static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(cdev);
+ struct scsi_device *sdp = sdkp->device;
+
+ return snprintf(buf, 20, "%u\n", sdp->manage_start_stop);
+}
+
static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(cdev);
@@ -251,6 +275,8 @@ static struct class_device_attribute sd_
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
__ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
sd_store_allow_restart),
+ __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop,
+ sd_store_manage_start_stop),
__ATTR_NULL,
};
@@ -267,6 +293,8 @@ static struct scsi_driver sd_template =
.name = "sd",
.probe = sd_probe,
.remove = sd_remove,
+ .suspend = sd_suspend,
+ .resume = sd_resume,
.shutdown = sd_shutdown,
},
.rescan = sd_rescan,
@@ -1776,6 +1804,32 @@ static void scsi_disk_release(struct cla
kfree(sdkp);
}
+static int sd_start_stop_device(struct scsi_device *sdp, int start)
+{
+ unsigned char cmd[6] = { START_STOP }; /* START_VALID */
+ struct scsi_sense_hdr sshdr;
+ int res;
+
+ if (start)
+ cmd[4] |= 1; /* START */
+
+ if (!scsi_device_online(sdp))
+ return -ENODEV;
+
+ res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
+ SD_TIMEOUT, SD_MAX_RETRIES);
+ if (res) {
+ printk(KERN_WARNING "FAILED\n status = %x, message = %02x, "
+ "host = %d, driver = %02x\n ",
+ status_byte(res), msg_byte(res),
+ host_byte(res), driver_byte(res));
+ if (driver_byte(res) & DRIVER_SENSE)
+ scsi_print_sense_hdr("sd", &sshdr);
+ }
+
+ return res;
+}
+
/*
* Send a SYNCHRONIZE CACHE instruction down to the device through
* the normal SCSI command structure. Wait for the command to
@@ -1794,9 +1848,57 @@ static void sd_shutdown(struct device *d
sdkp->disk->disk_name);
sd_sync_cache(sdp);
}
+
+ if (system_state != SYSTEM_RESTART && sdp->manage_start_stop) {
+ printk(KERN_NOTICE "Stopping disk %s: \n",
+ sdkp->disk->disk_name);
+ sd_start_stop_device(sdp, 0);
+ }
+
scsi_disk_put(sdkp);
}
+static int sd_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct scsi_device *sdp = to_scsi_device(dev);
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+ int ret;
+
+ if (!sdkp)
+ return 0; /* this can happen */
+
+ if (sdkp->WCE) {
+ printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
+ sdkp->disk->disk_name);
+ ret = sd_sync_cache(sdp);
+ if (ret)
+ return ret;
+ }
+
+ if (mesg.event == PM_EVENT_SUSPEND && sdp->manage_start_stop) {
+ printk(KERN_NOTICE "Stopping disk %s: \n",
+ sdkp->disk->disk_name);
+ ret = sd_start_stop_device(sdp, 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sd_resume(struct device *dev)
+{
+ struct scsi_device *sdp = to_scsi_device(dev);
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+
+ if (!sdp->manage_start_stop)
+ return 0;
+
+ printk(KERN_NOTICE "Starting disk %s: \n", sdkp->disk->disk_name);
+
+ return sd_start_stop_device(sdp, 1);
+}
+
/**
* init_sd - entry point for this driver (both when built in or when
* a module).
Index: work/include/scsi/scsi_device.h
===================================================================
--- work.orig/include/scsi/scsi_device.h
+++ work/include/scsi/scsi_device.h
@@ -119,6 +119,7 @@ struct scsi_device {
unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
unsigned no_start_on_add:1; /* do not issue start on add */
unsigned allow_restart:1; /* issue START_UNIT in error handler */
+ unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */
unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
unsigned select_no_atn:1;
unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
Index: work/drivers/scsi/scsi_sysfs.c
===================================================================
--- work.orig/drivers/scsi/scsi_sysfs.c
+++ work/drivers/scsi/scsi_sysfs.c
@@ -278,6 +278,7 @@ static int scsi_bus_match(struct device
static int scsi_bus_suspend(struct device * dev, pm_message_t state)
{
+ struct device_driver *drv = dev->driver;
struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_host_template *sht = sdev->host->hostt;
int err;
@@ -286,23 +287,45 @@ static int scsi_bus_suspend(struct devic
if (err)
return err;
- if (sht->suspend)
+ /* call HLD suspend first */
+ if (drv && drv->suspend) {
+ err = drv->suspend(dev, state);
+ if (err)
+ return err;
+ }
+
+ /* then, call host suspend */
+ if (sht->suspend) {
err = sht->suspend(sdev, state);
+ if (err) {
+ if (drv && drv->resume)
+ drv->resume(dev);
+ return err;
+ }
+ }
- return err;
+ return 0;
}
static int scsi_bus_resume(struct device * dev)
{
+ struct device_driver *drv = dev->driver;
struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_host_template *sht = sdev->host->hostt;
- int err = 0;
+ int err = 0, err2 = 0;
+ /* call host resume first */
if (sht->resume)
err = sht->resume(sdev);
+ /* then, call HLD resume */
+ if (drv && drv->resume)
+ err2 = drv->resume(dev);
+
scsi_device_resume(sdev);
- return err;
+
+ /* favor LLD failure */
+ return err ? err : err2;;
}
struct bus_type scsi_bus_type = {
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop
2007-03-20 15:13 ` [PATCH 2/3] sd: implement START/STOP management Tejun Heo
@ 2007-03-20 15:25 ` Tejun Heo
2007-03-20 15:29 ` Christoph Hellwig
` (2 more replies)
2007-03-20 16:58 ` [PATCH 2/3] sd: implement START/STOP management James Bottomley
2007-03-20 17:58 ` Douglas Gilbert
2 siblings, 3 replies; 27+ messages in thread
From: Tejun Heo @ 2007-03-20 15:25 UTC (permalink / raw)
To: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
Reimplement suspend/resume support using sdev->manage_start_stop.
* Device suspend/resume is now SCSI layer's responsibility and the
code is simplified a lot.
* DPM is dropped. This also simplifies code a lot. Suspend/resume
status is port-wide now.
* ata_scsi_device_suspend/resume() and ata_dev_ready() removed.
* Resume now has to wait for disk to spin up before proceeding. I
couldn't find easy way out as libata is in EH waiting for the
disk to be ready and sd is waiting for EH to complete to issue
START_STOP.
* sdev->manage_start_stop is set to 1 in ata_scsi_slave_config().
This fixes spindown on shutdown and suspend-to-disk.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/ahci.c | 4
drivers/ata/ata_generic.c | 6 -
drivers/ata/ata_piix.c | 4
drivers/ata/libata-core.c | 39 ------
drivers/ata/libata-eh.c | 237 ----------------------------------------
drivers/ata/libata-scsi.c | 129 ---------------------
drivers/ata/pata_ali.c | 4
drivers/ata/pata_amd.c | 4
drivers/ata/pata_atiixp.c | 4
drivers/ata/pata_cmd640.c | 2
drivers/ata/pata_cmd64x.c | 4
drivers/ata/pata_cs5520.c | 4
drivers/ata/pata_cs5530.c | 4
drivers/ata/pata_cs5535.c | 4
drivers/ata/pata_cypress.c | 4
drivers/ata/pata_efar.c | 4
drivers/ata/pata_hpt366.c | 4
drivers/ata/pata_hpt3x3.c | 4
drivers/ata/pata_it8213.c | 4
drivers/ata/pata_it821x.c | 4
drivers/ata/pata_ixp4xx_cf.c | 2
drivers/ata/pata_jmicron.c | 4
drivers/ata/pata_marvell.c | 4
drivers/ata/pata_mpc52xx.c | 4
drivers/ata/pata_mpiix.c | 4
drivers/ata/pata_netcell.c | 4
drivers/ata/pata_ns87410.c | 4
drivers/ata/pata_oldpiix.c | 4
drivers/ata/pata_opti.c | 4
drivers/ata/pata_optidma.c | 4
drivers/ata/pata_pdc202xx_old.c | 4
drivers/ata/pata_radisys.c | 4
drivers/ata/pata_rz1000.c | 6 -
drivers/ata/pata_sc1200.c | 4
drivers/ata/pata_scc.c | 4
drivers/ata/pata_serverworks.c | 4
drivers/ata/pata_sil680.c | 4
drivers/ata/pata_sis.c | 4
drivers/ata/pata_triflex.c | 4
drivers/ata/pata_via.c | 4
drivers/ata/sata_inic162x.c | 4
drivers/ata/sata_nv.c | 8 -
drivers/ata/sata_sil.c | 4
drivers/ata/sata_sil24.c | 4
include/linux/libata.h | 14 --
45 files changed, 14 insertions(+), 573 deletions(-)
Index: work/drivers/ata/ahci.c
===================================================================
--- work.orig/drivers/ata/ahci.c
+++ work/drivers/ata/ahci.c
@@ -243,10 +243,6 @@ static struct scsi_host_template ahci_sh
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations ahci_ops = {
Index: work/drivers/ata/ata_generic.c
===================================================================
--- work.orig/drivers/ata/ata_generic.c
+++ work/drivers/ata/ata_generic.c
@@ -83,7 +83,7 @@ static int generic_set_mode(struct ata_p
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
@@ -119,10 +119,6 @@ static struct scsi_host_template generic
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations generic_port_ops = {
Index: work/drivers/ata/ata_piix.c
===================================================================
--- work.orig/drivers/ata/ata_piix.c
+++ work/drivers/ata/ata_piix.c
@@ -275,10 +275,6 @@ static struct scsi_host_template piix_sh
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations piix_pata_ops = {
Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -2607,7 +2607,7 @@ int ata_do_set_mode(struct ata_port *ap,
dev = &ap->device[i];
/* don't update suspended devices' xfer mode */
- if (!ata_dev_ready(dev))
+ if (!ata_dev_enabled(dev))
continue;
rc = ata_dev_set_mode(dev);
@@ -5504,37 +5504,11 @@ static int ata_host_request_pm(struct at
*/
int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
{
- int i, j, rc;
+ int rc;
rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
- if (rc)
- goto fail;
-
- /* EH is quiescent now. Fail if we have any ready device.
- * This happens if hotplug occurs between completion of device
- * suspension and here.
- */
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- for (j = 0; j < ATA_MAX_DEVICES; j++) {
- struct ata_device *dev = &ap->device[j];
-
- if (ata_dev_ready(dev)) {
- ata_port_printk(ap, KERN_WARNING,
- "suspend failed, device %d "
- "still active\n", dev->devno);
- rc = -EBUSY;
- goto fail;
- }
- }
- }
-
- host->dev->power.power_state = mesg;
- return 0;
-
- fail:
- ata_host_resume(host);
+ if (rc == 0)
+ host->dev->power.power_state = mesg;
return rc;
}
@@ -6488,11 +6462,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter
EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
#endif /* CONFIG_PCI */
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
-EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
-#endif /* CONFIG_PM */
-
EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
EXPORT_SYMBOL_GPL(ata_port_abort);
Index: work/drivers/ata/libata-eh.c
===================================================================
--- work.orig/drivers/ata/libata-eh.c
+++ work/drivers/ata/libata-eh.c
@@ -55,29 +55,12 @@ static void ata_eh_finish(struct ata_por
#ifdef CONFIG_PM
static void ata_eh_handle_port_suspend(struct ata_port *ap);
static void ata_eh_handle_port_resume(struct ata_port *ap);
-static int ata_eh_suspend(struct ata_port *ap,
- struct ata_device **r_failed_dev);
-static void ata_eh_prep_resume(struct ata_port *ap);
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
#else /* CONFIG_PM */
static void ata_eh_handle_port_suspend(struct ata_port *ap)
{ }
static void ata_eh_handle_port_resume(struct ata_port *ap)
{ }
-
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- return 0;
-}
-
-static void ata_eh_prep_resume(struct ata_port *ap)
-{ }
-
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- return 0;
-}
#endif /* CONFIG_PM */
static void ata_ering_record(struct ata_ering *ering, int is_io,
@@ -1757,7 +1740,7 @@ static int ata_eh_revalidate_and_attach(
if (ehc->i.flags & ATA_EHI_DID_RESET)
readid_flags |= ATA_READID_POSTRESET;
- if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
+ if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
if (ata_port_offline(ap)) {
rc = -EIO;
break;
@@ -1821,166 +1804,6 @@ static int ata_eh_revalidate_and_attach(
return rc;
}
-#ifdef CONFIG_PM
-/**
- * ata_eh_suspend - handle suspend EH action
- * @ap: target host port
- * @r_failed_dev: result parameter to indicate failing device
- *
- * Handle suspend EH action. Disk devices are spinned down and
- * other types of devices are just marked suspended. Once
- * suspended, no EH action to the device is allowed until it is
- * resumed.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise
- */
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- struct ata_device *dev;
- int i, rc = 0;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned long flags;
- unsigned int action, err_mask;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
- continue;
-
- WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
-
- ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
-
- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
- /* flush cache */
- rc = ata_flush_cache(dev);
- if (rc)
- break;
-
- /* spin down */
- err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
- if (err_mask) {
- ata_dev_printk(dev, KERN_ERR, "failed to "
- "spin down (err_mask=0x%x)\n",
- err_mask);
- rc = -EIO;
- break;
- }
- }
-
- spin_lock_irqsave(ap->lock, flags);
- dev->flags |= ATA_DFLAG_SUSPENDED;
- spin_unlock_irqrestore(ap->lock, flags);
-
- ata_eh_done(ap, dev, ATA_EH_SUSPEND);
- }
-
- if (rc)
- *r_failed_dev = dev;
-
- DPRINTK("EXIT\n");
- return rc;
-}
-
-/**
- * ata_eh_prep_resume - prep for resume EH action
- * @ap: target host port
- *
- * Clear SUSPENDED in preparation for scheduled resume actions.
- * This allows other parts of EH to access the devices being
- * resumed.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- */
-static void ata_eh_prep_resume(struct ata_port *ap)
-{
- struct ata_device *dev;
- unsigned long flags;
- int i;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned int action;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
- continue;
-
- spin_lock_irqsave(ap->lock, flags);
- dev->flags &= ~ATA_DFLAG_SUSPENDED;
- spin_unlock_irqrestore(ap->lock, flags);
- }
-
- DPRINTK("EXIT\n");
-}
-
-/**
- * ata_eh_resume - handle resume EH action
- * @ap: target host port
- * @r_failed_dev: result parameter to indicate failing device
- *
- * Handle resume EH action. Target devices are already reset and
- * revalidated. Spinning up is the only operation left.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise
- */
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- struct ata_device *dev;
- int i, rc = 0;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned int action, err_mask;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
- continue;
-
- ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
-
- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
- err_mask = ata_do_simple_cmd(dev,
- ATA_CMD_IDLEIMMEDIATE);
- if (err_mask) {
- ata_dev_printk(dev, KERN_ERR, "failed to "
- "spin up (err_mask=0x%x)\n",
- err_mask);
- rc = -EIO;
- break;
- }
- }
-
- ata_eh_done(ap, dev, ATA_EH_RESUME);
- }
-
- if (rc)
- *r_failed_dev = dev;
-
- DPRINTK("EXIT\n");
- return 0;
-}
-#endif /* CONFIG_PM */
-
static int ata_port_nr_enabled(struct ata_port *ap)
{
int i, cnt = 0;
@@ -2006,17 +1829,6 @@ static int ata_eh_skip_recovery(struct a
struct ata_eh_context *ehc = &ap->eh_context;
int i;
- /* skip if all possible devices are suspended */
- for (i = 0; i < ata_port_max_devices(ap); i++) {
- struct ata_device *dev = &ap->device[i];
-
- if (!(dev->flags & ATA_DFLAG_SUSPENDED))
- break;
- }
-
- if (i == ata_port_max_devices(ap))
- return 1;
-
/* thaw frozen port, resume link and recover failed devices */
if ((ap->pflags & ATA_PFLAG_FROZEN) ||
(ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
@@ -2096,9 +1908,6 @@ static int ata_eh_recover(struct ata_por
if (ap->pflags & ATA_PFLAG_UNLOADING)
goto out;
- /* prep for resume */
- ata_eh_prep_resume(ap);
-
/* skip EH if possible. */
if (ata_eh_skip_recovery(ap))
ehc->i.action = 0;
@@ -2126,11 +1935,6 @@ static int ata_eh_recover(struct ata_por
if (rc)
goto dev_fail;
- /* resume devices */
- rc = ata_eh_resume(ap, &dev);
- if (rc)
- goto dev_fail;
-
/* configure transfer mode if necessary */
if (ehc->i.flags & ATA_EHI_SETMODE) {
rc = ata_set_mode(ap, &dev);
@@ -2139,11 +1943,6 @@ static int ata_eh_recover(struct ata_por
ehc->i.flags &= ~ATA_EHI_SETMODE;
}
- /* suspend devices */
- rc = ata_eh_suspend(ap, &dev);
- if (rc)
- goto dev_fail;
-
goto out;
dev_fail:
@@ -2339,22 +2138,13 @@ static void ata_eh_handle_port_suspend(s
*
* Resume @ap.
*
- * This function also waits upto one second until all devices
- * hanging off this port requests resume EH action. This is to
- * prevent invoking EH and thus reset multiple times on resume.
- *
- * On DPM resume, where some of devices might not be resumed
- * together, this may delay port resume upto one second, but such
- * DPM resumes are rare and 1 sec delay isn't too bad.
- *
* LOCKING:
* Kernel thread context (may sleep).
*/
static void ata_eh_handle_port_resume(struct ata_port *ap)
{
- unsigned long timeout;
unsigned long flags;
- int i, rc = 0;
+ int rc = 0;
/* are we resuming? */
spin_lock_irqsave(ap->lock, flags);
@@ -2365,31 +2155,12 @@ static void ata_eh_handle_port_resume(st
}
spin_unlock_irqrestore(ap->lock, flags);
- /* spurious? */
- if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
- goto done;
+ WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
if (ap->ops->port_resume)
rc = ap->ops->port_resume(ap);
- /* give devices time to request EH */
- timeout = jiffies + HZ; /* 1s max */
- while (1) {
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- struct ata_device *dev = &ap->device[i];
- unsigned int action = ata_eh_dev_action(dev);
-
- if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
- !(action & ATA_EH_RESUME))
- break;
- }
-
- if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
- break;
- msleep(10);
- }
-
- done:
+ /* report result */
spin_lock_irqsave(ap->lock, flags);
ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
if (ap->pm_result) {
Index: work/drivers/ata/libata-scsi.c
===================================================================
--- work.orig/drivers/ata/libata-scsi.c
+++ work/drivers/ata/libata-scsi.c
@@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id,
}
}
-#ifdef CONFIG_PM
-/**
- * ata_scsi_device_suspend - suspend ATA device associated with sdev
- * @sdev: the SCSI device to suspend
- * @mesg: target power management message
- *
- * Request suspend EH action on the ATA device associated with
- * @sdev and wait for the operation to complete.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg)
-{
- struct ata_port *ap = ata_shost_to_port(sdev->host);
- struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
- unsigned long flags;
- unsigned int action;
- int rc = 0;
-
- if (!dev)
- goto out;
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* wait for the previous resume to complete */
- while (dev->flags & ATA_DFLAG_SUSPENDED) {
- spin_unlock_irqrestore(ap->lock, flags);
- ata_port_wait_eh(ap);
- spin_lock_irqsave(ap->lock, flags);
- }
-
- /* if @sdev is already detached, nothing to do */
- if (sdev->sdev_state == SDEV_OFFLINE ||
- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
- goto out_unlock;
-
- /* request suspend */
- action = ATA_EH_SUSPEND;
- if (mesg.event != PM_EVENT_SUSPEND)
- action |= ATA_EH_PM_FREEZE;
- ap->eh_info.dev_action[dev->devno] |= action;
- ap->eh_info.flags |= ATA_EHI_QUIET;
- ata_port_schedule_eh(ap);
-
- spin_unlock_irqrestore(ap->lock, flags);
-
- /* wait for EH to do the job */
- ata_port_wait_eh(ap);
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* If @sdev is still attached but the associated ATA device
- * isn't suspended, the operation failed.
- */
- if (sdev->sdev_state != SDEV_OFFLINE &&
- sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL &&
- !(dev->flags & ATA_DFLAG_SUSPENDED))
- rc = -EIO;
-
- out_unlock:
- spin_unlock_irqrestore(ap->lock, flags);
- out:
- if (rc == 0)
- sdev->sdev_gendev.power.power_state = mesg;
- return rc;
-}
-
-/**
- * ata_scsi_device_resume - resume ATA device associated with sdev
- * @sdev: the SCSI device to resume
- *
- * Request resume EH action on the ATA device associated with
- * @sdev and return immediately. This enables parallel
- * wakeup/spinup of devices.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0.
- */
-int ata_scsi_device_resume(struct scsi_device *sdev)
-{
- struct ata_port *ap = ata_shost_to_port(sdev->host);
- struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
- struct ata_eh_info *ehi = &ap->eh_info;
- unsigned long flags;
- unsigned int action;
-
- if (!dev)
- goto out;
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* if @sdev is already detached, nothing to do */
- if (sdev->sdev_state == SDEV_OFFLINE ||
- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
- goto out_unlock;
-
- /* request resume */
- action = ATA_EH_RESUME;
- if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND)
- __ata_ehi_hotplugged(ehi);
- else
- action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET;
- ehi->dev_action[dev->devno] |= action;
-
- /* We don't want autopsy and verbose EH messages. Disable
- * those if we're the only device on this link.
- */
- if (ata_port_max_devices(ap) == 1)
- ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
- ata_port_schedule_eh(ap);
-
- out_unlock:
- spin_unlock_irqrestore(ap->lock, flags);
- out:
- sdev->sdev_gendev.power.power_state = PMSG_ON;
- return 0;
-}
-#endif /* CONFIG_PM */
-
/**
* ata_to_sense_error - convert ATA error to SCSI error
* @id: ATA device number
@@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_de
blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
+ sdev->manage_start_stop = 1;
+
if (dev)
ata_scsi_dev_config(sdev, dev);
Index: work/drivers/ata/pata_ali.c
===================================================================
--- work.orig/drivers/ata/pata_ali.c
+++ work/drivers/ata/pata_ali.c
@@ -345,10 +345,6 @@ static struct scsi_host_template ali_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
/*
Index: work/drivers/ata/pata_amd.c
===================================================================
--- work.orig/drivers/ata/pata_amd.c
+++ work/drivers/ata/pata_amd.c
@@ -334,10 +334,6 @@ static struct scsi_host_template amd_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations amd33_port_ops = {
Index: work/drivers/ata/pata_atiixp.c
===================================================================
--- work.orig/drivers/ata/pata_atiixp.c
+++ work/drivers/ata/pata_atiixp.c
@@ -229,10 +229,6 @@ static struct scsi_host_template atiixp_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations atiixp_port_ops = {
Index: work/drivers/ata/pata_cmd640.c
===================================================================
--- work.orig/drivers/ata/pata_cmd640.c
+++ work/drivers/ata/pata_cmd640.c
@@ -181,8 +181,6 @@ static struct scsi_host_template cmd640_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cmd640_port_ops = {
Index: work/drivers/ata/pata_cmd64x.c
===================================================================
--- work.orig/drivers/ata/pata_cmd64x.c
+++ work/drivers/ata/pata_cmd64x.c
@@ -266,10 +266,6 @@ static struct scsi_host_template cmd64x_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cmd64x_port_ops = {
Index: work/drivers/ata/pata_cs5520.c
===================================================================
--- work.orig/drivers/ata/pata_cs5520.c
+++ work/drivers/ata/pata_cs5520.c
@@ -155,10 +155,6 @@ static struct scsi_host_template cs5520_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5520_port_ops = {
Index: work/drivers/ata/pata_cs5530.c
===================================================================
--- work.orig/drivers/ata/pata_cs5530.c
+++ work/drivers/ata/pata_cs5530.c
@@ -176,10 +176,6 @@ static struct scsi_host_template cs5530_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5530_port_ops = {
Index: work/drivers/ata/pata_cs5535.c
===================================================================
--- work.orig/drivers/ata/pata_cs5535.c
+++ work/drivers/ata/pata_cs5535.c
@@ -185,10 +185,6 @@ static struct scsi_host_template cs5535_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5535_port_ops = {
Index: work/drivers/ata/pata_cypress.c
===================================================================
--- work.orig/drivers/ata/pata_cypress.c
+++ work/drivers/ata/pata_cypress.c
@@ -136,10 +136,6 @@ static struct scsi_host_template cy82c69
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cy82c693_port_ops = {
Index: work/drivers/ata/pata_efar.c
===================================================================
--- work.orig/drivers/ata/pata_efar.c
+++ work/drivers/ata/pata_efar.c
@@ -246,10 +246,6 @@ static struct scsi_host_template efar_sh
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations efar_ops = {
Index: work/drivers/ata/pata_hpt366.c
===================================================================
--- work.orig/drivers/ata/pata_hpt366.c
+++ work/drivers/ata/pata_hpt366.c
@@ -332,10 +332,6 @@ static struct scsi_host_template hpt36x_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
/*
Index: work/drivers/ata/pata_hpt3x3.c
===================================================================
--- work.orig/drivers/ata/pata_hpt3x3.c
+++ work/drivers/ata/pata_hpt3x3.c
@@ -100,10 +100,6 @@ static struct scsi_host_template hpt3x3_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations hpt3x3_port_ops = {
Index: work/drivers/ata/pata_it8213.c
===================================================================
--- work.orig/drivers/ata/pata_it8213.c
+++ work/drivers/ata/pata_it8213.c
@@ -255,10 +255,6 @@ static struct scsi_host_template it8213_
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations it8213_ops = {
Index: work/drivers/ata/pata_it821x.c
===================================================================
--- work.orig/drivers/ata/pata_it821x.c
+++ work/drivers/ata/pata_it821x.c
@@ -620,10 +620,6 @@ static struct scsi_host_template it821x_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations it821x_smart_port_ops = {
Index: work/drivers/ata/pata_ixp4xx_cf.c
===================================================================
--- work.orig/drivers/ata/pata_ixp4xx_cf.c
+++ work/drivers/ata/pata_ixp4xx_cf.c
@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_po
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
Index: work/drivers/ata/pata_jmicron.c
===================================================================
--- work.orig/drivers/ata/pata_jmicron.c
+++ work/drivers/ata/pata_jmicron.c
@@ -137,10 +137,6 @@ static struct scsi_host_template jmicron
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations jmicron_ops = {
Index: work/drivers/ata/pata_marvell.c
===================================================================
--- work.orig/drivers/ata/pata_marvell.c
+++ work/drivers/ata/pata_marvell.c
@@ -104,10 +104,6 @@ static struct scsi_host_template marvell
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations marvell_ops = {
Index: work/drivers/ata/pata_mpc52xx.c
===================================================================
--- work.orig/drivers/ata/pata_mpc52xx.c
+++ work/drivers/ata/pata_mpc52xx.c
@@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct ata_port_operations mpc52xx_ata_port_ops = {
Index: work/drivers/ata/pata_mpiix.c
===================================================================
--- work.orig/drivers/ata/pata_mpiix.c
+++ work/drivers/ata/pata_mpiix.c
@@ -164,10 +164,6 @@ static struct scsi_host_template mpiix_s
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations mpiix_port_ops = {
Index: work/drivers/ata/pata_netcell.c
===================================================================
--- work.orig/drivers/ata/pata_netcell.c
+++ work/drivers/ata/pata_netcell.c
@@ -63,10 +63,6 @@ static struct scsi_host_template netcell
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations netcell_ops = {
Index: work/drivers/ata/pata_ns87410.c
===================================================================
--- work.orig/drivers/ata/pata_ns87410.c
+++ work/drivers/ata/pata_ns87410.c
@@ -156,10 +156,6 @@ static struct scsi_host_template ns87410
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations ns87410_port_ops = {
Index: work/drivers/ata/pata_oldpiix.c
===================================================================
--- work.orig/drivers/ata/pata_oldpiix.c
+++ work/drivers/ata/pata_oldpiix.c
@@ -232,10 +232,6 @@ static struct scsi_host_template oldpiix
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations oldpiix_pata_ops = {
Index: work/drivers/ata/pata_opti.c
===================================================================
--- work.orig/drivers/ata/pata_opti.c
+++ work/drivers/ata/pata_opti.c
@@ -177,10 +177,6 @@ static struct scsi_host_template opti_sh
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations opti_port_ops = {
Index: work/drivers/ata/pata_optidma.c
===================================================================
--- work.orig/drivers/ata/pata_optidma.c
+++ work/drivers/ata/pata_optidma.c
@@ -360,10 +360,6 @@ static struct scsi_host_template optidma
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations optidma_port_ops = {
Index: work/drivers/ata/pata_pdc202xx_old.c
===================================================================
--- work.orig/drivers/ata/pata_pdc202xx_old.c
+++ work/drivers/ata/pata_pdc202xx_old.c
@@ -244,10 +244,6 @@ static struct scsi_host_template pdc202x
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations pdc2024x_port_ops = {
Index: work/drivers/ata/pata_radisys.c
===================================================================
--- work.orig/drivers/ata/pata_radisys.c
+++ work/drivers/ata/pata_radisys.c
@@ -200,10 +200,6 @@ static struct scsi_host_template radisys
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations radisys_pata_ops = {
Index: work/drivers/ata/pata_rz1000.c
===================================================================
--- work.orig/drivers/ata/pata_rz1000.c
+++ work/drivers/ata/pata_rz1000.c
@@ -40,7 +40,7 @@ static int rz1000_set_mode(struct ata_po
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
@@ -69,10 +69,6 @@ static struct scsi_host_template rz1000_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations rz1000_port_ops = {
Index: work/drivers/ata/pata_sc1200.c
===================================================================
--- work.orig/drivers/ata/pata_sc1200.c
+++ work/drivers/ata/pata_sc1200.c
@@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations sc1200_port_ops = {
Index: work/drivers/ata/pata_scc.c
===================================================================
--- work.orig/drivers/ata/pata_scc.c
+++ work/drivers/ata/pata_scc.c
@@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations scc_pata_ops = {
Index: work/drivers/ata/pata_serverworks.c
===================================================================
--- work.orig/drivers/ata/pata_serverworks.c
+++ work/drivers/ata/pata_serverworks.c
@@ -313,10 +313,6 @@ static struct scsi_host_template serverw
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations serverworks_osb4_port_ops = {
Index: work/drivers/ata/pata_sil680.c
===================================================================
--- work.orig/drivers/ata/pata_sil680.c
+++ work/drivers/ata/pata_sil680.c
@@ -230,10 +230,6 @@ static struct scsi_host_template sil680_
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct ata_port_operations sil680_port_ops = {
Index: work/drivers/ata/pata_sis.c
===================================================================
--- work.orig/drivers/ata/pata_sis.c
+++ work/drivers/ata/pata_sis.c
@@ -520,10 +520,6 @@ static struct scsi_host_template sis_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations sis_133_ops = {
Index: work/drivers/ata/pata_triflex.c
===================================================================
--- work.orig/drivers/ata/pata_triflex.c
+++ work/drivers/ata/pata_triflex.c
@@ -192,10 +192,6 @@ static struct scsi_host_template triflex
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations triflex_port_ops = {
Index: work/drivers/ata/pata_via.c
===================================================================
--- work.orig/drivers/ata/pata_via.c
+++ work/drivers/ata/pata_via.c
@@ -300,10 +300,6 @@ static struct scsi_host_template via_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations via_port_ops = {
Index: work/drivers/ata/sata_inic162x.c
===================================================================
--- work.orig/drivers/ata/sata_inic162x.c
+++ work/drivers/ata/sata_inic162x.c
@@ -135,10 +135,6 @@ static struct scsi_host_template inic_sh
.slave_configure = inic_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const int scr_map[] = {
Index: work/drivers/ata/sata_nv.c
===================================================================
--- work.orig/drivers/ata/sata_nv.c
+++ work/drivers/ata/sata_nv.c
@@ -322,10 +322,6 @@ static struct scsi_host_template nv_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct scsi_host_template nv_adma_sht = {
@@ -344,10 +340,6 @@ static struct scsi_host_template nv_adma
.slave_configure = nv_adma_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations nv_generic_ops = {
Index: work/drivers/ata/sata_sil.c
===================================================================
--- work.orig/drivers/ata/sata_sil.c
+++ work/drivers/ata/sata_sil.c
@@ -183,10 +183,6 @@ static struct scsi_host_template sil_sht
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations sil_ops = {
Index: work/drivers/ata/sata_sil24.c
===================================================================
--- work.orig/drivers/ata/sata_sil24.c
+++ work/drivers/ata/sata_sil24.c
@@ -381,10 +381,6 @@ static struct scsi_host_template sil24_s
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations sil24_ops = {
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -140,7 +140,6 @@ enum {
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
- ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
ATA_DFLAG_DETACH = (1 << 16),
@@ -267,13 +266,9 @@ enum {
ATA_EH_REVALIDATE = (1 << 0),
ATA_EH_SOFTRESET = (1 << 1),
ATA_EH_HARDRESET = (1 << 2),
- ATA_EH_SUSPEND = (1 << 3),
- ATA_EH_RESUME = (1 << 4),
- ATA_EH_PM_FREEZE = (1 << 5),
ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
- ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
- ATA_EH_RESUME | ATA_EH_PM_FREEZE,
+ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE,
/* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
@@ -753,8 +748,6 @@ extern int sata_scr_write_flush(struct a
extern int ata_port_online(struct ata_port *ap);
extern int ata_port_offline(struct ata_port *ap);
#ifdef CONFIG_PM
-extern int ata_scsi_device_resume(struct scsi_device *);
-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host);
#endif
@@ -1026,11 +1019,6 @@ static inline unsigned int ata_dev_absen
return ata_class_absent(dev->class);
}
-static inline unsigned int ata_dev_ready(const struct ata_device *dev)
-{
- return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
-}
-
/*
* port helpers
*/
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
@ 2007-03-20 15:29 ` Christoph Hellwig
2007-03-21 7:05 ` [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume Tejun Heo
2007-03-20 15:55 ` [PATCH 4/4] libata: implement libata.spindown_compat Tejun Heo
2007-03-20 16:39 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Alan Cox
2 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2007-03-20 15:29 UTC (permalink / raw)
To: Tejun Heo
Cc: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
On Wed, Mar 21, 2007 at 12:25:33AM +0900, Tejun Heo wrote:
> Reimplement suspend/resume support using sdev->manage_start_stop.
>
> * Device suspend/resume is now SCSI layer's responsibility and the
> code is simplified a lot.
Finally. I've been telling people to do it this way forever.
Can you please also kill the braindead suspend and resume scsi_host_template
methods now?
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 4/4] libata: implement libata.spindown_compat
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
2007-03-20 15:29 ` Christoph Hellwig
@ 2007-03-20 15:55 ` Tejun Heo
2007-04-17 14:45 ` Jeff Garzik
2007-03-20 16:39 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Alan Cox
2 siblings, 1 reply; 27+ messages in thread
From: Tejun Heo @ 2007-03-20 15:55 UTC (permalink / raw)
To: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
Now that libata uses sd->manage_start_stop, libata spins down disk on
shutdown. In an attempt to compensate libata's previous shortcoming,
shutdown(8) syncs and spins down disks attached via libata. Some
disks spin back up just to spin down again on STANDBYNOW1 if the
command is issued when the disk is spun down, so this double spinning
down causes problem.
This patch implements module parameter libata.spindown_compat which,
when set to one (default value), prevents libata from spinning down
disks on shutdown thus avoiding double spinning down. Note that
libata spins down disks for suspend to mem and disk, so with
libata.spindown_compat set to one, disks should be properly spun down
in all cases without modifying shutdown(8).
shutdown(8) should be fixed eventually tho. Some drive do spin up on
SYNCHRONZE_CACHE even when their cache is clean. Those disks
currently spin up briefly when sd tries to shutdown the device and
then the machine powers off immediately, which can't be good for the
head. We can't skip SYNCHRONIZE_CACHE during shudown as it can be
dangerous data integrity-wise.
So, this spindown_compat parameter is already scheduled for removal by
the end of the next year and here's what shutdown(8) should do.
1. Check whether /sys/modules/libata/parameters/spindown_compat
exists. If it does, write 0 to it.
For each libata harddisk {
2. Check whether /sys/class/scsi_disk/h:c:i:l/manage_start_stop
exists. If so, write 1 to it and continue; otherwise, fall
through to #3.
3. Synchronize cache and spin down as before.
}
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
Henrique, does it look good enough? How do we coordinate this with
distributions? I can take care of suse and I guess Alan/Jeff can do
so for redhat. So, that leaves us with Debian, Ubuntu, Gentoo...
Documentation/feature-removal-schedule.txt | 19 +++++++++++++++++++
drivers/ata/libata-core.c | 6 ++++++
drivers/ata/libata-scsi.c | 14 +++++++++++++-
drivers/ata/libata.h | 1 +
4 files changed, 39 insertions(+), 1 deletion(-)
Index: work/Documentation/feature-removal-schedule.txt
===================================================================
--- work.orig/Documentation/feature-removal-schedule.txt
+++ work/Documentation/feature-removal-schedule.txt
@@ -324,3 +324,22 @@ Why: the i8xx_tco watchdog driver has be
Who: Wim Van Sebroeck <wim@iguana.be>
---------------------------
+
+What: libata.spindown_compat module parameter
+When: Dec 2008
+Why: halt(8) synchronizes caches for and spins down libata disks
+ because libata didn't use to spin down disk on system halt
+ (only synchronized caches).
+ Spin down on system halt is now implemented and can be tested
+ using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop.
+ Because issuing spin down command to an already spun down disk
+ makes some disks spin up just to spin down again, the old
+ behavior needs to be maintained till userspace tool is updated
+ to check the sysfs node and not to spin down disks with the
+ node set to one.
+ This module parameter is to give userspace tool the time to
+ get updated and should be removed after userspace is
+ reasonably updated.
+Who: Tejun Heo <htejun@gmail.com>
+
+---------------------------
Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -97,6 +97,12 @@ int noacpi;
module_param(noacpi, int, 0444);
MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
+int ata_spindown_compat = 1;
+module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
+ "behavior. Will be removed. More info can be found in "
+ "Documentation/feature-removal-schedule.txt\n");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
Index: work/drivers/ata/libata-scsi.c
===================================================================
--- work.orig/drivers/ata/libata-scsi.c
+++ work/drivers/ata/libata-scsi.c
@@ -944,9 +944,21 @@ static unsigned int ata_scsi_start_stop_
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else
+ } else {
+ /* XXX: This is for backward compatibility, will be
+ * removed. Read Documentation/feature-removal-schedule.txt
+ * for more info.
+ */
+ if (ata_spindown_compat &&
+ (system_state == SYSTEM_HALT ||
+ system_state == SYSTEM_POWER_OFF)) {
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
+ }
+
/* Issue ATA STANDBY IMMEDIATE command */
tf->command = ATA_CMD_STANDBYNOW1;
+ }
/*
* Standby and Idle condition timers could be implemented but that
Index: work/drivers/ata/libata.h
===================================================================
--- work.orig/drivers/ata/libata.h
+++ work/drivers/ata/libata.h
@@ -57,6 +57,7 @@ extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
extern int noacpi;
+extern int ata_spindown_compat;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop
2007-03-20 16:39 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Alan Cox
@ 2007-03-20 16:15 ` Oliver Neukum
0 siblings, 0 replies; 27+ messages in thread
From: Oliver Neukum @ 2007-03-20 16:15 UTC (permalink / raw)
To: Alan Cox
Cc: Tejun Heo, Jeff Garzik, linux-ide, linux-scsi, James Bottomley,
djwong, hmh
Am Dienstag, 20. März 2007 17:39 schrieb Alan Cox:
> > * sdev->manage_start_stop is set to 1 in ata_scsi_slave_config().
> > This fixes spindown on shutdown and suspend-to-disk.
>
> Yay!!!!
Which kernel version is this?
Regards
Oliver
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" 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] 27+ messages in thread
* Re: [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
2007-03-20 15:29 ` Christoph Hellwig
2007-03-20 15:55 ` [PATCH 4/4] libata: implement libata.spindown_compat Tejun Heo
@ 2007-03-20 16:39 ` Alan Cox
2007-03-20 16:15 ` Oliver Neukum
2 siblings, 1 reply; 27+ messages in thread
From: Alan Cox @ 2007-03-20 16:39 UTC (permalink / raw)
To: Tejun Heo
Cc: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
> * DPM is dropped. This also simplifies code a lot. Suspend/resume
> status is port-wide now.
Makes sense
> * sdev->manage_start_stop is set to 1 in ata_scsi_slave_config().
> This fixes spindown on shutdown and suspend-to-disk.
Yay!!!!
> Signed-off-by: Tejun Heo <htejun@gmail.com>
Acked-by: Alan Cox <alan@redhat.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 15:13 ` [PATCH 2/3] sd: implement START/STOP management Tejun Heo
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
@ 2007-03-20 16:58 ` James Bottomley
2007-03-20 17:08 ` Tejun Heo
2007-03-20 17:58 ` Douglas Gilbert
2 siblings, 1 reply; 27+ messages in thread
From: James Bottomley @ 2007-03-20 16:58 UTC (permalink / raw)
To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
On Wed, 2007-03-21 at 00:13 +0900, Tejun Heo wrote:
> Implement SBC START/STOP management. sdev->mange_start_stop is added.
> When it's set to one, sd STOPs the device on suspend and shutdown and
> STARTs it on resume. sdev->manage_start_stop defaults is in sdev
> instead of scsi_disk cdev to allow ->slave_config() override the
> default configuration but is exported under scsi_disk sysfs node as
> sdev->allow_restart is.
>
> When manage_start_stop is zero (the default value), this patch doesn't
> introduce any behavior change.
I have this in scsi-misc-2.6. There was a minor space before tab no-no
which git complained about (and I fixed). Unfortunately, there's a
pretty major merge conflict with prior sd.c patches in scsi-misc-2.6.
I've merged and fixed this but it's going to create a bit of a
difficulty for applying the libata pieces.
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 16:58 ` [PATCH 2/3] sd: implement START/STOP management James Bottomley
@ 2007-03-20 17:08 ` Tejun Heo
2007-03-20 17:26 ` James Bottomley
0 siblings, 1 reply; 27+ messages in thread
From: Tejun Heo @ 2007-03-20 17:08 UTC (permalink / raw)
To: James Bottomley; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
James Bottomley wrote:
> On Wed, 2007-03-21 at 00:13 +0900, Tejun Heo wrote:
>> Implement SBC START/STOP management. sdev->mange_start_stop is added.
>> When it's set to one, sd STOPs the device on suspend and shutdown and
>> STARTs it on resume. sdev->manage_start_stop defaults is in sdev
>> instead of scsi_disk cdev to allow ->slave_config() override the
>> default configuration but is exported under scsi_disk sysfs node as
>> sdev->allow_restart is.
>>
>> When manage_start_stop is zero (the default value), this patch doesn't
>> introduce any behavior change.
>
> I have this in scsi-misc-2.6. There was a minor space before tab no-no
> which git complained about (and I fixed). Unfortunately, there's a
> pretty major merge conflict with prior sd.c patches in scsi-misc-2.6.
> I've merged and fixed this but it's going to create a bit of a
> difficulty for applying the libata pieces.
I got too comfortable with libata-dev#upstream and forgot to verify
patches against scsi-misc-2.6. Sorry about that. If you don't have
objection against the content, I'll resubmit the SCSI part against
scsi-misc-2.6. Once it's in scsi-misc-2.6, we can pull it into
libata-dev#upstream and do the libata part there. As the SCSI change
doesn't break libata, they can be done separately.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 17:08 ` Tejun Heo
@ 2007-03-20 17:26 ` James Bottomley
2007-03-21 3:42 ` Tejun Heo
0 siblings, 1 reply; 27+ messages in thread
From: James Bottomley @ 2007-03-20 17:26 UTC (permalink / raw)
To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
On Wed, 2007-03-21 at 02:08 +0900, Tejun Heo wrote:
> I got too comfortable with libata-dev#upstream and forgot to verify
> patches against scsi-misc-2.6. Sorry about that. If you don't have
> objection against the content, I'll resubmit the SCSI part against
> scsi-misc-2.6. Once it's in scsi-misc-2.6, we can pull it into
> libata-dev#upstream and do the libata part there. As the SCSI change
> doesn't break libata, they can be done separately.
I should already have it in scsi-misc-2.6 ... you could verify I got the
merge right ...
There'll be an additional piece to put the new sd_printk helpers into
the routines, which I attach below.
James
---
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 49a94ae..b044dcf 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1733,10 +1733,11 @@ static void scsi_disk_release(struct class_device *cdev)
kfree(sdkp);
}
-static int sd_start_stop_device(struct scsi_device *sdp, int start)
+static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
{
unsigned char cmd[6] = { START_STOP }; /* START_VALID */
struct scsi_sense_hdr sshdr;
+ struct scsi_device *sdp = sdkp->device;
int res;
if (start)
@@ -1748,12 +1749,10 @@ static int sd_start_stop_device(struct scsi_device *sdp, int start)
res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
SD_TIMEOUT, SD_MAX_RETRIES);
if (res) {
- printk(KERN_WARNING "FAILED\n status = %x, message = %02x, "
- "host = %d, driver = %02x\n ",
- status_byte(res), msg_byte(res),
- host_byte(res), driver_byte(res));
+ sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n");
+ sd_print_result(sdkp, res);
if (driver_byte(res) & DRIVER_SENSE)
- scsi_print_sense_hdr("sd", &sshdr);
+ sd_print_sense_hdr(sdkp, &sshdr);
}
return res;
@@ -1766,7 +1765,6 @@ static int sd_start_stop_device(struct scsi_device *sdp, int start)
*/
static void sd_shutdown(struct device *dev)
{
- struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
if (!sdkp)
@@ -1777,10 +1775,9 @@ static void sd_shutdown(struct device *dev)
sd_sync_cache(sdkp);
}
- if (system_state != SYSTEM_RESTART && sdp->manage_start_stop) {
- printk(KERN_NOTICE "Stopping disk %s: \n",
- sdkp->disk->disk_name);
- sd_start_stop_device(sdp, 0);
+ if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) {
+ sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
+ sd_start_stop_device(sdkp, 0);
}
scsi_disk_put(sdkp);
@@ -1788,7 +1785,6 @@ static void sd_shutdown(struct device *dev)
static int sd_suspend(struct device *dev, pm_message_t mesg)
{
- struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
int ret;
@@ -1796,17 +1792,16 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
return 0; /* this can happen */
if (sdkp->WCE) {
- printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
- sdkp->disk->disk_name);
+ sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp);
if (ret)
return ret;
}
- if (mesg.event == PM_EVENT_SUSPEND && sdp->manage_start_stop) {
- printk(KERN_NOTICE "Stopping disk %s: \n",
- sdkp->disk->disk_name);
- ret = sd_start_stop_device(sdp, 0);
+ if (mesg.event == PM_EVENT_SUSPEND &&
+ sdkp->device->manage_start_stop) {
+ sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
+ ret = sd_start_stop_device(sdkp, 0);
if (ret)
return ret;
}
@@ -1816,15 +1811,14 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
static int sd_resume(struct device *dev)
{
- struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
- if (!sdp->manage_start_stop)
+ if (!sdkp->device->manage_start_stop)
return 0;
- printk(KERN_NOTICE "Starting disk %s: \n", sdkp->disk->disk_name);
+ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
- return sd_start_stop_device(sdp, 1);
+ return sd_start_stop_device(sdkp, 1);
}
/**
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 15:13 ` [PATCH 2/3] sd: implement START/STOP management Tejun Heo
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
2007-03-20 16:58 ` [PATCH 2/3] sd: implement START/STOP management James Bottomley
@ 2007-03-20 17:58 ` Douglas Gilbert
2007-03-20 18:41 ` James Bottomley
2007-03-21 2:35 ` Tejun Heo
2 siblings, 2 replies; 27+ messages in thread
From: Douglas Gilbert @ 2007-03-20 17:58 UTC (permalink / raw)
To: Tejun Heo
Cc: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
Tejun Heo wrote:
> Implement SBC START/STOP management. sdev->mange_start_stop is added.
> When it's set to one, sd STOPs the device on suspend and shutdown and
> STARTs it on resume. sdev->manage_start_stop defaults is in sdev
> instead of scsi_disk cdev to allow ->slave_config() override the
> default configuration but is exported under scsi_disk sysfs node as
> sdev->allow_restart is.
>
> When manage_start_stop is zero (the default value), this patch doesn't
> introduce any behavior change.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> ---
> drivers/scsi/scsi_sysfs.c | 31 +++++++++++--
> drivers/scsi/sd.c | 102 +++++++++++++++++++++++++++++++++++++++++++++
> include/scsi/scsi_device.h | 1
> 3 files changed, 130 insertions(+), 4 deletions(-)
>
> Index: work/drivers/scsi/sd.c
> ===================================================================
> --- work.orig/drivers/scsi/sd.c
> +++ work/drivers/scsi/sd.c
> @@ -142,6 +142,8 @@ static void sd_rw_intr(struct scsi_cmnd
> static int sd_probe(struct device *);
> static int sd_remove(struct device *);
> static void sd_shutdown(struct device *dev);
> +static int sd_suspend(struct device *dev, pm_message_t state);
> +static int sd_resume(struct device *dev);
> static void sd_rescan(struct device *);
> static int sd_init_command(struct scsi_cmnd *);
> static int sd_issue_flush(struct device *, sector_t *);
> @@ -206,6 +208,20 @@ static ssize_t sd_store_cache_type(struc
> return count;
> }
>
> +static ssize_t sd_store_manage_start_stop(struct class_device *cdev,
> + const char *buf, size_t count)
> +{
> + struct scsi_disk *sdkp = to_scsi_disk(cdev);
> + struct scsi_device *sdp = sdkp->device;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EACCES;
> +
> + sdp->manage_start_stop = simple_strtoul(buf, NULL, 10);
> +
> + return count;
> +}
> +
> static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
> size_t count)
> {
> @@ -238,6 +254,14 @@ static ssize_t sd_show_fua(struct class_
> return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
> }
>
> +static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf)
> +{
> + struct scsi_disk *sdkp = to_scsi_disk(cdev);
> + struct scsi_device *sdp = sdkp->device;
> +
> + return snprintf(buf, 20, "%u\n", sdp->manage_start_stop);
> +}
> +
> static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
> {
> struct scsi_disk *sdkp = to_scsi_disk(cdev);
> @@ -251,6 +275,8 @@ static struct class_device_attribute sd_
> __ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
> __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
> sd_store_allow_restart),
> + __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop,
> + sd_store_manage_start_stop),
> __ATTR_NULL,
> };
>
> @@ -267,6 +293,8 @@ static struct scsi_driver sd_template =
> .name = "sd",
> .probe = sd_probe,
> .remove = sd_remove,
> + .suspend = sd_suspend,
> + .resume = sd_resume,
> .shutdown = sd_shutdown,
> },
> .rescan = sd_rescan,
> @@ -1776,6 +1804,32 @@ static void scsi_disk_release(struct cla
> kfree(sdkp);
> }
>
> +static int sd_start_stop_device(struct scsi_device *sdp, int start)
> +{
> + unsigned char cmd[6] = { START_STOP }; /* START_VALID */
> + struct scsi_sense_hdr sshdr;
> + int res;
> +
> + if (start)
> + cmd[4] |= 1; /* START */
> +
> + if (!scsi_device_online(sdp))
> + return -ENODEV;
> +
> + res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
> + SD_TIMEOUT, SD_MAX_RETRIES);
Tejun,
I note at this point that the IMMED bit in the
START STOP UNIT cdb is clear. [The code might
note that as well.] All SCSI disks that I have
seen, implement the IMMED bit and according to
the SAT standard, so should SAT layers like the
one in libata.
With the IMMED bit clear:
- on spin up, it will wait until disk is ready.
Okay unless there are a lot of disks, in
which case we could ask Matthew Wilcox for help
- on spin down, will wait until media is
stopped. That could be 20 seconds, and if there
were multiple disks ....
I guess the question is do we need to wait until a
disk is spun down before dropping power to it
and suspending.
Doug Gilbert
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 17:58 ` Douglas Gilbert
@ 2007-03-20 18:41 ` James Bottomley
2007-03-21 2:35 ` Tejun Heo
1 sibling, 0 replies; 27+ messages in thread
From: James Bottomley @ 2007-03-20 18:41 UTC (permalink / raw)
To: dougg; +Cc: Tejun Heo, Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
On Tue, 2007-03-20 at 13:58 -0400, Douglas Gilbert wrote:
> I note at this point that the IMMED bit in the
> START STOP UNIT cdb is clear. [The code might
> note that as well.] All SCSI disks that I have
> seen, implement the IMMED bit and according to
> the SAT standard, so should SAT layers like the
> one in libata.
>
> With the IMMED bit clear:
> - on spin up, it will wait until disk is ready.
> Okay unless there are a lot of disks, in
> which case we could ask Matthew Wilcox for help
> - on spin down, will wait until media is
> stopped. That could be 20 seconds, and if there
> were multiple disks ....
>
> I guess the question is do we need to wait until a
> disk is spun down before dropping power to it
> and suspending.
Realistically, if you're thinking of doing a bank spin up / spin down
with IMMED=1 I suspect we can wait and see if anyone has sufficient need
for it to be implemented before trying. The majority of the
suspend/resume cases are laptops with a single disc ... and there immed
is irrelevant to them.
I think we need assurance that the head is parked before full suspend,
yes, so IMMED=0 seems the easiest way to do this.
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 17:58 ` Douglas Gilbert
2007-03-20 18:41 ` James Bottomley
@ 2007-03-21 2:35 ` Tejun Heo
2007-03-22 10:21 ` Vladislav Bolkhovitin
1 sibling, 1 reply; 27+ messages in thread
From: Tejun Heo @ 2007-03-21 2:35 UTC (permalink / raw)
To: dougg; +Cc: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
Hello, Douglas.
Douglas Gilbert wrote:
> Tejun,
> I note at this point that the IMMED bit in the
> START STOP UNIT cdb is clear. [The code might
> note that as well.] All SCSI disks that I have
> seen, implement the IMMED bit and according to
> the SAT standard, so should SAT layers like the
> one in libata.
>
> With the IMMED bit clear:
> - on spin up, it will wait until disk is ready.
> Okay unless there are a lot of disks, in
> which case we could ask Matthew Wilcox for help
> - on spin down, will wait until media is
> stopped. That could be 20 seconds, and if there
> were multiple disks ....
>
> I guess the question is do we need to wait until a
> disk is spun down before dropping power to it
> and suspending.
I think we do. As we're issuing SYNCHRONIZE CACHE prior to spinning
down disks, it's probably okay to drop power early data-integrity-wise
but still...
We can definitely use IMMED=1 during resume (needs to be throttled
somehow tho). This helps even when there is only one disk. We can let
the disk spin up in the background and proceed with the rest of resuming
process. Unfortunately, libata SAT layer doesn't do IMMED and even if
it does (I've tried and have a patch available) it doesn't really work
because during host resume each port enters EH and resets and
revalidates each device. Many if not most ATA harddisks don't respond
to reset or IDENTIFY till it's fully spun up meaning libata EH has to
wait for all drives to spin up. libata EH runs inside SCSI EH thread
meaning SCSI comman issue blocks till libata EH finishes resetting the
port. So, IMMED or not, sd gotta wait for libata disks.
If we want to do parallel spin down, PM core needs to be updated such
that there are two events - issue and done - somewhat similar to what
SCSI is doing to probe devices parallelly. If we're gonna do that, we
maybe can apply the same mechanism to resume path so that we can do
things parallelly IMMED or not.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-20 17:26 ` James Bottomley
@ 2007-03-21 3:42 ` Tejun Heo
0 siblings, 0 replies; 27+ messages in thread
From: Tejun Heo @ 2007-03-21 3:42 UTC (permalink / raw)
To: James Bottomley; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
James Bottomley wrote:
> On Wed, 2007-03-21 at 02:08 +0900, Tejun Heo wrote:
>> I got too comfortable with libata-dev#upstream and forgot to verify
>> patches against scsi-misc-2.6. Sorry about that. If you don't have
>> objection against the content, I'll resubmit the SCSI part against
>> scsi-misc-2.6. Once it's in scsi-misc-2.6, we can pull it into
>> libata-dev#upstream and do the libata part there. As the SCSI change
>> doesn't break libata, they can be done separately.
>
> I should already have it in scsi-misc-2.6 ... you could verify I got the
> merge right ...
>
> There'll be an additional piece to put the new sd_printk helpers into
> the routines, which I attach below.
Yeap, everything looks fine. Thanks.
--
tejun
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume
2007-03-20 15:29 ` Christoph Hellwig
@ 2007-03-21 7:05 ` Tejun Heo
2007-03-21 14:19 ` Christoph Hellwig
2007-03-21 15:16 ` James Bottomley
0 siblings, 2 replies; 27+ messages in thread
From: Tejun Heo @ 2007-03-21 7:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jeff Garzik, linux-ide, linux-scsi, James Bottomley, djwong, hmh
With libata converted to use sdev->manage_start_stop for suspend and
resume, sht->suspend/resume() has no user left and low level
suspend/ressume should be taken care of by low level driver's
suspend/resume callbacks (e.g. PCI or PCMCIA driver callbacks). This
patch removes sht->suspend/resume() callbacks.
This change is suggested by Christoph Hellwig.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
---
This patch breaks the existing libata suspend/resume support and thus
should not be applied before libata is updated. So, please don't
apply it yet.
Thanks.
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 96db51c..ec64aff 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -280,30 +280,18 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state)
{
struct device_driver *drv = dev->driver;
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)
return err;
- /* call HLD suspend first */
if (drv && drv->suspend) {
err = drv->suspend(dev, state);
if (err)
return err;
}
- /* then, call host suspend */
- if (sht->suspend) {
- err = sht->suspend(sdev, state);
- if (err) {
- if (drv && drv->resume)
- drv->resume(dev);
- return err;
- }
- }
-
return 0;
}
@@ -311,21 +299,14 @@ static int scsi_bus_resume(struct device * dev)
{
struct device_driver *drv = dev->driver;
struct scsi_device *sdev = to_scsi_device(dev);
- struct scsi_host_template *sht = sdev->host->hostt;
- int err = 0, err2 = 0;
-
- /* call host resume first */
- if (sht->resume)
- err = sht->resume(sdev);
+ int err = 0;
- /* then, call HLD resume */
if (drv && drv->resume)
- err2 = drv->resume(dev);
+ err = drv->resume(dev);
scsi_device_resume(sdev);
- /* favor LLD failure */
- return err ? err : err2;;
+ return err;
}
struct bus_type scsi_bus_type = {
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 68f461b..4a2e490 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -339,12 +339,6 @@ struct scsi_host_template {
enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
/*
- * suspend support
- */
- int (*resume)(struct scsi_device *);
- int (*suspend)(struct scsi_device *, pm_message_t state);
-
- /*
* Name of proc directory
*/
char *proc_name;
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume
2007-03-21 7:05 ` [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume Tejun Heo
@ 2007-03-21 14:19 ` Christoph Hellwig
2007-03-21 15:16 ` James Bottomley
1 sibling, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2007-03-21 14:19 UTC (permalink / raw)
To: Tejun Heo
Cc: Christoph Hellwig, Jeff Garzik, linux-ide, linux-scsi,
James Bottomley, djwong, hmh
On Wed, Mar 21, 2007 at 04:05:16PM +0900, Tejun Heo wrote:
> With libata converted to use sdev->manage_start_stop for suspend and
> resume, sht->suspend/resume() has no user left and low level
> suspend/ressume should be taken care of by low level driver's
> suspend/resume callbacks (e.g. PCI or PCMCIA driver callbacks). This
> patch removes sht->suspend/resume() callbacks.
>
> This change is suggested by Christoph Hellwig.
Very nice, as the rest of the series. Thanks a lot Tejun.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume
2007-03-21 7:05 ` [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume Tejun Heo
2007-03-21 14:19 ` Christoph Hellwig
@ 2007-03-21 15:16 ` James Bottomley
2007-05-14 15:52 ` Tejun Heo
1 sibling, 1 reply; 27+ messages in thread
From: James Bottomley @ 2007-03-21 15:16 UTC (permalink / raw)
To: Tejun Heo
Cc: Christoph Hellwig, Jeff Garzik, linux-ide, linux-scsi, djwong,
hmh
On Wed, 2007-03-21 at 16:05 +0900, Tejun Heo wrote:
> This patch breaks the existing libata suspend/resume support and thus
> should not be applied before libata is updated. So, please don't
> apply it yet.
I don't have a git tree for this, but I'll mark it in my email, just
say the word.
Thanks for doing this,
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-21 2:35 ` Tejun Heo
@ 2007-03-22 10:21 ` Vladislav Bolkhovitin
2007-03-22 12:29 ` Henrique de Moraes Holschuh
0 siblings, 1 reply; 27+ messages in thread
From: Vladislav Bolkhovitin @ 2007-03-22 10:21 UTC (permalink / raw)
To: Tejun Heo
Cc: dougg, Jeff Garzik, linux-ide, linux-scsi, James Bottomley,
djwong, hmh
Tejun Heo wrote:
> Hello, Douglas.
>
> Douglas Gilbert wrote:
>
>>Tejun,
>>I note at this point that the IMMED bit in the
>>START STOP UNIT cdb is clear. [The code might
>>note that as well.] All SCSI disks that I have
>>seen, implement the IMMED bit and according to
>>the SAT standard, so should SAT layers like the
>>one in libata.
>>
>>With the IMMED bit clear:
>> - on spin up, it will wait until disk is ready.
>> Okay unless there are a lot of disks, in
>> which case we could ask Matthew Wilcox for help
>> - on spin down, will wait until media is
>> stopped. That could be 20 seconds, and if there
>> were multiple disks ....
>>
>>I guess the question is do we need to wait until a
>>disk is spun down before dropping power to it
>>and suspending.
>
>
> I think we do. As we're issuing SYNCHRONIZE CACHE prior to spinning
> down disks, it's probably okay to drop power early data-integrity-wise
> but still...
>
> We can definitely use IMMED=1 during resume (needs to be throttled
> somehow tho). This helps even when there is only one disk. We can let
> the disk spin up in the background and proceed with the rest of resuming
> process. Unfortunately, libata SAT layer doesn't do IMMED and even if
> it does (I've tried and have a patch available) it doesn't really work
> because during host resume each port enters EH and resets and
> revalidates each device. Many if not most ATA harddisks don't respond
> to reset or IDENTIFY till it's fully spun up meaning libata EH has to
> wait for all drives to spin up. libata EH runs inside SCSI EH thread
> meaning SCSI comman issue blocks till libata EH finishes resetting the
> port. So, IMMED or not, sd gotta wait for libata disks.
>
> If we want to do parallel spin down, PM core needs to be updated such
> that there are two events - issue and done - somewhat similar to what
> SCSI is doing to probe devices parallelly. If we're gonna do that, we
> maybe can apply the same mechanism to resume path so that we can do
> things parallelly IMMED or not.
Seems, there is another way of doing a bank spin up / spin down: doing
it in two passes. On the first pass START_STOP will be issued with
IMMED=1 on all devices, then on the second pass START_STOP will be
issued with IMMED=0. So the devices will spin up / spin down in the
parallel, but synchronously, hence the needed result will be achieved
with minimal code changes, although it will indeed need upper layer
changes in struct device_driver's suspend(), resume(), etc. callers.
Vlad
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-22 10:21 ` Vladislav Bolkhovitin
@ 2007-03-22 12:29 ` Henrique de Moraes Holschuh
2007-03-22 15:14 ` Vladislav Bolkhovitin
0 siblings, 1 reply; 27+ messages in thread
From: Henrique de Moraes Holschuh @ 2007-03-22 12:29 UTC (permalink / raw)
To: Vladislav Bolkhovitin
Cc: Tejun Heo, dougg, Jeff Garzik, linux-ide, linux-scsi,
James Bottomley, djwong
On Thu, 22 Mar 2007, Vladislav Bolkhovitin wrote:
> Seems, there is another way of doing a bank spin up / spin down: doing
> it in two passes. On the first pass START_STOP will be issued with
> IMMED=1 on all devices, then on the second pass START_STOP will be
> issued with IMMED=0. So the devices will spin up / spin down in the
> parallel, but synchronously, hence the needed result will be achieved
And maybe trip the PSU's overcurrent defenses? There is a reason to default
to sequential spin-up for disks... Of course, it can be user-selectable.
But should it be the default?
--
"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] 27+ messages in thread
* Re: [PATCH 2/3] sd: implement START/STOP management
2007-03-22 12:29 ` Henrique de Moraes Holschuh
@ 2007-03-22 15:14 ` Vladislav Bolkhovitin
0 siblings, 0 replies; 27+ messages in thread
From: Vladislav Bolkhovitin @ 2007-03-22 15:14 UTC (permalink / raw)
To: Henrique de Moraes Holschuh
Cc: Tejun Heo, dougg, Jeff Garzik, linux-ide, linux-scsi,
James Bottomley, djwong
Henrique de Moraes Holschuh wrote:
> On Thu, 22 Mar 2007, Vladislav Bolkhovitin wrote:
>
>>Seems, there is another way of doing a bank spin up / spin down: doing
>>it in two passes. On the first pass START_STOP will be issued with
>>IMMED=1 on all devices, then on the second pass START_STOP will be
>>issued with IMMED=0. So the devices will spin up / spin down in the
>>parallel, but synchronously, hence the needed result will be achieved
>
>
> And maybe trip the PSU's overcurrent defenses? There is a reason to default
> to sequential spin-up for disks...
But on spin down there is no such problem
> Of course, it can be user-selectable. But should it be the default?
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-03-20 15:55 ` [PATCH 4/4] libata: implement libata.spindown_compat Tejun Heo
@ 2007-04-17 14:45 ` Jeff Garzik
2007-04-17 15:01 ` James Bottomley
0 siblings, 1 reply; 27+ messages in thread
From: Jeff Garzik @ 2007-04-17 14:45 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, linux-scsi, James Bottomley, djwong, hmh
Tejun Heo wrote:
> Now that libata uses sd->manage_start_stop, libata spins down disk on
> shutdown. In an attempt to compensate libata's previous shortcoming,
> shutdown(8) syncs and spins down disks attached via libata. Some
> disks spin back up just to spin down again on STANDBYNOW1 if the
> command is issued when the disk is spun down, so this double spinning
> down causes problem.
>
> This patch implements module parameter libata.spindown_compat which,
> when set to one (default value), prevents libata from spinning down
> disks on shutdown thus avoiding double spinning down. Note that
> libata spins down disks for suspend to mem and disk, so with
> libata.spindown_compat set to one, disks should be properly spun down
> in all cases without modifying shutdown(8).
>
> shutdown(8) should be fixed eventually tho. Some drive do spin up on
> SYNCHRONZE_CACHE even when their cache is clean. Those disks
> currently spin up briefly when sd tries to shutdown the device and
> then the machine powers off immediately, which can't be good for the
> head. We can't skip SYNCHRONIZE_CACHE during shudown as it can be
> dangerous data integrity-wise.
>
> So, this spindown_compat parameter is already scheduled for removal by
> the end of the next year and here's what shutdown(8) should do.
>
> 1. Check whether /sys/modules/libata/parameters/spindown_compat
> exists. If it does, write 0 to it.
>
> For each libata harddisk {
>
> 2. Check whether /sys/class/scsi_disk/h:c:i:l/manage_start_stop
> exists. If so, write 1 to it and continue; otherwise, fall
> through to #3.
>
> 3. Synchronize cache and spin down as before.
>
> }
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> ---
> Henrique, does it look good enough? How do we coordinate this with
> distributions? I can take care of suse and I guess Alan/Jeff can do
> so for redhat. So, that leaves us with Debian, Ubuntu, Gentoo...
ACK patches 3-4 for upstream. I'm dropping them, and requesting resend
when patches 1-2 are applied (which I also ACK). Or, alternately, I
could apply all four patches with the other subsystem owner's assent, or
the other subsystem owner could apply all four patches now that I have
ACK'd them. Pick any of the three options. :)
Jeff
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-04-17 14:45 ` Jeff Garzik
@ 2007-04-17 15:01 ` James Bottomley
2007-04-17 15:20 ` Jeff Garzik
0 siblings, 1 reply; 27+ messages in thread
From: James Bottomley @ 2007-04-17 15:01 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Tejun Heo, linux-ide, linux-scsi, djwong, hmh
On Tue, 2007-04-17 at 10:45 -0400, Jeff Garzik wrote:
> ACK patches 3-4 for upstream. I'm dropping them, and requesting resend
> when patches 1-2 are applied (which I also ACK). Or, alternately, I
> could apply all four patches with the other subsystem owner's assent, or
> the other subsystem owner could apply all four patches now that I have
> ACK'd them. Pick any of the three options. :)
I've got 1 and 2 upstream to -mm via scsi-misc-2.6 already.
Unfortunately they're not simply separable since there's a bad
interaction with the sd messages rework that's also in scsi-misc.
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-04-17 15:01 ` James Bottomley
@ 2007-04-17 15:20 ` Jeff Garzik
2007-04-17 15:26 ` James Bottomley
0 siblings, 1 reply; 27+ messages in thread
From: Jeff Garzik @ 2007-04-17 15:20 UTC (permalink / raw)
To: James Bottomley; +Cc: Tejun Heo, linux-ide, linux-scsi, djwong, hmh
James Bottomley wrote:
> On Tue, 2007-04-17 at 10:45 -0400, Jeff Garzik wrote:
>> ACK patches 3-4 for upstream. I'm dropping them, and requesting resend
>> when patches 1-2 are applied (which I also ACK). Or, alternately, I
>> could apply all four patches with the other subsystem owner's assent, or
>> the other subsystem owner could apply all four patches now that I have
>> ACK'd them. Pick any of the three options. :)
>
> I've got 1 and 2 upstream to -mm via scsi-misc-2.6 already.
> Unfortunately they're not simply separable since there's a bad
> interaction with the sd messages rework that's also in scsi-misc.
then, unless there are dependencies in libata-dev, how about Tejun
pushes patches 3-4 through scsi-misc as well?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-04-17 15:20 ` Jeff Garzik
@ 2007-04-17 15:26 ` James Bottomley
2007-04-17 17:09 ` Tejun Heo
0 siblings, 1 reply; 27+ messages in thread
From: James Bottomley @ 2007-04-17 15:26 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Tejun Heo, linux-ide, linux-scsi, djwong, hmh
On Tue, 2007-04-17 at 11:20 -0400, Jeff Garzik wrote:
> then, unless there are dependencies in libata-dev, how about Tejun
> pushes patches 3-4 through scsi-misc as well?
Sure ... as long as there are no dependencies.
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-04-17 15:26 ` James Bottomley
@ 2007-04-17 17:09 ` Tejun Heo
2007-04-17 17:33 ` James Bottomley
0 siblings, 1 reply; 27+ messages in thread
From: Tejun Heo @ 2007-04-17 17:09 UTC (permalink / raw)
To: James Bottomley; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
James Bottomley wrote:
> On Tue, 2007-04-17 at 11:20 -0400, Jeff Garzik wrote:
>> then, unless there are dependencies in libata-dev, how about Tejun
>> pushes patches 3-4 through scsi-misc as well?
>
> Sure ... as long as there are no dependencies.
James, are you going to rebase scsi-misc-2.6 before sending to Linus
when 2.6.22-rc1 window opens? If not, Jeff can pull it into libata-dev
and patch 3 and 4 can go in there. The difference in libata between
scsi-misc-2.6 and libata-dev is rather large and applying 3 and 4 to
scsi-misc-2.6 would cause merging headache later.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 4/4] libata: implement libata.spindown_compat
2007-04-17 17:09 ` Tejun Heo
@ 2007-04-17 17:33 ` James Bottomley
0 siblings, 0 replies; 27+ messages in thread
From: James Bottomley @ 2007-04-17 17:33 UTC (permalink / raw)
To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux-scsi, djwong, hmh
On Wed, 2007-04-18 at 02:09 +0900, Tejun Heo wrote:
> James, are you going to rebase scsi-misc-2.6 before sending to Linus
> when 2.6.22-rc1 window opens? If not, Jeff can pull it into libata-dev
> and patch 3 and 4 can go in there. The difference in libata between
> scsi-misc-2.6 and libata-dev is rather large and applying 3 and 4 to
> scsi-misc-2.6 would cause merging headache later.
No ... I try never to rebase a for-linus tree ... it just causes more
hassle than it's worth.
James
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume
2007-03-21 15:16 ` James Bottomley
@ 2007-05-14 15:52 ` Tejun Heo
0 siblings, 0 replies; 27+ messages in thread
From: Tejun Heo @ 2007-05-14 15:52 UTC (permalink / raw)
To: James Bottomley
Cc: Christoph Hellwig, Jeff Garzik, linux-ide, linux-scsi, djwong,
hmh
James Bottomley wrote:
> On Wed, 2007-03-21 at 16:05 +0900, Tejun Heo wrote:
>> This patch breaks the existing libata suspend/resume support and thus
>> should not be applied before libata is updated. So, please don't
>> apply it yet.
>
> I don't have a git tree for this, but I'll mark it in my email, just
> say the word.
It took quite some while but libata is updated now and this patch can go in.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2007-05-14 15:53 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-20 15:07 [PATCH 1/3] sd: fix return value of sd_sync_cache() Tejun Heo
2007-03-20 15:13 ` [PATCH 2/3] sd: implement START/STOP management Tejun Heo
2007-03-20 15:25 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Tejun Heo
2007-03-20 15:29 ` Christoph Hellwig
2007-03-21 7:05 ` [PATCH scsi-misc-2.6] SCSI: kill sht->suspend/resume Tejun Heo
2007-03-21 14:19 ` Christoph Hellwig
2007-03-21 15:16 ` James Bottomley
2007-05-14 15:52 ` Tejun Heo
2007-03-20 15:55 ` [PATCH 4/4] libata: implement libata.spindown_compat Tejun Heo
2007-04-17 14:45 ` Jeff Garzik
2007-04-17 15:01 ` James Bottomley
2007-04-17 15:20 ` Jeff Garzik
2007-04-17 15:26 ` James Bottomley
2007-04-17 17:09 ` Tejun Heo
2007-04-17 17:33 ` James Bottomley
2007-03-20 16:39 ` [PATCH 3/4] libata: reimplement suspend/resume support using sdev->manage_start_stop Alan Cox
2007-03-20 16:15 ` Oliver Neukum
2007-03-20 16:58 ` [PATCH 2/3] sd: implement START/STOP management James Bottomley
2007-03-20 17:08 ` Tejun Heo
2007-03-20 17:26 ` James Bottomley
2007-03-21 3:42 ` Tejun Heo
2007-03-20 17:58 ` Douglas Gilbert
2007-03-20 18:41 ` James Bottomley
2007-03-21 2:35 ` Tejun Heo
2007-03-22 10:21 ` Vladislav Bolkhovitin
2007-03-22 12:29 ` Henrique de Moraes Holschuh
2007-03-22 15:14 ` Vladislav Bolkhovitin
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).