From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gwendal Grignou Subject: Re: [RFC PATCH] libata: scsi: flush cache on scsi stop command Date: Fri, 21 Sep 2012 12:05:33 -0700 Message-ID: References: <1348045019-21532-1-git-send-email-aaron.lu@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Return-path: Received: from mail-qc0-f174.google.com ([209.85.216.174]:35431 "EHLO mail-qc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933127Ab2IUTFe (ORCPT ); Fri, 21 Sep 2012 15:05:34 -0400 Received: by qcro28 with SMTP id o28so2857451qcr.19 for ; Fri, 21 Sep 2012 12:05:33 -0700 (PDT) In-Reply-To: <1348045019-21532-1-git-send-email-aaron.lu@intel.com> Sender: linux-ide-owner@vger.kernel.org List-Id: linux-ide@vger.kernel.org To: Aaron Lu Cc: Jeff Garzik , Alan Stern , James Bottomley , linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, Aaron Lu On Wed, Sep 19, 2012 at 1:56 AM, Aaron Lu wrote: > scsi stop command is used to put a device into stopped power > condition, and scsi devices will take care of its internal cache > before entering this power condition. For ata devices, this command > should be translated to flush cache + standby immediate, currently, > we are translating it to only standby. > > This patch handle this by sending flush cache command when standby is > to be sent, and in its qc complete function, send the actual standby. > > This patch will be used to support poweroff hard disk either when > runtime or when system is going to S3/S4/S5. The sd_suspend will be > modified to only send a stop command to the device if device manages > start_stop, the current implementation will send a sync cache command, > which is not necessary per the scsi spec. > > Signed-off-by: Aaron Lu > --- > drivers/ata/libata-scsi.c | 32 ++++++++++++++++++++++++++++++-- > 1 file changed, 30 insertions(+), 2 deletions(-) > > diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c > index 8ec81ca..de6e734 100644 > --- a/drivers/ata/libata-scsi.c > +++ b/drivers/ata/libata-scsi.c > @@ -1759,6 +1759,27 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) > ata_qc_free(qc); > } > > +static void ata_flush_qc_complete(struct ata_queued_cmd *qc) > +{ > + if (qc->err_mask) { > + ata_gen_ata_sense(qc); > + qc->scsidone(qc->scsicmd); > + ata_qc_free(qc); > + } else { > + qc->complete_fn = ata_scsi_qc_complete; > + qc->tf.command = ATA_CMD_STANDBYNOW1; > + ata_qc_issue(qc); > + } > +} > + > +static void ata_qc_issue_flush(struct ata_queued_cmd *qc) > +{ > + qc->complete_fn = ata_flush_qc_complete; > + qc->tf.command = qc->dev->flags & ATA_DFLAG_FLUSH_EXT ? > + ATA_CMD_FLUSH_EXT : ATA_CMD_FLUSH; > + ata_qc_issue(qc); > +} > + > /** > * ata_scsi_translate - Translate then issue SCSI command to ATA device > * @dev: ATA device to which the command is addressed > @@ -1821,8 +1842,15 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, > goto defer; > } > > - /* select device, send command to hardware */ > - ata_qc_issue(qc); > + /* > + * If we received scsi stop command, > + * we will need to flush cache first > + */ > + if (qc->tf.command == ATA_CMD_STANDBYNOW1 && ata_try_flush_cache(dev)) You are adding tests on the data path. What about changing the xlat function ata_scsi_start_stop_xlat to - when stop is requested: - if try_flush_cache is true, change qc->complete_fn to ata_flush_qc_complete build a flush command - else do as usual. ata_flush_qc_complete remains the same. > + ata_qc_issue_flush(qc); > + else > + /* select device, send command to hardware */ > + ata_qc_issue(qc); > > VPRINTK("EXIT\n"); > return 0; > -- > 1.7.12.21.g871e293 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ide" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html