 if(dmabase) { did = inb(dmabase + 0x22); rid = inb(dmabase + 0x28);  if((did == 4 && rid == 6) || (did == 5 && rid > 1)) is_372n = 1; }  /* * default to pci clock. make sure MA15/16 are set to output * to prevent drives having problems with 40-pin cables. */ pci_write_config_byte(dev, 0x5b, 0x23);  /* * set up the PLL. we need to adjust it so that it's stable. * freq = Tpll * 192 / Tpci * * Todo. For non x86 should probably check the dword is * set to 0xABCDExxx indicating the BIOS saved f_CNT */ pci_read_config_word(dev, 0x78, &freq); freq &= 0x1FF;  /* * The 372N uses different PCI clock information and has * some other complications *	On PCI33 timing we must clock switch *	On PCI66 timing we must NOT use the PCI clock * * Currently we always set up the PLL for the 372N */  pci_set_drvdata(dev, NULL);  if(is_372n) { printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n"); if(freq < 0x55) pll = F_LOW_PCI_33; else if(freq < 0x70) pll = F_LOW_PCI_40; else if(freq < 0x7F) pll = F_LOW_PCI_50; else pll = F_LOW_PCI_66;  printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll);  /* We always use the pll not the PCI clock on 372N */ } else { if(freq < 0x9C) pll = F_LOW_PCI_33; else if(freq < 0xb0) pll = F_LOW_PCI_40; else if(freq <0xc8) pll = F_LOW_PCI_50; else pll = F_LOW_PCI_66;  if (pll == F_LOW_PCI_33) { if (hpt_minimum_revision(dev,8)) pci_set_drvdata(dev, (void *) thirty_three_base_hpt374); else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) thirty_three_base_hpt372); else if (hpt_minimum_revision(dev,4)) pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a); else pci_set_drvdata(dev, (void *) thirty_three_base_hpt370); printk("HPT37X: using 33MHz PCI clock\n"); } else if (pll == F_LOW_PCI_40) { /* Unsupported */ } else if (pll == F_LOW_PCI_50) { if (hpt_minimum_revision(dev,8)) pci_set_drvdata(dev, (void *) fifty_base_hpt370a); else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) fifty_base_hpt372); else if (hpt_minimum_revision(dev,4)) pci_set_drvdata(dev, (void *) fifty_base_hpt370a); else pci_set_drvdata(dev, (void *) fifty_base_hpt370a); printk("HPT37X: using 50MHz PCI clock\n"); } else { if (hpt_minimum_revision(dev,8)) { printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); } else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) sixty_six_base_hpt372); else if (hpt_minimum_revision(dev,4)) pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a); else pci_set_drvdata(dev, (void *) sixty_six_base_hpt370); printk("HPT37X: using 66MHz PCI clock\n"); } }  /* * only try the pll if we don't have a table for the clock * speed that we're running at. NOTE: the internal PLL will * result in slow reads when using a 33MHz PCI clock. we also * don't like to use the PLL because it will cause glitches * on PRST/SRST when the HPT state engine gets reset. */ if (pci_get_drvdata(dev)) goto init_hpt37X_done;  /* * adjust PLL based upon PCI clock, enable it, and wait for * stabilization. */ adjust = 0; freq = (pll < F_LOW_PCI_50) ? 2 : 4; while (adjust++ < 6) { pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | pll | 0x100);  /* wait for clock stabilization */ for (i = 0; i < 0x50000; i++) { pci_read_config_byte(dev, 0x5b, &reg5bh); if (reg5bh & 0x80) { /* spin looking for the clock to destabilize */ for (i = 0; i < 0x1000; ++i) { pci_read_config_byte(dev, 0x5b, &reg5bh); if ((reg5bh & 0x80) == 0) goto pll_recal; } pci_read_config_dword(dev, 0x5c, &pll); pci_write_config_dword(dev, 0x5c, pll & ~0x100); pci_write_config_byte(dev, 0x5b, 0x21); if (hpt_minimum_revision(dev,8)) pci_set_drvdata(dev, (void *) fifty_base_hpt370a); else if (hpt_minimum_revision(dev,5)) pci_set_drvdata(dev, (void *) fifty_base_hpt372); else if (hpt_minimum_revision(dev,4)) pci_set_drvdata(dev, (void *) fifty_base_hpt370a); else pci_set_drvdata(dev, (void *) fifty_base_hpt370a); printk("HPT37X: using 50MHz internal PLL\n"); goto init_hpt37X_done; } } pll_recal: if (adjust & 1) pll -= (adjust >> 1); else pll += (adjust >> 1); }  init_hpt37X_done: /* reset state engine */ pci_write_config_byte(dev, 0x50, 0x37); pci_write_config_byte(dev, 0x54, 0x37); udelay(100); 
static int __devinit init_hpt37x(struct pci_dev *dev){	int adjust, i;	u16 freq;	u32 pll;	u8 reg5bh;	u8 reg5ah = 0;	unsigned long dmabase = pci_resource_start(dev, 4);	u8 did, rid;		int is_372n = 0;		pci_read_config_byte(dev, 0x5a, &reg5ah);	/* interrupt force enable */	pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));	if(dmabase)	{		did = inb(dmabase + 0x22);		rid = inb(dmabase + 0x28);			if((did == 4 && rid == 6) || (did == 5 && rid > 1))			is_372n = 1;	}	/*	 * default to pci clock. make sure MA15/16 are set to output	 * to prevent drives having problems with 40-pin cables.	 */	pci_write_config_byte(dev, 0x5b, 0x23);	/*	 * set up the PLL. we need to adjust it so that it's stable. 	 * freq = Tpll * 192 / Tpci	 *	 * Todo. For non x86 should probably check the dword is	 * set to 0xABCDExxx indicating the BIOS saved f_CNT	 */	pci_read_config_word(dev, 0x78, &freq);	freq &= 0x1FF;		/*	 * The 372N uses different PCI clock information and has	 * some other complications	 *	On PCI33 timing we must clock switch	 *	On PCI66 timing we must NOT use the PCI clock	 *	 * Currently we always set up the PLL for the 372N	 */	 	pci_set_drvdata(dev, NULL);		if(is_372n)	{		printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");		if(freq < 0x55)			pll = F_LOW_PCI_33;		else if(freq < 0x70)			pll = F_LOW_PCI_40;		else if(freq < 0x7F)			pll = F_LOW_PCI_50;		else			pll = F_LOW_PCI_66;					printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll);					/* We always use the pll not the PCI clock on 372N */	}	else	{		if(freq < 0x9C)			pll = F_LOW_PCI_33;		else if(freq < 0xb0)			pll = F_LOW_PCI_40;		else if(freq <0xc8)			pll = F_LOW_PCI_50;		else			pll = F_LOW_PCI_66;			if (pll == F_LOW_PCI_33) {			if (hpt_minimum_revision(dev,8))				pci_set_drvdata(dev, (void *) thirty_three_base_hpt374);			else if (hpt_minimum_revision(dev,5))				pci_set_drvdata(dev, (void *) thirty_three_base_hpt372);			else if (hpt_minimum_revision(dev,4))				pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a);			else				pci_set_drvdata(dev, (void *) thirty_three_base_hpt370);			printk("HPT37X: using 33MHz PCI clock\n");		} else if (pll == F_LOW_PCI_40) {			/* Unsupported */		} else if (pll == F_LOW_PCI_50) {			if (hpt_minimum_revision(dev,8))				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);			else if (hpt_minimum_revision(dev,5))				pci_set_drvdata(dev, (void *) fifty_base_hpt372);			else if (hpt_minimum_revision(dev,4))				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);			else				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);			printk("HPT37X: using 50MHz PCI clock\n");		} else {			if (hpt_minimum_revision(dev,8))			{				printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");			}			else if (hpt_minimum_revision(dev,5))				pci_set_drvdata(dev, (void *) sixty_six_base_hpt372);			else if (hpt_minimum_revision(dev,4))				pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a);			else				pci_set_drvdata(dev, (void *) sixty_six_base_hpt370);			printk("HPT37X: using 66MHz PCI clock\n");		}	}		/*	 * only try the pll if we don't have a table for the clock	 * speed that we're running at. NOTE: the internal PLL will	 * result in slow reads when using a 33MHz PCI clock. we also	 * don't like to use the PLL because it will cause glitches	 * on PRST/SRST when the HPT state engine gets reset.	 */	if (pci_get_drvdata(dev)) 		goto init_hpt37X_done;		/*	 * adjust PLL based upon PCI clock, enable it, and wait for	 * stabilization.	 */	adjust = 0;	freq = (pll < F_LOW_PCI_50) ? 2 : 4;	while (adjust++ < 6) {		pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |				       pll | 0x100);		/* wait for clock stabilization */		for (i = 0; i < 0x50000; i++) {			pci_read_config_byte(dev, 0x5b, &reg5bh);			if (reg5bh & 0x80) {				/* spin looking for the clock to destabilize */				for (i = 0; i < 0x1000; ++i) {					pci_read_config_byte(dev, 0x5b, 							     &reg5bh);					if ((reg5bh & 0x80) == 0)						goto pll_recal;				}				pci_read_config_dword(dev, 0x5c, &pll);				pci_write_config_dword(dev, 0x5c, 						       pll & ~0x100);				pci_write_config_byte(dev, 0x5b, 0x21);				if (hpt_minimum_revision(dev,8))					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);				else if (hpt_minimum_revision(dev,5))					pci_set_drvdata(dev, (void *) fifty_base_hpt372);				else if (hpt_minimum_revision(dev,4))					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);				else					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);				printk("HPT37X: using 50MHz internal PLL\n");				goto init_hpt37X_done;			}		}pll_recal:		if (adjust & 1)			pll -= (adjust >> 1);		else			pll += (adjust >> 1);	} init_hpt37X_done:	/* reset state engine */	pci_write_config_byte(dev, 0x50, 0x37); 	pci_write_config_byte(dev, 0x54, 0x37); 	udelay(100);	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b39b01ffb75e14ed76510e4229ffb575007df0fb/hpt366.c/buggy/drivers/ide/pci/hpt366.c