pata_cm64x: fix boot crash on parisc
The old IDE cmd64x checks the status of the CNTRL register to see if the ports are enabled before probing them. pata_cmd64x doesn't do this, which causes a HPMC on parisc when it tries to poke at the secondary port because apparently the BAR isn't wired up (and a non-responding piece of memory causes a HPMC). Fix this by porting the CNTRL register port detection logic from IDE cmd64x. In addition, following converns from Alan Cox, add a check to see if a mobility electronics bridge is the immediate parent and forgo the check if it is (prevents problems on hotplug controllers). Signed-off-by: James Bottomley <James.Bottomley@suse.de> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
		
					parent
					
						
							
								5f6f12ccf3
							
						
					
				
			
			
				commit
				
					
						9281b16caa
					
				
			
		
					 2 changed files with 40 additions and 4 deletions
				
			
		|  | @ -41,6 +41,9 @@ | ||||||
| enum { | enum { | ||||||
| 	CFR 		= 0x50, | 	CFR 		= 0x50, | ||||||
| 		CFR_INTR_CH0  = 0x04, | 		CFR_INTR_CH0  = 0x04, | ||||||
|  | 	CNTRL		= 0x51, | ||||||
|  | 		CNTRL_CH0     = 0x04, | ||||||
|  | 		CNTRL_CH1     = 0x08, | ||||||
| 	CMDTIM 		= 0x52, | 	CMDTIM 		= 0x52, | ||||||
| 	ARTTIM0 	= 0x53, | 	ARTTIM0 	= 0x53, | ||||||
| 	DRWTIM0 	= 0x54, | 	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 | 			.port_ops = &cmd648_port_ops | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 	const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; | 	const struct ata_port_info *ppi[] = {  | ||||||
| 	u8 mrdmode; | 		&cmd_info[id->driver_data], | ||||||
|  | 		&cmd_info[id->driver_data], | ||||||
|  | 		NULL | ||||||
|  | 	}; | ||||||
|  | 	u8 mrdmode, reg; | ||||||
| 	int rc; | 	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); | 	rc = pcim_enable_device(pdev); | ||||||
| 	if (rc) | 	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) { | 	if (pdev->device == PCI_DEVICE_ID_CMD_646) { | ||||||
| 		/* Does UDMA work ? */ | 		/* Does UDMA work ? */ | ||||||
| 		if (pdev->revision > 4) | 		if (pdev->revision > 4) { | ||||||
| 			ppi[0] = &cmd_info[2]; | 			ppi[0] = &cmd_info[2]; | ||||||
|  | 			ppi[1] = &cmd_info[2]; | ||||||
|  | 		} | ||||||
| 		/* Early rev with other problems ? */ | 		/* Early rev with other problems ? */ | ||||||
| 		else if (pdev->revision == 1) | 		else if (pdev->revision == 1) { | ||||||
| 			ppi[0] = &cmd_info[3]; | 			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); | 	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 */ | 	mrdmode |= 0x02;	/* Memory read line enable */ | ||||||
| 	pci_write_config_byte(pdev, MRDMODE, mrdmode); | 	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.. */ | 	/* Force PIO 0 here.. */ | ||||||
| 
 | 
 | ||||||
| 	/* PPC specific fixup copied from old driver */ | 	/* PPC specific fixup copied from old driver */ | ||||||
|  |  | ||||||
|  | @ -608,6 +608,8 @@ | ||||||
| #define PCI_DEVICE_ID_MATROX_G550	0x2527 | #define PCI_DEVICE_ID_MATROX_G550	0x2527 | ||||||
| #define PCI_DEVICE_ID_MATROX_VIA	0x4536 | #define PCI_DEVICE_ID_MATROX_VIA	0x4536 | ||||||
| 
 | 
 | ||||||
|  | #define PCI_VENDOR_ID_MOBILITY_ELECTRONICS	0x14f2 | ||||||
|  | 
 | ||||||
| #define PCI_VENDOR_ID_CT		0x102c | #define PCI_VENDOR_ID_CT		0x102c | ||||||
| #define PCI_DEVICE_ID_CT_69000		0x00c0 | #define PCI_DEVICE_ID_CT_69000		0x00c0 | ||||||
| #define PCI_DEVICE_ID_CT_65545		0x00d8 | #define PCI_DEVICE_ID_CT_65545		0x00d8 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 James Bottomley
				James Bottomley