aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c44
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)
1283void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, 1283void 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 */
1310void ata_port_flush_task(struct ata_port *ap) 1303void 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 */