diff options
Diffstat (limited to 'drivers/ata/pata_cmd64x.c')
| -rw-r--r-- | drivers/ata/pata_cmd64x.c | 42 | 
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 905ff76d3cb..7bafc16cf5e 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -41,6 +41,9 @@  enum {  	CFR 		= 0x50,  		CFR_INTR_CH0  = 0x04, +	CNTRL		= 0x51, +		CNTRL_CH0     = 0x04, +		CNTRL_CH1     = 0x08,  	CMDTIM 		= 0x52,  	ARTTIM0 	= 0x53,  	DRWTIM0 	= 0x54, @@ -328,9 +331,19 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)  			.port_ops = &cmd648_port_ops  		}  	}; -	const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; -	u8 mrdmode; +	const struct ata_port_info *ppi[] = {  +		&cmd_info[id->driver_data], +		&cmd_info[id->driver_data], +		NULL +	}; +	u8 mrdmode, reg;  	int rc; +	struct pci_dev *bridge = pdev->bus->self; +	/* mobility split bridges don't report enabled ports correctly */ +	int port_ok = !(bridge && bridge->vendor == +			PCI_VENDOR_ID_MOBILITY_ELECTRONICS); +	/* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */ +	int cntrl_ch0_ok = (id->driver_data != 0);  	rc = pcim_enable_device(pdev);  	if (rc) @@ -341,11 +354,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)  	if (pdev->device == PCI_DEVICE_ID_CMD_646) {  		/* Does UDMA work ? */ -		if (pdev->revision > 4) +		if (pdev->revision > 4) {  			ppi[0] = &cmd_info[2]; +			ppi[1] = &cmd_info[2]; +		}  		/* Early rev with other problems ? */ -		else if (pdev->revision == 1) +		else if (pdev->revision == 1) {  			ppi[0] = &cmd_info[3]; +			ppi[1] = &cmd_info[3]; +		} +		/* revs 1,2 have no CNTRL_CH0 */ +		if (pdev->revision < 3) +			cntrl_ch0_ok = 0;  	}  	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); @@ -354,6 +374,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)  	mrdmode |= 0x02;	/* Memory read line enable */  	pci_write_config_byte(pdev, MRDMODE, mrdmode); +	/* check for enabled ports */ +	pci_read_config_byte(pdev, CNTRL, ®); +	if (!port_ok) +		dev_printk(KERN_NOTICE, &pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n"); +	if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) { +		dev_printk(KERN_NOTICE, &pdev->dev, "Primary port is disabled\n"); +		ppi[0] = &ata_dummy_port_info; +		 +	} +	if (port_ok && !(reg & CNTRL_CH1)) { +		dev_printk(KERN_NOTICE, &pdev->dev, "Secondary port is disabled\n"); +		ppi[1] = &ata_dummy_port_info; +	} +  	/* Force PIO 0 here.. */  	/* PPC specific fixup copied from old driver */  |