libata: implement ATA_FLAG_IGN_SIMPLEX and use it in sata_uli
Some uli controllers have stuck SIMPLEX bit which can't be cleared with ata_pci_clear_simplex(), but the controller is capable of doing DMAs on both channels simultaneously. Implement ATA_FLAG_IGN_SIMPLEX which makes libata ignore the simplex bit and use it in sata_uli. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
@@ -870,7 +870,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
|
|||||||
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
|
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
|
||||||
bmdma = pci_resource_start(pdev, 4);
|
bmdma = pci_resource_start(pdev, 4);
|
||||||
if (bmdma) {
|
if (bmdma) {
|
||||||
if (inb(bmdma + 2) & 0x80)
|
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||||
|
(inb(bmdma + 2) & 0x80))
|
||||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||||
probe_ent->port[p].bmdma_addr = bmdma;
|
probe_ent->port[p].bmdma_addr = bmdma;
|
||||||
}
|
}
|
||||||
@@ -886,7 +887,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
|
|||||||
bmdma = pci_resource_start(pdev, 4);
|
bmdma = pci_resource_start(pdev, 4);
|
||||||
if (bmdma) {
|
if (bmdma) {
|
||||||
bmdma += 8;
|
bmdma += 8;
|
||||||
if(inb(bmdma + 2) & 0x80)
|
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||||
|
(inb(bmdma + 2) & 0x80))
|
||||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||||
probe_ent->port[p].bmdma_addr = bmdma;
|
probe_ent->port[p].bmdma_addr = bmdma;
|
||||||
}
|
}
|
||||||
@@ -920,7 +922,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
|||||||
probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL;
|
probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL;
|
||||||
if (bmdma) {
|
if (bmdma) {
|
||||||
probe_ent->port[0].bmdma_addr = bmdma;
|
probe_ent->port[0].bmdma_addr = bmdma;
|
||||||
if (inb(bmdma + 2) & 0x80)
|
if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||||
|
(inb(bmdma + 2) & 0x80))
|
||||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||||
}
|
}
|
||||||
ata_std_ports(&probe_ent->port[0]);
|
ata_std_ports(&probe_ent->port[0]);
|
||||||
@@ -937,7 +940,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
|||||||
probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
|
probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
|
||||||
if (bmdma) {
|
if (bmdma) {
|
||||||
probe_ent->port[1].bmdma_addr = bmdma + 8;
|
probe_ent->port[1].bmdma_addr = bmdma + 8;
|
||||||
if (inb(bmdma + 10) & 0x80)
|
if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||||
|
(inb(bmdma + 10) & 0x80))
|
||||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||||
}
|
}
|
||||||
ata_std_ports(&probe_ent->port[1]);
|
ata_std_ports(&probe_ent->port[1]);
|
||||||
|
@@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = {
|
|||||||
|
|
||||||
static struct ata_port_info uli_port_info = {
|
static struct ata_port_info uli_port_info = {
|
||||||
.sht = &uli_sht,
|
.sht = &uli_sht,
|
||||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||||
|
ATA_FLAG_IGN_SIMPLEX,
|
||||||
.pio_mask = 0x1f, /* pio0-4 */
|
.pio_mask = 0x1f, /* pio0-4 */
|
||||||
.udma_mask = 0x7f, /* udma0-6 */
|
.udma_mask = 0x7f, /* udma0-6 */
|
||||||
.port_ops = &uli_ops,
|
.port_ops = &uli_ops,
|
||||||
|
@@ -177,6 +177,7 @@ enum {
|
|||||||
* Register FIS clearing BSY */
|
* Register FIS clearing BSY */
|
||||||
ATA_FLAG_DEBUGMSG = (1 << 13),
|
ATA_FLAG_DEBUGMSG = (1 << 13),
|
||||||
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
|
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
|
||||||
|
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
|
||||||
|
|
||||||
/* The following flag belongs to ap->pflags but is kept in
|
/* The following flag belongs to ap->pflags but is kept in
|
||||||
* ap->flags because it's referenced in many LLDs and will be
|
* ap->flags because it's referenced in many LLDs and will be
|
||||||
|
Reference in New Issue
Block a user