diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2007-07-09 14:46:13 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-10 20:55:04 -0400 |
commit | 45a66c1c3ff88e8050dd25e81bafdf79a12a8042 (patch) | |
tree | 05b8ae20d034ffe16e0f13b51f43aa9f93eddf2f | |
parent | 4c75f7416f51b0c6855952467a5db04f9c598f09 (diff) |
libata-core: convert to use cancel_rearming_delayed_work()
We should not use cancel_work_sync(delayed_work->work). This works, but not
good. We can use cancel_rearming_delayed_work(), this also simplifies the
code.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/libata-core.c | 44 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
2 files changed, 4 insertions, 41 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5b25311ba885..257fda90e527 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1283,18 +1283,11 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
1283 | void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, | 1283 | void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, |
1284 | unsigned long delay) | 1284 | unsigned long delay) |
1285 | { | 1285 | { |
1286 | int rc; | ||
1287 | |||
1288 | if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK) | ||
1289 | return; | ||
1290 | |||
1291 | PREPARE_DELAYED_WORK(&ap->port_task, fn); | 1286 | PREPARE_DELAYED_WORK(&ap->port_task, fn); |
1292 | ap->port_task_data = data; | 1287 | ap->port_task_data = data; |
1293 | 1288 | ||
1294 | rc = queue_delayed_work(ata_wq, &ap->port_task, delay); | 1289 | /* may fail if ata_port_flush_task() in progress */ |
1295 | 1290 | queue_delayed_work(ata_wq, &ap->port_task, delay); | |
1296 | /* rc == 0 means that another user is using port task */ | ||
1297 | WARN_ON(rc == 0); | ||
1298 | } | 1291 | } |
1299 | 1292 | ||
1300 | /** | 1293 | /** |
@@ -1309,32 +1302,9 @@ void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, | |||
1309 | */ | 1302 | */ |
1310 | void ata_port_flush_task(struct ata_port *ap) | 1303 | void ata_port_flush_task(struct ata_port *ap) |
1311 | { | 1304 | { |
1312 | unsigned long flags; | ||
1313 | |||
1314 | DPRINTK("ENTER\n"); | 1305 | DPRINTK("ENTER\n"); |
1315 | 1306 | ||
1316 | spin_lock_irqsave(ap->lock, flags); | 1307 | cancel_rearming_delayed_work(&ap->port_task); |
1317 | ap->pflags |= ATA_PFLAG_FLUSH_PORT_TASK; | ||
1318 | spin_unlock_irqrestore(ap->lock, flags); | ||
1319 | |||
1320 | DPRINTK("flush #1\n"); | ||
1321 | cancel_work_sync(&ap->port_task.work); /* akpm: seems unneeded */ | ||
1322 | |||
1323 | /* | ||
1324 | * At this point, if a task is running, it's guaranteed to see | ||
1325 | * the FLUSH flag; thus, it will never queue pio tasks again. | ||
1326 | * Cancel and flush. | ||
1327 | */ | ||
1328 | if (!cancel_delayed_work(&ap->port_task)) { | ||
1329 | if (ata_msg_ctl(ap)) | ||
1330 | ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", | ||
1331 | __FUNCTION__); | ||
1332 | cancel_work_sync(&ap->port_task.work); | ||
1333 | } | ||
1334 | |||
1335 | spin_lock_irqsave(ap->lock, flags); | ||
1336 | ap->pflags &= ~ATA_PFLAG_FLUSH_PORT_TASK; | ||
1337 | spin_unlock_irqrestore(ap->lock, flags); | ||
1338 | 1308 | ||
1339 | if (ata_msg_ctl(ap)) | 1309 | if (ata_msg_ctl(ap)) |
1340 | ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); | 1310 | ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); |
@@ -6557,13 +6527,7 @@ void ata_port_detach(struct ata_port *ap) | |||
6557 | spin_unlock_irqrestore(ap->lock, flags); | 6527 | spin_unlock_irqrestore(ap->lock, flags); |
6558 | 6528 | ||
6559 | ata_port_wait_eh(ap); | 6529 | ata_port_wait_eh(ap); |
6560 | 6530 | cancel_rearming_delayed_work(&ap->hotplug_task); | |
6561 | /* Flush hotplug task. The sequence is similar to | ||
6562 | * ata_port_flush_task(). | ||
6563 | */ | ||
6564 | cancel_work_sync(&ap->hotplug_task.work); /* akpm: why? */ | ||
6565 | cancel_delayed_work(&ap->hotplug_task); | ||
6566 | cancel_work_sync(&ap->hotplug_task.work); | ||
6567 | 6531 | ||
6568 | skip_eh: | 6532 | skip_eh: |
6569 | /* remove the associated SCSI host */ | 6533 | /* remove the associated SCSI host */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index a3df64677ac3..bf98d44c8109 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -196,7 +196,6 @@ enum { | |||
196 | ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ | 196 | ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ |
197 | ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */ | 197 | ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */ |
198 | 198 | ||
199 | ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ | ||
200 | ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ | 199 | ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ |
201 | ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ | 200 | ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ |
202 | ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ | 201 | ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ |