linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libata: fix shutdown warning message printing
@ 2007-05-14 15:26 Tejun Heo
  2007-05-14 15:45 ` James Bottomley
  2007-05-16  5:22 ` Jeff Garzik
  0 siblings, 2 replies; 3+ messages in thread
From: Tejun Heo @ 2007-05-14 15:26 UTC (permalink / raw)
  To: Jeff Garzik, linux-kernel, IDE/ATA development list,
	James Bottomley, Andrew Morton

Unlocking ap->lock and ssleeping don't work because SCSI commands can
be issued from completion path without context.  Reimplement delayed
completion by allowing translation functions to override
qc->scsidone(), storing the original completion function to
scmd->scsi_done() and overriding qc->scsidone() with a function which
schedules delayed invocation of scmd->scsi_done().

This isn't pretty at all but all the ugly parts are thankfully
contained in the stop translation path where the compat feature is
implemented.

Signed-off-by: Tejun Heo <htejun@gmail.com>

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index dd81fa7..07b5a3d 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct s
 	return queue_depth;
 }
 
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done_timerfn(unsigned long arg)
+{
+	struct scsi_cmnd *scmd = (void *)arg;
+
+	scmd->scsi_done(scmd);
+}
+
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done(struct scsi_cmnd *scmd)
+{
+	static struct timer_list timer;
+
+	setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
+	mod_timer(&timer, jiffies + 5 * HZ);
+}
+
 /**
  *	ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *	@qc: Storage for translated ATA taskfile
@@ -952,19 +969,21 @@ static unsigned int ata_scsi_start_stop_
 		if (ata_spindown_compat &&
 		    (system_state == SYSTEM_HALT ||
 		     system_state == SYSTEM_POWER_OFF)) {
-			static int warned = 0;
+			static unsigned long warned = 0;
 
-			if (!warned) {
-				spin_unlock_irq(qc->ap->lock);
+			if (!test_and_set_bit(0, &warned)) {
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
 					"UPDATE SHUTDOWN UTILITY\n");
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"For more info, visit "
 					"http://linux-ata.org/shutdown.html\n");
-				warned = 1;
-				ssleep(5);
-				spin_lock_irq(qc->ap->lock);
+
+				/* ->scsi_done is not used, use it for
+				 * delayed completion.
+				 */
+				scmd->scsi_done = qc->scsidone;
+				qc->scsidone = ata_delayed_done;
 			}
 			scmd->result = SAM_STAT_GOOD;
 			return 1;
@@ -1488,14 +1507,14 @@ static int ata_scsi_translate(struct ata
 
 early_finish:
         ata_qc_free(qc);
-	done(cmd);
+	qc->scsidone(cmd);
 	DPRINTK("EXIT - early finish (good or error)\n");
 	return 0;
 
 err_did:
 	ata_qc_free(qc);
 	cmd->result = (DID_ERROR << 16);
-	done(cmd);
+	qc->scsidone(cmd);
 err_mem:
 	DPRINTK("EXIT - internal\n");
 	return 0;

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] libata: fix shutdown warning message printing
  2007-05-14 15:26 [PATCH] libata: fix shutdown warning message printing Tejun Heo
@ 2007-05-14 15:45 ` James Bottomley
  2007-05-16  5:22 ` Jeff Garzik
  1 sibling, 0 replies; 3+ messages in thread
From: James Bottomley @ 2007-05-14 15:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Jeff Garzik, linux-kernel, IDE/ATA development list,
	Andrew Morton

On Mon, 2007-05-14 at 17:26 +0200, Tejun Heo wrote:
> Unlocking ap->lock and ssleeping don't work because SCSI commands can
> be issued from completion path without context.  Reimplement delayed
> completion by allowing translation functions to override
> qc->scsidone(), storing the original completion function to
> scmd->scsi_done() and overriding qc->scsidone() with a function which
> schedules delayed invocation of scmd->scsi_done().
> 
> This isn't pretty at all but all the ugly parts are thankfully
> contained in the stop translation path where the compat feature is
> implemented.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

Heh, very clever, but a bit of  a hack (however, no better way I can see
to do it given the layering constraints).

Acked-by: James Bottomley <James.Bottomley@SteelEye.com>

James



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libata: fix shutdown warning message printing
  2007-05-14 15:26 [PATCH] libata: fix shutdown warning message printing Tejun Heo
  2007-05-14 15:45 ` James Bottomley
@ 2007-05-16  5:22 ` Jeff Garzik
  1 sibling, 0 replies; 3+ messages in thread
From: Jeff Garzik @ 2007-05-16  5:22 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-kernel, IDE/ATA development list, James Bottomley,
	Andrew Morton

Tejun Heo wrote:
> Unlocking ap->lock and ssleeping don't work because SCSI commands can
> be issued from completion path without context.  Reimplement delayed
> completion by allowing translation functions to override
> qc->scsidone(), storing the original completion function to
> scmd->scsi_done() and overriding qc->scsidone() with a function which
> schedules delayed invocation of scmd->scsi_done().
> 
> This isn't pretty at all but all the ugly parts are thankfully
> contained in the stop translation path where the compat feature is
> implemented.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

applied to #upstream-fixes



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-05-16  5:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-14 15:26 [PATCH] libata: fix shutdown warning message printing Tejun Heo
2007-05-14 15:45 ` James Bottomley
2007-05-16  5:22 ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).