/[linux-patches]/genpatches-2.6/tags/2.6.21-4/2114_libata-shutdown-warning.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.21-4/2114_libata-shutdown-warning.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 974 - (show annotations) (download)
Thu May 24 23:17:59 2007 UTC (10 years, 8 months ago) by dsd
File size: 3064 byte(s)
2.6.21-4 release
1 From da071b42f73dabbd0daf7ea4c3ff157d53b00648 Mon Sep 17 00:00:00 2001
2 From: Tejun Heo <htejun@gmail.com>
3 Date: Mon, 14 May 2007 17:26:18 +0200
4 Subject: [PATCH] libata: fix shutdown warning message printing
5
6 Unlocking ap->lock and ssleeping don't work because SCSI commands can
7 be issued from completion path without context. Reimplement delayed
8 completion by allowing translation functions to override
9 qc->scsidone(), storing the original completion function to
10 scmd->scsi_done() and overriding qc->scsidone() with a function which
11 schedules delayed invocation of scmd->scsi_done().
12
13 This isn't pretty at all but all the ugly parts are thankfully
14 contained in the stop translation path where the compat feature is
15 implemented.
16
17 Signed-off-by: Tejun Heo <htejun@gmail.com>
18 Signed-off-by: Jeff Garzik <jeff@garzik.org>
19 ---
20 drivers/ata/libata-scsi.c | 35 +++++++++++++++++++++++++++--------
21 1 files changed, 27 insertions(+), 8 deletions(-)
22
23 diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
24 index dd81fa7..07b5a3d 100644
25 --- a/drivers/ata/libata-scsi.c
26 +++ b/drivers/ata/libata-scsi.c
27 @@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
28 return queue_depth;
29 }
30
31 +/* XXX: for ata_spindown_compat */
32 +static void ata_delayed_done_timerfn(unsigned long arg)
33 +{
34 + struct scsi_cmnd *scmd = (void *)arg;
35 +
36 + scmd->scsi_done(scmd);
37 +}
38 +
39 +/* XXX: for ata_spindown_compat */
40 +static void ata_delayed_done(struct scsi_cmnd *scmd)
41 +{
42 + static struct timer_list timer;
43 +
44 + setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
45 + mod_timer(&timer, jiffies + 5 * HZ);
46 +}
47 +
48 /**
49 * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
50 * @qc: Storage for translated ATA taskfile
51 @@ -952,19 +969,21 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
52 if (ata_spindown_compat &&
53 (system_state == SYSTEM_HALT ||
54 system_state == SYSTEM_POWER_OFF)) {
55 - static int warned = 0;
56 + static unsigned long warned = 0;
57
58 - if (!warned) {
59 - spin_unlock_irq(qc->ap->lock);
60 + if (!test_and_set_bit(0, &warned)) {
61 ata_dev_printk(qc->dev, KERN_WARNING,
62 "DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
63 "UPDATE SHUTDOWN UTILITY\n");
64 ata_dev_printk(qc->dev, KERN_WARNING,
65 "For more info, visit "
66 "http://linux-ata.org/shutdown.html\n");
67 - warned = 1;
68 - ssleep(5);
69 - spin_lock_irq(qc->ap->lock);
70 +
71 + /* ->scsi_done is not used, use it for
72 + * delayed completion.
73 + */
74 + scmd->scsi_done = qc->scsidone;
75 + qc->scsidone = ata_delayed_done;
76 }
77 scmd->result = SAM_STAT_GOOD;
78 return 1;
79 @@ -1488,14 +1507,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
80
81 early_finish:
82 ata_qc_free(qc);
83 - done(cmd);
84 + qc->scsidone(cmd);
85 DPRINTK("EXIT - early finish (good or error)\n");
86 return 0;
87
88 err_did:
89 ata_qc_free(qc);
90 cmd->result = (DID_ERROR << 16);
91 - done(cmd);
92 + qc->scsidone(cmd);
93 err_mem:
94 DPRINTK("EXIT - internal\n");
95 return 0;
96 --
97 1.5.1.4
98

  ViewVC Help
Powered by ViewVC 1.1.20