diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 44 |
1 files changed, 4 insertions, 40 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 */ |