Explorar o código

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>
Alan %!s(int64=18) %!d(string=hai) anos
pai
achega
4112e16a7c
Modificáronse 1 ficheiros con 22 adicións e 0 borrados
  1. 22 0
      drivers/ata/libata-sff.c

+ 22 - 0
drivers/ata/libata-sff.c

@@ -832,6 +832,21 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
 }
 
 #ifdef CONFIG_PCI
+
+static int ata_resources_present(struct pci_dev *pdev, int port)
+{
+	int i;
+	
+	/* Check the PCI resources for this channel are enabled */
+	port = port * 2;
+	for (i = 0; i < 2; i ++) {
+		if (pci_resource_start(pdev, port + i) == 0 ||
+			pci_resource_len(pdev, port + i) == 0)
+		return 0;
+	}
+	return 1;
+}
+		
 /**
  *	ata_pci_init_native_mode - Initialize native-mode driver
  *	@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
 
 	probe_ent->irq = pdev->irq;
 	probe_ent->irq_flags = IRQF_SHARED;
+	
+	/* Discard disabled ports. Some controllers show their
+	   unused channels this way */
+	if (ata_resources_present(pdev, 0) == 0)
+		ports &= ~ATA_PORT_PRIMARY;
+	if (ata_resources_present(pdev, 1) == 0)
+		ports &= ~ATA_PORT_SECONDARY;
 
 	if (ports & ATA_PORT_PRIMARY) {
 		probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);