diff options
Diffstat (limited to 'drivers/dma/ioat')
-rw-r--r-- | drivers/dma/ioat/dca.c | 23 | ||||
-rw-r--r-- | drivers/dma/ioat/pci.c | 2 |
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index abd9038e06b..d6668071bd0 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c @@ -604,6 +604,23 @@ static int ioat3_dca_count_dca_slots(void *iobase, u16 dca_offset) return slots; } +static inline int dca3_tag_map_invalid(u8 *tag_map) +{ + /* + * If the tag map is not programmed by the BIOS the default is: + * 0x80 0x80 0x80 0x80 0x80 0x00 0x00 0x00 + * + * This an invalid map and will result in only 2 possible tags + * 0x1F and 0x00. 0x00 is an invalid DCA tag so we know that + * this entire definition is invalid. + */ + return ((tag_map[0] == DCA_TAG_MAP_VALID) && + (tag_map[1] == DCA_TAG_MAP_VALID) && + (tag_map[2] == DCA_TAG_MAP_VALID) && + (tag_map[3] == DCA_TAG_MAP_VALID) && + (tag_map[4] == DCA_TAG_MAP_VALID)); +} + struct dca_provider * __devinit ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase) { @@ -674,6 +691,12 @@ ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase) ioatdca->tag_map[i] = bit & DCA_TAG_MAP_MASK; } + if (dca3_tag_map_invalid(ioatdca->tag_map)) { + dev_err(&pdev->dev, "APICID_TAG_MAP set incorrectly by BIOS, disabling DCA\n"); + free_dca_provider(dca); + return NULL; + } + err = register_dca_provider(dca, &pdev->dev); if (err) { free_dca_provider(dca); diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c index c0573061b45..bfa9a3536e0 100644 --- a/drivers/dma/ioat/pci.c +++ b/drivers/dma/ioat/pci.c @@ -125,7 +125,7 @@ static struct pci_driver ioat_pci_driver = { .name = DRV_NAME, .id_table = ioat_pci_tbl, .probe = ioat_pci_probe, - .remove = __devexit_p(ioat_remove), + .remove = ioat_remove, }; static struct ioatdma_device * |