forked from Minki/linux
[PATCH] libata: BMDMA handling updates
This is the minimal patch set to enable the current code to be used with a controller following SFF (ie any PATA and early SATA controllers) safely without crashes if there is no BMDMA area or if BMDMA is not assigned by the BIOS for some reason. Simplex status is recorded but not acted upon in this change, this isn't a problem with the current drivers as none of them are for simplex hardware. A following diff will deal with that. The flags in the probe structure remain ->host_set_flags although Jeff asked me to rename them, simply because the rename would break the usual Linux rules that old code should break when there are changes. not compile and run and then blow up/eat your computer/etc. Renaming this later is a trivial exercise once a better name is chosen. Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
05c8e0ac5c
commit
4e5ec5dba2
@ -703,6 +703,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
|
|||||||
struct ata_probe_ent *probe_ent =
|
struct ata_probe_ent *probe_ent =
|
||||||
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
|
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
unsigned long bmdma;
|
||||||
|
|
||||||
if (!probe_ent)
|
if (!probe_ent)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -716,7 +717,12 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
|
|||||||
probe_ent->port[p].altstatus_addr =
|
probe_ent->port[p].altstatus_addr =
|
||||||
probe_ent->port[p].ctl_addr =
|
probe_ent->port[p].ctl_addr =
|
||||||
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
|
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
|
||||||
probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
|
bmdma = pci_resource_start(pdev, 4);
|
||||||
|
if (bmdma) {
|
||||||
|
if (inb(bmdma + 2) & 0x80)
|
||||||
|
probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
|
||||||
|
probe_ent->port[p].bmdma_addr = bmdma;
|
||||||
|
}
|
||||||
ata_std_ports(&probe_ent->port[p]);
|
ata_std_ports(&probe_ent->port[p]);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
@ -726,7 +732,13 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
|
|||||||
probe_ent->port[p].altstatus_addr =
|
probe_ent->port[p].altstatus_addr =
|
||||||
probe_ent->port[p].ctl_addr =
|
probe_ent->port[p].ctl_addr =
|
||||||
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
|
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
|
||||||
probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
|
bmdma = pci_resource_start(pdev, 4);
|
||||||
|
if (bmdma) {
|
||||||
|
bmdma += 8;
|
||||||
|
if(inb(bmdma + 2) & 0x80)
|
||||||
|
probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
|
||||||
|
probe_ent->port[p].bmdma_addr = bmdma;
|
||||||
|
}
|
||||||
ata_std_ports(&probe_ent->port[p]);
|
ata_std_ports(&probe_ent->port[p]);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
@ -740,6 +752,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
|||||||
struct ata_port_info *port, int port_num)
|
struct ata_port_info *port, int port_num)
|
||||||
{
|
{
|
||||||
struct ata_probe_ent *probe_ent;
|
struct ata_probe_ent *probe_ent;
|
||||||
|
unsigned long bmdma;
|
||||||
|
|
||||||
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
|
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
|
||||||
if (!probe_ent)
|
if (!probe_ent)
|
||||||
@ -766,8 +779,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
probe_ent->port[0].bmdma_addr =
|
bmdma = pci_resource_start(pdev, 4);
|
||||||
pci_resource_start(pdev, 4) + 8 * port_num;
|
if (bmdma != 0) {
|
||||||
|
bmdma += 8 * port_num;
|
||||||
|
probe_ent->port[0].bmdma_addr = bmdma;
|
||||||
|
if (inb(bmdma + 2) & 0x80)
|
||||||
|
probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
|
||||||
|
}
|
||||||
ata_std_ports(&probe_ent->port[0]);
|
ata_std_ports(&probe_ent->port[0]);
|
||||||
|
|
||||||
return probe_ent;
|
return probe_ent;
|
||||||
|
@ -160,6 +160,9 @@ enum {
|
|||||||
ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
|
ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
|
||||||
ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */
|
ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */
|
||||||
|
|
||||||
|
/* host set flags */
|
||||||
|
ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */
|
||||||
|
|
||||||
/* various lengths of time */
|
/* various lengths of time */
|
||||||
ATA_TMOUT_PIO = 30 * HZ,
|
ATA_TMOUT_PIO = 30 * HZ,
|
||||||
ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
|
ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
|
||||||
@ -278,6 +281,7 @@ struct ata_probe_ent {
|
|||||||
unsigned long irq;
|
unsigned long irq;
|
||||||
unsigned int irq_flags;
|
unsigned int irq_flags;
|
||||||
unsigned long host_flags;
|
unsigned long host_flags;
|
||||||
|
unsigned long host_set_flags;
|
||||||
void __iomem *mmio_base;
|
void __iomem *mmio_base;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user