aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan <alan@lxorguk.ukuu.org.uk>2007-01-08 07:10:05 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 17:39:30 -0500
commit4112e16a7c606a80810d22d55bfc742eaa61fecb (patch)
treec48274decc14c4d71dd99f9c3f93087698e767f4 /drivers
parentd73f30e1c9a9af14757fa5bf4014343926047156 (diff)
libata-sff: Don't try and activate channels which are not in use
An ATA controller in native mode may have one or more channels disabled and not assigned resources. In that case the existing code crashes trying to access I/O ports 0-7. Add the neccessary check. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-sff.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 12c88c588039..cfa9ed179d9c 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -832,6 +832,21 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
832} 832}
833 833
834#ifdef CONFIG_PCI 834#ifdef CONFIG_PCI
835
836static int ata_resources_present(struct pci_dev *pdev, int port)
837{
838 int i;
839
840 /* Check the PCI resources for this channel are enabled */
841 port = port * 2;
842 for (i = 0; i < 2; i ++) {
843 if (pci_resource_start(pdev, port + i) == 0 ||
844 pci_resource_len(pdev, port + i) == 0)
845 return 0;
846 }
847 return 1;
848}
849
835/** 850/**
836 * ata_pci_init_native_mode - Initialize native-mode driver 851 * ata_pci_init_native_mode - Initialize native-mode driver
837 * @pdev: pci device to be initialized 852 * @pdev: pci device to be initialized
@@ -863,6 +878,13 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
863 878
864 probe_ent->irq = pdev->irq; 879 probe_ent->irq = pdev->irq;
865 probe_ent->irq_flags = IRQF_SHARED; 880 probe_ent->irq_flags = IRQF_SHARED;
881
882 /* Discard disabled ports. Some controllers show their
883 unused channels this way */
884 if (ata_resources_present(pdev, 0) == 0)
885 ports &= ~ATA_PORT_PRIMARY;
886 if (ata_resources_present(pdev, 1) == 0)
887 ports &= ~ATA_PORT_SECONDARY;
866 888
867 if (ports & ATA_PORT_PRIMARY) { 889 if (ports & ATA_PORT_PRIMARY) {
868 probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); 890 probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);