libata-core: Fix simplex handling

The initial simplex handling code is fooled if you suspend and resume.
This also causes problems with some single channel controllers which
claim to be simplex.

The fix is fairly simple, instead of keeping a flag to remember if we
gave away the simplex channel we remember the actual owner. As the owner
is always part of the host_set we don't even need a refcount.

Knowing the owner also means we can reassign simplex DMA channels in
future hotplug code etc if we need to

Signed-off-by: Alan Cox <alan@redhat.com>
(and a signed-off for the patch I sent before while I remember)
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Alan and committed by Jeff Garzik 032af1ce 562aa1d4

+3 -5
+2 -3
drivers/ata/libata-core.c
··· 2556 * host channels are not permitted to do so. 2557 */ 2558 if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX)) 2559 - ap->host->simplex_claimed = 1; 2560 2561 /* step5: chip specific finalisation */ 2562 if (ap->ops->post_set_mode) 2563 ap->ops->post_set_mode(ap); 2564 - 2565 out: 2566 if (rc) 2567 *r_failed_dev = dev; ··· 3443 "device is on DMA blacklist, disabling DMA\n"); 3444 } 3445 3446 - if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) { 3447 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); 3448 ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " 3449 "other device, disabling DMA\n");
··· 2556 * host channels are not permitted to do so. 2557 */ 2558 if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX)) 2559 + ap->host->simplex_claimed = ap; 2560 2561 /* step5: chip specific finalisation */ 2562 if (ap->ops->post_set_mode) 2563 ap->ops->post_set_mode(ap); 2564 out: 2565 if (rc) 2566 *r_failed_dev = dev; ··· 3444 "device is on DMA blacklist, disabling DMA\n"); 3445 } 3446 3447 + if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed != ap) { 3448 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); 3449 ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " 3450 "other device, disabling DMA\n");
+1 -2
include/linux/libata.h
··· 403 void *private_data; 404 const struct ata_port_operations *ops; 405 unsigned long flags; 406 - int simplex_claimed; /* Keep seperate in case we 407 - ever need to do this locked */ 408 struct ata_port *ports[0]; 409 }; 410
··· 403 void *private_data; 404 const struct ata_port_operations *ops; 405 unsigned long flags; 406 + struct ata_port *simplex_claimed; /* channel owning the DMA */ 407 struct ata_port *ports[0]; 408 }; 409