コード例 #1
0
ファイル: piix.c プロジェクト: wxlong/Test
static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
{
	char *p = buffer;
	int i;

	for (i = 0; i < n_piix_devs; i++) {
		struct pci_dev *dev	= piix_devs[i];
		unsigned long bibma = pci_resource_start(dev, 4);
	        u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
		u8  c0 = 0, c1 = 0, reg54 = 0, reg55 = 0;
		u8  reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0;

		p += sprintf(p, "\nController: %d\n", i);
		p += sprintf(p, "\n                                Intel ");
		switch(dev->device) {
			case PCI_DEVICE_ID_INTEL_82801EB_1:
				p += sprintf(p, "PIIX4 SATA 150 ");
				break;
			case PCI_DEVICE_ID_INTEL_82801BA_8:
			case PCI_DEVICE_ID_INTEL_82801BA_9:
			case PCI_DEVICE_ID_INTEL_82801CA_10:
			case PCI_DEVICE_ID_INTEL_82801CA_11:
			case PCI_DEVICE_ID_INTEL_82801DB_10:
			case PCI_DEVICE_ID_INTEL_82801DB_11:
			case PCI_DEVICE_ID_INTEL_82801EB_11:
			case PCI_DEVICE_ID_INTEL_82801E_11:
			case PCI_DEVICE_ID_INTEL_ESB_2:
			case PCI_DEVICE_ID_INTEL_ICH6_2:
				p += sprintf(p, "PIIX4 Ultra 100 ");
				break;
			case PCI_DEVICE_ID_INTEL_82372FB_1:
			case PCI_DEVICE_ID_INTEL_82801AA_1:
				p += sprintf(p, "PIIX4 Ultra 66 ");
				break;
			case PCI_DEVICE_ID_INTEL_82451NX:
			case PCI_DEVICE_ID_INTEL_82801AB_1:
			case PCI_DEVICE_ID_INTEL_82443MX_1:
			case PCI_DEVICE_ID_INTEL_82371AB:
				p += sprintf(p, "PIIX4 Ultra 33 ");
				break;
			case PCI_DEVICE_ID_INTEL_82371SB_1:
				p += sprintf(p, "PIIX3 ");
				break;
			case PCI_DEVICE_ID_INTEL_82371MX:
				p += sprintf(p, "MPIIX ");
				break;
			case PCI_DEVICE_ID_INTEL_82371FB_1:
			case PCI_DEVICE_ID_INTEL_82371FB_0:
			default:
				p += sprintf(p, "PIIX ");
				break;
		}
		p += sprintf(p, "Chipset.\n");

		if (dev->device == PCI_DEVICE_ID_INTEL_82371MX)
			continue;

		pci_read_config_word(dev, 0x40, &reg40);
		pci_read_config_word(dev, 0x42, &reg42);
		pci_read_config_byte(dev, 0x44, &reg44);
		pci_read_config_byte(dev, 0x48, &reg48);
		pci_read_config_byte(dev, 0x4a, &reg4a);
		pci_read_config_byte(dev, 0x4b, &reg4b);
		pci_read_config_byte(dev, 0x54, &reg54);
		pci_read_config_byte(dev, 0x55, &reg55);

		psitre = (reg40 & 0x4000) ? 1 : 0;
		ssitre = (reg42 & 0x4000) ? 1 : 0;

		/*
		 * at that point bibma+0x2 et bibma+0xa are byte registers
		 * to investigate:
		 */
		c0 = inb(bibma + 0x02);
		c1 = inb(bibma + 0x0a);

		p += sprintf(p, "--------------- Primary Channel "
				"---------------- Secondary Channel "
				"-------------\n");
		p += sprintf(p, "                %sabled "
				"                        %sabled\n",
				(c0&0x80) ? "dis" : " en",
				(c1&0x80) ? "dis" : " en");
		p += sprintf(p, "--------------- drive0 --------- drive1 "
				"-------- drive0 ---------- drive1 ------\n");
		p += sprintf(p, "DMA enabled:    %s              %s "
				"            %s               %s\n",
				(c0&0x20) ? "yes" : "no ",
				(c0&0x40) ? "yes" : "no ",
				(c1&0x20) ? "yes" : "no ",
				(c1&0x40) ? "yes" : "no " );
		p += sprintf(p, "UDMA enabled:   %s              %s "
				"            %s               %s\n",
				(reg48&0x01) ? "yes" : "no ",
				(reg48&0x02) ? "yes" : "no ",
				(reg48&0x04) ? "yes" : "no ",
				(reg48&0x08) ? "yes" : "no " );
		p += sprintf(p, "UDMA enabled:   %s                %s "
				"              %s                 %s\n",
				((reg54&0x11) &&
				 (reg55&0x10) && (reg4a&0x01)) ? "5" :
				((reg54&0x11) && (reg4a&0x02)) ? "4" :
				((reg54&0x11) && (reg4a&0x01)) ? "3" :
				(reg4a&0x02) ? "2" :
				(reg4a&0x01) ? "1" :
				(reg4a&0x00) ? "0" : "X",
				((reg54&0x22) &&
				 (reg55&0x20) && (reg4a&0x10)) ? "5" :
				((reg54&0x22) && (reg4a&0x20)) ? "4" :
				((reg54&0x22) && (reg4a&0x10)) ? "3" :
				(reg4a&0x20) ? "2" :
				(reg4a&0x10) ? "1" :
				(reg4a&0x00) ? "0" : "X",
				((reg54&0x44) &&
				 (reg55&0x40) && (reg4b&0x03)) ? "5" :
				((reg54&0x44) && (reg4b&0x02)) ? "4" :
				((reg54&0x44) && (reg4b&0x01)) ? "3" :
				(reg4b&0x02) ? "2" :
				(reg4b&0x01) ? "1" :
				(reg4b&0x00) ? "0" : "X",
				((reg54&0x88) &&
				 (reg55&0x80) && (reg4b&0x30)) ? "5" :
				((reg54&0x88) && (reg4b&0x20)) ? "4" :
				((reg54&0x88) && (reg4b&0x10)) ? "3" :
				(reg4b&0x20) ? "2" :
				(reg4b&0x10) ? "1" :
				(reg4b&0x00) ? "0" : "X");

		p += sprintf(p, "UDMA\n");
		p += sprintf(p, "DMA\n");
		p += sprintf(p, "PIO\n");

		/*
		 * FIXME.... Add configuration junk data....blah blah......
		 */
	}
	return p-buffer;	 /* => must be less than 4k! */
}
コード例 #2
0
int awc4500_pci_probe(struct net_device *dev)
{
    int cards_found = 0;
    static int pci_index;	/* Static, for multiple probe calls. */
    u8 pci_irq_line = 0;
//	int p;

    unsigned char awc_pci_dev, awc_pci_bus;

    if (!pci_present())
        return -1;

    for (; pci_index < 0xff; pci_index++) {
        u16 vendor, device, pci_command, new_command;
        u32 pci_memaddr;
        u32 pci_ioaddr;
        u32 pci_cisaddr;
        struct pci_dev *pdev;

        if (pcibios_find_class	(PCI_CLASS_NETWORK_OTHER << 8,
                                 reverse_probe ? 0xfe - pci_index : pci_index,
                                 &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL) {
            if (reverse_probe) {
                continue;
            } else {
                break;
            }
        }
        pdev = pci_find_slot(awc_pci_bus, awc_pci_dev);
        if (!pdev)
            continue;
        if (pci_enable_device(pdev))
            continue;
        vendor = pdev->vendor;
        device = pdev->device;
        pci_irq_line = pdev->irq;
        pci_memaddr = pci_resource_start (pdev, 0);
        pci_cisaddr = pci_resource_start (pdev, 1);
        pci_ioaddr = pci_resource_start (pdev, 2);

//		printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr);
        /* Remove I/O space marker in bit 0. */

        if (vendor != PCI_VENDOR_ID_AIRONET)
            continue;
        if (device != PCI_DEVICE_AIRONET_4800_1 &&
                device != PCI_DEVICE_AIRONET_4800 &&
                device != PCI_DEVICE_AIRONET_4500 )
            continue;

//		if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||
//			check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||
//			check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {
//				printk(KERN_ERR "aironet4X00 mem addrs not available for maping \n");
//				continue;
//		}
        if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
            continue;
//		request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
//		request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");

        mdelay(10);

        pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
        new_command = pci_command | PCI_COMMAND_SERR;
        if (pci_command != new_command)
            pci_write_config_word(pdev, PCI_COMMAND, new_command);


        /*		if (device == PCI_DEVICE_AIRONET_4800)
        			pci_write_config_dword(pdev, 0x40, 0x00000000);

        		udelay(1000);
        */
        if (device == PCI_DEVICE_AIRONET_4800)
            pci_write_config_dword(pdev, 0x40, 0x40000000);

        if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)) {
            printk(KERN_ERR "awc4800 pci init failed \n");
            break;
        }
        dev = 0;
        cards_found++;
    }

    return cards_found ? 0 : -ENODEV;
}
コード例 #3
0
ファイル: piix.c プロジェクト: ivucica/linux
/**
 *	piix_tune_drive		-	tune a drive attached to a PIIX
 *	@drive: drive to tune
 *	@pio: desired PIO mode
 *
 *	Set the interface PIO mode based upon  the settings done by AMI BIOS
 *	(might be useful if drive is not registered in CMOS for any reason).
 */
static void piix_tune_drive (ide_drive_t *drive, u8 pio)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	int is_slave		= (&hwif->drives[1] == drive);
	int master_port		= hwif->channel ? 0x42 : 0x40;
	int slave_port		= 0x44;
	unsigned long flags;
	u16 master_data;
	u8 slave_data;
	static DEFINE_SPINLOCK(tune_lock);
	int control = 0;

				 /* ISP  RTC */
	static const u8 timings[][2]= {
					{ 0, 0 },
					{ 0, 0 },
					{ 1, 0 },
					{ 2, 1 },
					{ 2, 3 }, };

	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);

	/*
	 * Master vs slave is synchronized above us but the slave register is
	 * shared by the two hwifs so the corner case of two slave timeouts in
	 * parallel must be locked.
	 */
	spin_lock_irqsave(&tune_lock, flags);
	pci_read_config_word(dev, master_port, &master_data);

	if (pio >= 2)
		control |= 1;	/* Programmable timing on */
	if (drive->media == ide_disk)
		control |= 4;	/* Prefetch, post write */
	if (pio >= 3)
		control |= 2;	/* IORDY */
	if (is_slave) {
		master_data = master_data | 0x4000;
		if (pio > 1) {
			/* enable PPE, IE and TIME */
			master_data = master_data | (control << 4);
		} else {
			master_data &= ~0x0070;
		}
		pci_read_config_byte(dev, slave_port, &slave_data);
		slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
		slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
	} else {
		master_data = master_data & 0xccf8;
		if (pio > 1) {
			/* enable PPE, IE and TIME */
			master_data = master_data | control;
		}
		master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
	}
	pci_write_config_word(dev, master_port, master_data);
	if (is_slave)
		pci_write_config_byte(dev, slave_port, slave_data);
	spin_unlock_irqrestore(&tune_lock, flags);
}
コード例 #4
0
ファイル: ehci-pci.c プロジェクト: AshishPrasad/BTP
/* called during probe() after chip reset completes */
static int ehci_pci_setup(struct usb_hcd *hcd)
{
	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
	struct pci_dev		*p_smbus;
	u8			rev;
	u32			temp;
	int			retval;

	switch (pdev->vendor) {
	case PCI_VENDOR_ID_TOSHIBA_2:
		/* celleb's companion chip */
		if (pdev->device == 0x01b5) {
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
			ehci->big_endian_mmio = 1;
#else
			ehci_warn(ehci,
				  "unsupported big endian Toshiba quirk\n");
#endif
		}
		break;
	}

	ehci->caps = hcd->regs;
	ehci->regs = hcd->regs +
		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));

	dbg_hcs_params(ehci, "reset");
	dbg_hcc_params(ehci, "reset");

        /* ehci_init() causes memory for DMA transfers to be
         * allocated.  Thus, any vendor-specific workarounds based on
         * limiting the type of memory used for DMA transfers must
         * happen before ehci_init() is called. */
	switch (pdev->vendor) {
	case PCI_VENDOR_ID_NVIDIA:
		/* NVidia reports that certain chips don't handle
		 * QH, ITD, or SITD addresses above 2GB.  (But TD,
		 * data buffer, and periodic schedule are normal.)
		 */
		switch (pdev->device) {
		case 0x003c:	/* MCP04 */
		case 0x005b:	/* CK804 */
		case 0x00d8:	/* CK8 */
		case 0x00e8:	/* CK8S */
			if (pci_set_consistent_dma_mask(pdev,
						DMA_BIT_MASK(31)) < 0)
				ehci_warn(ehci, "can't enable NVidia "
					"workaround for >2GB RAM\n");
			break;
		}
		break;
	}

	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);

	retval = ehci_halt(ehci);
	if (retval)
		return retval;

	/* data structure init */
	retval = ehci_init(hcd);
	if (retval)
		return retval;

	switch (pdev->vendor) {
	case PCI_VENDOR_ID_NEC:
		ehci->need_io_watchdog = 0;
		break;
	case PCI_VENDOR_ID_INTEL:
		ehci->need_io_watchdog = 0;
		ehci->fs_i_thresh = 1;
		if (pdev->device == 0x27cc) {
			ehci->broken_periodic = 1;
			ehci_info(ehci, "using broken periodic workaround\n");
		}
		if (pdev->device == 0x0806 || pdev->device == 0x0811
				|| pdev->device == 0x0829) {
			ehci_info(ehci, "disable lpm for langwell/penwell\n");
			ehci->has_lpm = 0;
		}
		break;
	case PCI_VENDOR_ID_TDI:
		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
			hcd->has_tt = 1;
			tdi_reset(ehci);
		}
		break;
	case PCI_VENDOR_ID_AMD:
		/* AMD8111 EHCI doesn't work, according to AMD errata */
		if (pdev->device == 0x7463) {
			ehci_info(ehci, "ignoring AMD8111 (errata)\n");
			retval = -EIO;
			goto done;
		}
		break;
	case PCI_VENDOR_ID_NVIDIA:
		switch (pdev->device) {
		/* Some NForce2 chips have problems with selective suspend;
		 * fixed in newer silicon.
		 */
		case 0x0068:
			if (pdev->revision < 0xa4)
				ehci->no_selective_suspend = 1;
			break;
		}
		break;
	case PCI_VENDOR_ID_VIA:
		if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) {
			u8 tmp;

			/* The VT6212 defaults to a 1 usec EHCI sleep time which
			 * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes
			 * that sleep time use the conventional 10 usec.
			 */
			pci_read_config_byte(pdev, 0x4b, &tmp);
			if (tmp & 0x20)
				break;
			pci_write_config_byte(pdev, 0x4b, tmp | 0x20);
		}
		break;
	case PCI_VENDOR_ID_ATI:
		/* SB600 and old version of SB700 have a bug in EHCI controller,
		 * which causes usb devices lose response in some cases.
		 */
		if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
			p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
						 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
						 NULL);
			if (!p_smbus)
				break;
			rev = p_smbus->revision;
			if ((pdev->device == 0x4386) || (rev == 0x3a)
			    || (rev == 0x3b)) {
				u8 tmp;
				ehci_info(ehci, "applying AMD SB600/SB700 USB "
					"freeze workaround\n");
				pci_read_config_byte(pdev, 0x53, &tmp);
				pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
			}
			pci_dev_put(p_smbus);
		}
		break;
	}

	/* optional debug port, normally in the first BAR */
	temp = pci_find_capability(pdev, 0x0a);
	if (temp) {
		pci_read_config_dword(pdev, temp, &temp);
		temp >>= 16;
		if ((temp & (3 << 13)) == (1 << 13)) {
			temp &= 0x1fff;
			ehci->debug = ehci_to_hcd(ehci)->regs + temp;
			temp = ehci_readl(ehci, &ehci->debug->control);
			ehci_info(ehci, "debug port %d%s\n",
				HCS_DEBUG_PORT(ehci->hcs_params),
				(temp & DBGP_ENABLED)
					? " IN USE"
					: "");
			if (!(temp & DBGP_ENABLED))
				ehci->debug = NULL;
		}
	}

	ehci_reset(ehci);

	/* at least the Genesys GL880S needs fixup here */
	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
	temp &= 0x0f;
	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
		ehci_dbg(ehci, "bogus port configuration: "
			"cc=%d x pcc=%d < ports=%d\n",
			HCS_N_CC(ehci->hcs_params),
			HCS_N_PCC(ehci->hcs_params),
			HCS_N_PORTS(ehci->hcs_params));

		switch (pdev->vendor) {
		case 0x17a0:		/* GENESYS */
			/* GL880S: should be PORTS=2 */
			temp |= (ehci->hcs_params & ~0xf);
			ehci->hcs_params = temp;
			break;
		case PCI_VENDOR_ID_NVIDIA:
			/* NF4: should be PCC=10 */
			break;
		}
	}

	/* Serial Bus Release Number is at PCI 0x60 offset */
	pci_read_config_byte(pdev, 0x60, &ehci->sbrn);

	/* Keep this around for a while just in case some EHCI
	 * implementation uses legacy PCI PM support.  This test
	 * can be removed on 17 Dec 2009 if the dev_warn() hasn't
	 * been triggered by then.
	 */
	if (!device_can_wakeup(&pdev->dev)) {
		u16	port_wake;

		pci_read_config_word(pdev, 0x62, &port_wake);
		if (port_wake & 0x0001) {
			dev_warn(&pdev->dev, "Enabling legacy PCI PM\n");
			device_set_wakeup_capable(&pdev->dev, 1);
		}
	}

#ifdef	CONFIG_USB_SUSPEND
	/* REVISIT: the controller works fine for wakeup iff the root hub
	 * itself is "globally" suspended, but usbcore currently doesn't
	 * understand such things.
	 *
	 * System suspend currently expects to be able to suspend the entire
	 * device tree, device-at-a-time.  If we failed selective suspend
	 * reports, system suspend would fail; so the root hub code must claim
	 * success.  That's lying to usbcore, and it matters for runtime
	 * PM scenarios with selective suspend and remote wakeup...
	 */
	if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev))
		ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
#endif

	ehci_port_power(ehci, 1);
	retval = ehci_pci_reinit(ehci, pdev);
done:
	return retval;
}
コード例 #5
0
static int
ohci_pci_suspend (struct pci_dev *dev, u32 state)
{
	ohci_t			*ohci = (ohci_t *) pci_get_drvdata(dev);
	unsigned long		flags;
	u16 cmd;

	if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
		dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
			hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
		return -EIO;
	}

	/* act as if usb suspend can always be used */
	info ("USB suspend: usb-%s", dev->slot_name);
	ohci->sleeping = 1;

	/* First stop processing */
  	spin_lock_irqsave (&usb_ed_lock, flags);
	ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
	writel (ohci->hc_control, &ohci->regs->control);
	writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
	(void) readl (&ohci->regs->intrstatus);
  	spin_unlock_irqrestore (&usb_ed_lock, flags);

	/* Wait a frame or two */
	mdelay(1);
	if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
		mdelay (1);
		
#ifdef CONFIG_PMAC_PBOOK
	if (_machine == _MACH_Pmac)
		disable_irq (ohci->irq);
	/* else, 2.4 assumes shared irqs -- don't disable */
#endif
	/* Enable remote wakeup */
	writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable);

	/* Suspend chip and let things settle down a bit */
	ohci->hc_control = OHCI_USB_SUSPEND;
	writel (ohci->hc_control, &ohci->regs->control);
	(void) readl (&ohci->regs->control);
	mdelay (500); /* No schedule here ! */
	switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
		case OHCI_USB_RESET:
			dbg("Bus in reset phase ???");
			break;
		case OHCI_USB_RESUME:
			dbg("Bus in resume phase ???");
			break;
		case OHCI_USB_OPER:
			dbg("Bus in operational phase ???");
			break;
		case OHCI_USB_SUSPEND:
			dbg("Bus suspended");
			break;
	}
	/* In some rare situations, Apple's OHCI have happily trashed
	 * memory during sleep. We disable it's bus master bit during
	 * suspend
	 */
	pci_read_config_word (dev, PCI_COMMAND, &cmd);
	cmd &= ~PCI_COMMAND_MASTER;
	pci_write_config_word (dev, PCI_COMMAND, cmd);
#ifdef CONFIG_PMAC_PBOOK
	{
	   	struct device_node	*of_node;

		/* Disable USB PAD & cell clock */
		of_node = pci_device_to_OF_node (ohci->ohci_dev);
		if (of_node)
			pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
	}
#endif
	return 0;
}
コード例 #6
0
ファイル: 4xx_pci.c プロジェクト: Brian1013/u-boot
/*-----------------------------------------------------------------------------+
 * pci_init.  Initializes the 405GP PCI Configuration regs.
 *-----------------------------------------------------------------------------*/
void pci_405gp_init(struct pci_controller *hose)
{
	int i, reg_num = 0;
	bd_t *bd = gd->bd;

	unsigned short temp_short;
	unsigned long ptmpcila[2] = {CONFIG_SYS_PCI_PTM1PCI, CONFIG_SYS_PCI_PTM2PCI};
#if defined(CONFIG_PCI_4xx_PTM_OVERWRITE)
	char *ptmla_str, *ptmms_str;
#endif
	unsigned long ptmla[2]    = {CONFIG_SYS_PCI_PTM1LA, CONFIG_SYS_PCI_PTM2LA};
	unsigned long ptmms[2]    = {CONFIG_SYS_PCI_PTM1MS, CONFIG_SYS_PCI_PTM2MS};
#if defined(CONFIG_PIP405) || defined (CONFIG_MIP405)
	unsigned long pmmla[3]    = {0x80000000, 0xA0000000, 0};
	unsigned long pmmma[3]    = {0xE0000001, 0xE0000001, 0};
	unsigned long pmmpcila[3] = {0x80000000, 0x00000000, 0};
	unsigned long pmmpciha[3] = {0x00000000, 0x00000000, 0};
#else
	unsigned long pmmla[3]    = {0x80000000, 0,0};
	unsigned long pmmma[3]    = {0xC0000001, 0,0};
	unsigned long pmmpcila[3] = {0x80000000, 0,0};
	unsigned long pmmpciha[3] = {0x00000000, 0,0};
#endif
#ifdef CONFIG_PCI_PNP
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
	char *s;
#endif
#endif

#if defined(CONFIG_PCI_4xx_PTM_OVERWRITE)
	ptmla_str = getenv("ptm1la");
	ptmms_str = getenv("ptm1ms");
	if(NULL != ptmla_str && NULL != ptmms_str ) {
	        ptmla[0] = simple_strtoul (ptmla_str, NULL, 16);
		ptmms[0] = simple_strtoul (ptmms_str, NULL, 16);
	}

	ptmla_str = getenv("ptm2la");
	ptmms_str = getenv("ptm2ms");
	if(NULL != ptmla_str && NULL != ptmms_str ) {
	        ptmla[1] = simple_strtoul (ptmla_str, NULL, 16);
		ptmms[1] = simple_strtoul (ptmms_str, NULL, 16);
	}
#endif

	/*
	 * Register the hose
	 */
	hose->first_busno = 0;
	hose->last_busno = 0xff;

	/* ISA/PCI I/O space */
	pci_set_region(hose->regions + reg_num++,
		       MIN_PCI_PCI_IOADDR,
		       MIN_PLB_PCI_IOADDR,
		       0x10000,
		       PCI_REGION_IO);

	/* PCI I/O space */
	pci_set_region(hose->regions + reg_num++,
		       0x00800000,
		       0xe8800000,
		       0x03800000,
		       PCI_REGION_IO);

	reg_num = 2;

	/* Memory spaces */
	for (i=0; i<2; i++)
		if (ptmms[i] & 1)
		{
			if (!i) hose->pci_fb = hose->regions + reg_num;

			pci_set_region(hose->regions + reg_num++,
				       ptmpcila[i], ptmla[i],
				       ~(ptmms[i] & 0xfffff000) + 1,
				       PCI_REGION_MEM |
				       PCI_REGION_SYS_MEMORY);
		}

	/* PCI memory spaces */
	for (i=0; i<3; i++)
		if (pmmma[i] & 1)
		{
			pci_set_region(hose->regions + reg_num++,
				       pmmpcila[i], pmmla[i],
				       ~(pmmma[i] & 0xfffff000) + 1,
				       PCI_REGION_MEM);
		}

	hose->region_count = reg_num;

	pci_setup_indirect(hose,
			   PCICFGADR,
			   PCICFGDATA);

	if (hose->pci_fb)
		pciauto_region_init(hose->pci_fb);

	/* Let board change/modify hose & do initial checks */
	if (pci_pre_init(hose) == 0) {
		printf("PCI: Board-specific initialization failed.\n");
		printf("PCI: Configuration aborted.\n");
		return;
	}

	pci_register_hose(hose);

	/*--------------------------------------------------------------------------+
	 * 405GP PCI Master configuration.
	 * Map one 512 MB range of PLB/processor addresses to PCI memory space.
	 * PLB address 0x80000000-0xBFFFFFFF ==> PCI address 0x80000000-0xBFFFFFFF
	 * Use byte reversed out routines to handle endianess.
	 *--------------------------------------------------------------------------*/
	out32r(PMM0MA,    (pmmma[0]&~0x1)); /* disable, configure PMMxLA, PMMxPCILA first */
	out32r(PMM0LA,    pmmla[0]);
	out32r(PMM0PCILA, pmmpcila[0]);
	out32r(PMM0PCIHA, pmmpciha[0]);
	out32r(PMM0MA,    pmmma[0]);

	/*--------------------------------------------------------------------------+
	 * PMM1 is not used.  Initialize them to zero.
	 *--------------------------------------------------------------------------*/
	out32r(PMM1MA,    (pmmma[1]&~0x1));
	out32r(PMM1LA,    pmmla[1]);
	out32r(PMM1PCILA, pmmpcila[1]);
	out32r(PMM1PCIHA, pmmpciha[1]);
	out32r(PMM1MA,    pmmma[1]);

	/*--------------------------------------------------------------------------+
	 * PMM2 is not used.  Initialize them to zero.
	 *--------------------------------------------------------------------------*/
	out32r(PMM2MA,    (pmmma[2]&~0x1));
	out32r(PMM2LA,    pmmla[2]);
	out32r(PMM2PCILA, pmmpcila[2]);
	out32r(PMM2PCIHA, pmmpciha[2]);
	out32r(PMM2MA,    pmmma[2]);

	/*--------------------------------------------------------------------------+
	 * 405GP PCI Target configuration.  (PTM1)
	 * Note: PTM1MS is hardwire enabled but we set the enable bit anyway.
	 *--------------------------------------------------------------------------*/
	out32r(PTM1LA,    ptmla[0]);         /* insert address                     */
	out32r(PTM1MS,    ptmms[0]);         /* insert size, enable bit is 1       */
	pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, ptmpcila[0]);

	/*--------------------------------------------------------------------------+
	 * 405GP PCI Target configuration.  (PTM2)
	 *--------------------------------------------------------------------------*/
	out32r(PTM2LA, ptmla[1]);            /* insert address                     */
	pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, ptmpcila[1]);

	if (ptmms[1] == 0)
	{
		out32r(PTM2MS,    0x00000001);   /* set enable bit                     */
		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, 0x00000000);
		out32r(PTM2MS,    0x00000000);   /* disable                            */
	}
	else
	{
		out32r(PTM2MS, ptmms[1]);        /* insert size, enable bit is 1       */
	}

	/*
	 * Insert Subsystem Vendor and Device ID
	 */
	pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_VENDOR_ID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
#ifdef CONFIG_CPCI405
	if (is_pci_host(hose))
		pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
	else
		pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID2);
#else
	pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
#endif

	/*
	 * Insert Class-code
	 */
#ifdef CONFIG_SYS_PCI_CLASSCODE
	pci_write_config_word(PCIDEVID_405GP, PCI_CLASS_SUB_CODE, CONFIG_SYS_PCI_CLASSCODE);
#endif /* CONFIG_SYS_PCI_CLASSCODE */

	/*--------------------------------------------------------------------------+
	 * If PCI speed = 66MHz, set 66MHz capable bit.
	 *--------------------------------------------------------------------------*/
	if (bd->bi_pci_busfreq >= 66000000) {
		pci_read_config_word(PCIDEVID_405GP, PCI_STATUS, &temp_short);
		pci_write_config_word(PCIDEVID_405GP,PCI_STATUS,(temp_short|PCI_STATUS_66MHZ));
	}

#if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER)
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
	if (is_pci_host(hose) ||
	    (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
#endif
	{
		/*--------------------------------------------------------------------------+
		 * Write the 405GP PCI Configuration regs.
		 * Enable 405GP to be a master on the PCI bus (PMM).
		 * Enable 405GP to act as a PCI memory target (PTM).
		 *--------------------------------------------------------------------------*/
		pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &temp_short);
		pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND, temp_short |
				      PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
	}
#endif

#if defined(CONFIG_405EP)
	/*
	 * on ppc405ep vendor/device id is not set
	 * The user manual says 0x1014 (IBM) / 0x0156 (405GP!)
	 * are the correct values.
	 */
	pci_write_config_word(PCIDEVID_405GP, PCI_VENDOR_ID, PCI_VENDOR_ID_IBM);
	pci_write_config_word(PCIDEVID_405GP,
			      PCI_DEVICE_ID, PCI_DEVICE_ID_IBM_405GP);
#endif

	/*
	 * Set HCE bit (Host Configuration Enabled)
	 */
	pci_read_config_word(PCIDEVID_405GP, PCIBRDGOPT2, &temp_short);
	pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, (temp_short | 0x0001));

#ifdef CONFIG_PCI_PNP
	/*--------------------------------------------------------------------------+
	 * Scan the PCI bus and configure devices found.
	 *--------------------------------------------------------------------------*/
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
	if (is_pci_host(hose) ||
	    (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
#endif
	{
#ifdef CONFIG_PCI_SCAN_SHOW
		printf("PCI:   Bus Dev VenId DevId Class Int\n");
#endif
		hose->last_busno = pci_hose_scan(hose);
	}
#endif  /* CONFIG_PCI_PNP */

}
コード例 #7
0
static void piix_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	u8 maslave		= hwif->channel ? 0x42 : 0x40;
	int a_speed		= 3 << (drive->dn * 4);
	int u_flag		= 1 << drive->dn;
	int v_flag		= 0x01 << drive->dn;
	int w_flag		= 0x10 << drive->dn;
	int u_speed		= 0;
	int			sitre;
	u16			reg4042, reg4a;
	u8			reg48, reg54, reg55;
	const u8 speed		= drive->dma_mode;

	pci_read_config_word(dev, maslave, &reg4042);
	sitre = (reg4042 & 0x4000) ? 1 : 0;
	pci_read_config_byte(dev, 0x48, &reg48);
	pci_read_config_word(dev, 0x4a, &reg4a);
	pci_read_config_byte(dev, 0x54, &reg54);
	pci_read_config_byte(dev, 0x55, &reg55);

	if (speed >= XFER_UDMA_0) {
		u8 udma = speed - XFER_UDMA_0;

		u_speed = min_t(u8, 2 - (udma & 1), udma) << (drive->dn * 4);

		if (!(reg48 & u_flag))
			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
		if (speed == XFER_UDMA_5) {
			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
		} else {
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
		}
		if ((reg4a & a_speed) != u_speed)
			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
		if (speed > XFER_UDMA_2) {
			if (!(reg54 & v_flag))
				pci_write_config_byte(dev, 0x54, reg54 | v_flag);
		} else
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
	} else {
		const u8 mwdma_to_pio[] = { 0, 3, 4 };

		if (reg48 & u_flag)
			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
		if (reg4a & a_speed)
			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
		if (reg54 & v_flag)
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
		if (reg55 & w_flag)
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);

		if (speed >= XFER_MW_DMA_0)
			drive->pio_mode =
				mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
		else
			drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */

		piix_set_pio_mode(hwif, drive);
	}
}
コード例 #8
0
static int __devinit sis_find_family(struct pci_dev *dev)
{
	struct pci_dev *host;
	int i = 0;

	chipset_family = 0;

	for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) {

		host = pci_get_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL);

		if (!host)
			continue;

		chipset_family = SiSHostChipInfo[i].chipset_family;

		/* Special case for SiS630 : 630S/ET is ATA_100a */
		if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
			if (host->revision >= 0x30)
				chipset_family = ATA_100a;
		}
		pci_dev_put(host);

		printk(KERN_INFO DRV_NAME " %s: %s %s controller\n",
			pci_name(dev), SiSHostChipInfo[i].name,
			chipset_capability[chipset_family]);
	}

	if (!chipset_family) { /* Belongs to pci-quirks */

			u32 idemisc;
			u16 trueid;

			/* Disable ID masking and register remapping */
			pci_read_config_dword(dev, 0x54, &idemisc);
			pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff));
			pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
			pci_write_config_dword(dev, 0x54, idemisc);

			if (trueid == 0x5518) {
				printk(KERN_INFO DRV_NAME " %s: SiS 962/963 MuTIOL IDE UDMA133 controller\n",
					pci_name(dev));
				chipset_family = ATA_133;

				/* Check for 5513 compability mapping
				 * We must use this, else the port enabled code will fail,
				 * as it expects the enablebits at 0x4a.
				 */
				if ((idemisc & 0x40000000) == 0) {
					pci_write_config_dword(dev, 0x54, idemisc | 0x40000000);
					printk(KERN_INFO DRV_NAME " %s: Switching to 5513 register mapping\n",
						pci_name(dev));
				}
			}
	}

	if (!chipset_family) { /* Belongs to pci-quirks */

			struct pci_dev *lpc_bridge;
			u16 trueid;
			u8 prefctl;
			u8 idecfg;

			pci_read_config_byte(dev, 0x4a, &idecfg);
			pci_write_config_byte(dev, 0x4a, idecfg | 0x10);
			pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
			pci_write_config_byte(dev, 0x4a, idecfg);

			if (trueid == 0x5517) { /* SiS 961/961B */

				lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */
				pci_read_config_byte(dev, 0x49, &prefctl);
				pci_dev_put(lpc_bridge);

				if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) {
					printk(KERN_INFO DRV_NAME " %s: SiS 961B MuTIOL IDE UDMA133 controller\n",
						pci_name(dev));
					chipset_family = ATA_133a;
				} else {
					printk(KERN_INFO DRV_NAME " %s: SiS 961 MuTIOL IDE UDMA100 controller\n",
						pci_name(dev));
					chipset_family = ATA_100;
				}
			}
	}

	return chipset_family;
}
コード例 #9
0
ファイル: irq.c プロジェクト: SnkBitten/amithlon-revival
static int pcicommand(pcidata* x)
{
  struct pci_dev* sh=(struct pci_dev*)x->starthandle;

  switch(x->command) {
  case CMD_FIND_SLOT:
    x->handle=(unsigned long)pci_find_slot(x->busnum,
					   PCI_DEVFN(x->devnum,x->funnum));
    return 0;
  case CMD_FIND_SUBSYS:
    x->handle=(unsigned long)pci_find_subsys(x->vendor,
					     x->device,
					     x->subsys_vendor,
					     x->subsys_device,
					     sh);
    return 0;
  case CMD_FIND_DEVICE:
    x->handle=(unsigned long)pci_find_device(x->vendor,
					     x->device,
					     sh);
    return 0;
  case CMD_FIND_CLASS:
    x->handle=(unsigned long)pci_find_class(x->class,
					    sh);
    return 0;
  case CMD_FIND_CAPAB:
    x->cappos=pci_find_capability(sh,
				  x->capability);
    return 0;
  case CMD_SET_POWER:
    x->oldpowerstate=pci_set_power_state(sh,
					 x->powerstate);
    return 0;
  case CMD_ENABLE:
    x->result=pci_enable_device(sh);
    return 0;
  case CMD_DISABLE:
    pci_disable_device(sh);
    return 0;
  case CMD_RELEASE:
    release_device(sh,0);
    return 0;
  case CMD_REQUEST:
    {
      char* name;
      
      if (x->res_name) {
	int len;
	char c;
	int i;

	len=0;
	while (!COPY_FROM_USER(&c, x->res_name+len,1)) {
	  if (!c)
	    break;
	  len++;
	}
	name=kmalloc(len+1,GFP_KERNEL);
	for (i=0;i<len;i++) {
	  name[i]=0;
	  COPY_FROM_USER(name+i, x->res_name+i,1);
	}
	name[i]=0;
      }
      else {
	name=kmalloc(22,GFP_KERNEL);
	strcpy(name,"amithlon pci system");
      }

      x->result=pci_request_regions(sh,name);
      if (!x->result) { /* Successful */
	pci_list* n=kmalloc(sizeof(pci_list),GFP_KERNEL);
	n->dev=sh;
	if (x->releasecode) {
	  int size=find_code_size(x->releasecode);
	  n->releasecode=kmalloc(size,GFP_KERNEL);
	  COPY_FROM_USER(n->releasecode,x->releasecode,size);
	}
	else 
	  n->releasecode=NULL;
	n->name=name;
	n->next=devlist;
	n->prev_p=&devlist;
	if (devlist)
	  devlist->prev_p=&(n->next);
	devlist=n;
      }
      else {
	kfree(name);
      }
    }
    return 0;
    
  case CMD_READBYTE:
    x->confdata=0;
    x->result=pci_read_config_byte(sh,
				   x->offset,
				   (u8*)&(x->confdata));
    return 0;

  case CMD_READWORD:
    x->confdata=0;
    x->result=pci_read_config_word(sh,
				   x->offset,
				   (u16*)&(x->confdata));
    return 0;
  case CMD_READLONG:
    x->confdata=0;
    x->result=pci_read_config_dword(sh,
				    x->offset,
				    (u32*)&(x->confdata));
    return 0;
  case CMD_WRITEBYTE:
    x->result=pci_write_config_byte(sh,
				    x->offset,
				    (u8)(x->confdata));
    return 0;
  case CMD_WRITEWORD:
    x->result=pci_write_config_word(sh,
				    x->offset,
				    (u16)(x->confdata));
    return 0;
  case CMD_WRITELONG:
    x->result=pci_write_config_dword(sh,
				     x->offset,
				     (u32)(x->confdata));
    return 0;
    
  case CMD_GETBASE:
    x->start=sh->resource[x->basenum].start;
    x->end=sh->resource[x->basenum].end;
    x->flags=sh->resource[x->basenum].flags;
    return 0;

  case CMD_GETINFO:
    x->irq=sh->irq;
    x->devnum=PCI_SLOT(sh->devfn);
    x->funnum=PCI_FUNC(sh->devfn);
    x->busnum=sh->bus->number;
    return 0;

  case CMD_GETNAME:
    {
      int len=0;
      do {  
	if (COPY_TO_USER((void*)(x->res_name+len),(void*)(sh->name+len),1))
	  return -EFAULT;
      } while (sh->name[len++]);
    }
    return 0;
  default:
    return -EINVAL;
  }
}
コード例 #10
0
ファイル: osdPciShared.c プロジェクト: Sangil-Lee/Work
static
int sharedDevPCIFind(epicsUInt16 dev,epicsUInt16 vend,ELLLIST* store)
{
  int N, ret=0, err;
  int b, d, f, region;

  /* Read config space */
  uint8_t val8;
  uint16_t val16;
  UINT32 val32;

  for(N=0; ; N++){

    osdPCIDevice *next=calloc(1,sizeof(osdPCIDevice));
    if(!next)
      return S_dev_noMemory;

    err=pci_find_device(vend,dev,N, &b, &d, &f);
    if(err){ /* No more */
      if(N==0 && devPCIDebug>=1)
        errlogPrintf("sharedDevPCIFind: found no vendor:device with %04x:%04x\n",vend,dev);
      free(next);
      break;
    }
    next->dev.bus=b;
    next->dev.device=d;
    next->dev.function=f;

    if(devPCIDebug>=1)
      errlogPrintf("sharedDevPCIFind found %d.%d.%d\n",b,d,f);

    pci_read_config_word(b,d,f,PCI_DEVICE_ID, &val16);
    next->dev.id.device=val16;

    pci_read_config_word(b,d,f,PCI_VENDOR_ID, &val16);
    next->dev.id.vendor=val16;

    pci_read_config_word(b,d,f,PCI_SUBSYSTEM_ID, &val16);
    next->dev.id.sub_device=val16;

    pci_read_config_word(b,d,f,PCI_SUBSYSTEM_VENDOR_ID, &val16);
    next->dev.id.sub_vendor=val16;

    pci_read_config_dword(b,d,f,PCI_CLASS_REVISION, &val32);
    next->dev.id.revision=val32&0xff;
    next->dev.id.pci_class=val32>>8;

    for(region=0;region<PCIBARCOUNT;region++){
      pci_read_config_dword(b,d,f,PCI_BASE_ADDRESS(region), &val32);

      next->dev.bar[region].ioport=(val32 & PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO;
      if(next->dev.bar[region].ioport){
        /* This BAR is I/O ports */
        next->dev.bar[region].below1M=0;
        next->dev.bar[region].addr64=0;

        next->base[region]=(volatile void*)( val32 & PCI_BASE_ADDRESS_IO_MASK );

        next->len[region]=0;

      }else{
        /* This BAR is memory mapped */
        next->dev.bar[region].below1M=!!(val32&PCI_BASE_ADDRESS_MEM_TYPE_1M);
        next->dev.bar[region].addr64=!!(val32&PCI_BASE_ADDRESS_MEM_TYPE_64);

        next->base[region]=(volatile void*)( val32 & PCI_BASE_ADDRESS_MEM_MASK );

        next->len[region]=0;
      }
    }

    pci_read_config_dword(b,d,f,PCI_ROM_ADDRESS, &val32);
    next->erom=(volatile void*)(val32 & PCI_ROM_ADDRESS_MASK);

    pci_read_config_byte(b,d,f,PCI_INTERRUPT_LINE, &val8);
    next->dev.irq=val8;

    if(devPCIDebug>=1)
      errlogPrintf(" as pri %04x:%04x sub %04x:%04x cls %06x\n",
                   next->dev.id.vendor, next->dev.id.device,
                   next->dev.id.sub_vendor, next->dev.id.sub_device,
                   next->dev.id.pci_class);

    ellInsert(store,NULL,&next->node);
  }

  return ret;
}
コード例 #11
0
ファイル: sedlbauer.c プロジェクト: chinnyannieb/empeg-hijack
__initfunc(int
setup_sedlbauer(struct IsdnCard *card))
{
	int bytecnt, ver, val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	u16 sub_vendor_id, sub_id;
	long flags;

	strcpy(tmp, Sedlbauer_revision);
	printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
	
 	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
 		cs->subtyp = SEDL_SPEED_CARD_WIN;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {	
 		cs->subtyp = SEDL_SPEED_STAR;
		cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {	
 		cs->subtyp = SEDL_SPEED_FAX;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
 	} else
		return (0);

	bytecnt = 8;
	if (card->para[1]) {
		cs->hw.sedl.cfg_reg = card->para[1];
		cs->irq = card->para[0];
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			bytecnt = 16;
		}
	} else {
/* Probe for Sedlbauer speed pci */
#if SEDLBAUER_PCI
#if CONFIG_PCI
		if (!pci_present()) {
			printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
			return(0);
		}
		if ((dev_sedl = pci_find_device(PCI_VENDOR_SEDLBAUER,
				PCI_SPEEDPCI_ID, dev_sedl))) {
			cs->irq = dev_sedl->irq;
			if (!cs->irq) {
				printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
				return(0);
			}
			cs->hw.sedl.cfg_reg = dev_sedl->base_address[ 0] &
				PCI_BASE_ADDRESS_IO_MASK; 
		} else {
			printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
			return(0);
		}
		cs->irq_flags |= SA_SHIRQ;
		cs->hw.sedl.bus = SEDL_BUS_PCI;
		pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_VENDOR_ID,
			&sub_vendor_id);
		pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_ID,
			&sub_id);
		printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
			sub_vendor_id, sub_id);
		printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
			cs->hw.sedl.cfg_reg);
		if ((sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER) &&
			(sub_id == PCI_SUB_ID_SPEEDFAXP)) {
			cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
			cs->subtyp = SEDL_SPEEDFAX_PCI;
		} else {
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
			cs->subtyp = SEDL_SPEED_PCI;
		}
		bytecnt = 256;
		cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
		cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
		byteout(cs->hw.sedl.cfg_reg, 0xff);
		byteout(cs->hw.sedl.cfg_reg, 0x00);
		byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
		byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
		save_flags(flags);
		sti();
		current->state = TASK_UNINTERRUPTIBLE;
		schedule_timeout((10*HZ)/1000);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
		restore_flags(flags);
#else
		printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
		return (0);
#endif /* CONFIG_PCI */
#endif /* SEDLBAUER_PCI */
	}	
	
       	/* In case of the sedlbauer pcmcia card, this region is in use,
           reserved for us by the card manager. So we do not check it
           here, it would fail. */
	if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
		check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
		printk(KERN_WARNING
			"HiSax: %s config port %x-%x already in use\n",
			CardType[card->typ],
			cs->hw.sedl.cfg_reg,
			cs->hw.sedl.cfg_reg + bytecnt);
			return (0);
	} else {
		request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn");
	}

	printk(KERN_INFO
	       "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
	       cs->hw.sedl.cfg_reg,
	       cs->hw.sedl.cfg_reg + bytecnt,
	       cs->irq);

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Sedl_card_msg;

/*
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC 
 * do not test for PCI card, because ports are different
 * and PCI card uses only IPAC (for the moment)
 */	
	if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
		val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
        	        cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
	        if (val == 1) {
		/* IPAC */
                	cs->subtyp = SEDL_SPEED_WIN2_PC104;
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->subtyp = SEDL_SPEED_STAR2;
			}
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
		} else {
		/* ISAC_HSCX oder ISAC_ISAR */
			if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
				cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
			}
		}
	}

/*
 * hw.sedl.chip is now properly set
 */
	printk(KERN_INFO "Sedlbauer: %s detected\n",
		Sedlbauer_Types[cs->subtyp]);


	if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
	/* IPAC */
		if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
        	        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
                	cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
		} else {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
        	        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
                	cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
		}
                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
                cs->readisac = &ReadISAC_IPAC;
                cs->writeisac = &WriteISAC_IPAC;
                cs->readisacfifo = &ReadISACfifo_IPAC;
                cs->writeisacfifo = &WriteISACfifo_IPAC;
                cs->irq_func = &sedlbauer_interrupt_ipac;

		val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
                printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
		reset_sedlbauer(cs);
	} else {
	/* ISAC_HSCX oder ISAC_ISAR */
		cs->readisac = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAR;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_OFF;
			}
			cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
			cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
			test_and_set_bit(HW_ISAR, &cs->HW_Flags);
			cs->irq_func = &sedlbauer_interrupt_isar;
			cs->auxcmd = &isar_auxcmd;
			ISACVersion(cs, "Sedlbauer:");
			cs->BC_Read_Reg = &ReadISAR;
			cs->BC_Write_Reg = &WriteISAR;
			cs->BC_Send_Data = &isar_fill_fifo;
			ver = ISARVersion(cs, "Sedlbauer:");
			if (ver < 0) {
				printk(KERN_WARNING
					"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
				release_io_sedlbauer(cs);
				return (0);
			}
		} else {
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
			}
			cs->irq_func = &sedlbauer_interrupt;
			ISACVersion(cs, "Sedlbauer:");
		
			if (HscxVersion(cs, "Sedlbauer:")) {
				printk(KERN_WARNING
					"Sedlbauer: wrong HSCX versions check IO address\n");
				release_io_sedlbauer(cs);
				return (0);
			}
			reset_sedlbauer(cs);
		}
	}
	return (1);
}
コード例 #12
0
ファイル: i2c-ali15x3.c プロジェクト: archith/camera_project
static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
{
	u16 a;
	unsigned char temp;

	/* Check the following things:
		- SMB I/O address is initialized
		- Device is enabled
		- We can use the addresses
	*/

	/* Unlock the register.
	   The data sheet says that the address registers are read-only
	   if the lock bits are 1, but in fact the address registers
	   are zero unless you clear the lock bits.
	*/
	pci_read_config_byte(ALI15X3_dev, SMBATPC, &temp);
	if (temp & ALI15X3_LOCK) {
		temp &= ~ALI15X3_LOCK;
		pci_write_config_byte(ALI15X3_dev, SMBATPC, temp);
	}

	/* Determine the address of the SMBus area */
	pci_read_config_word(ALI15X3_dev, SMBBA, &ali15x3_smba);
	ali15x3_smba &= (0xffff & ~(ALI15X3_SMB_IOSIZE - 1));
	if (ali15x3_smba == 0 && force_addr == 0) {
		dev_err(ALI15X3_dev, "ALI15X3_smb region uninitialized "
			"- upgrade BIOS or use force_addr=0xaddr\n");
		return -ENODEV;
	}

	if(force_addr)
		ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);

	if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) {
		dev_err(ALI15X3_dev,
			"ALI15X3_smb region 0x%x already in use!\n",
			ali15x3_smba);
		return -ENODEV;
	}

	if(force_addr) {
		dev_info(ALI15X3_dev, "forcing ISA address 0x%04X\n",
			ali15x3_smba);
		if (PCIBIOS_SUCCESSFUL !=
		    pci_write_config_word(ALI15X3_dev, SMBBA, ali15x3_smba))
			return -ENODEV;
		if (PCIBIOS_SUCCESSFUL !=
		    pci_read_config_word(ALI15X3_dev, SMBBA, &a))
			return -ENODEV;
		if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) {
			/* make sure it works */
			dev_err(ALI15X3_dev,
				"force address failed - not supported?\n");
			return -ENODEV;
		}
	}
	/* check if whole device is enabled */
	pci_read_config_byte(ALI15X3_dev, SMBCOM, &temp);
	if ((temp & 1) == 0) {
		dev_info(ALI15X3_dev, "enabling SMBus device\n");
		pci_write_config_byte(ALI15X3_dev, SMBCOM, temp | 0x01);
	}

	/* Is SMB Host controller enabled? */
	pci_read_config_byte(ALI15X3_dev, SMBHSTCFG, &temp);
	if ((temp & 1) == 0) {
		dev_info(ALI15X3_dev, "enabling SMBus controller\n");
		pci_write_config_byte(ALI15X3_dev, SMBHSTCFG, temp | 0x01);
	}

	/* set SMB clock to 74KHz as recommended in data sheet */
	pci_write_config_byte(ALI15X3_dev, SMBCLK, 0x20);

	/*
	  The interrupt routing for SMB is set up in register 0x77 in the
	  1533 ISA Bridge device, NOT in the 7101 device.
	  Don't bother with finding the 1533 device and reading the register.
	if ((....... & 0x0F) == 1)
		dev_dbg(ALI15X3_dev, "ALI15X3 using Interrupt 9 for SMBus.\n");
	*/
	pci_read_config_byte(ALI15X3_dev, SMBREV, &temp);
	dev_dbg(ALI15X3_dev, "SMBREV = 0x%X\n", temp);
	dev_dbg(ALI15X3_dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba);

	return 0;
}
コード例 #13
0
ファイル: testdma.c プロジェクト: WKakarot/c-homework
static int __devinit
test_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
    struct net_device *netdev = NULL;
    int err;
    unsigned short val = 0;

    netdev = alloc_etherdev(4);
    if (netdev == NULL)
    {
        printk("alloc_etherdev failed\n");
        return -1;
    }

    SET_NETDEV_DEV(netdev, &pdev->dev);
//	ether_setup(netdev);
    netdev->netdev_ops = &test_netdev_ops;

    netdev->irq               = pdev->irq;   //irq

    pci_set_drvdata(pdev, netdev);


    if ((err = register_netdev(netdev))) {
        printk("register_netdev failed\n");
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
        return err;
    }

    if ((err = pci_enable_device(pdev))) {
        printk("pci_enable_device failed");
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
        return err;
    }

    if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
        printk("pci_resource_flags failed\n");
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
        return -2;
    }

    err = pci_request_regions(pdev, DRV_MODULE_NAME);
    if (err) {
        printk("pci_request_regions failed\n");
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
        return -2;
    }

    Pbase = pci_resource_start(pdev, 0);
    len   = pci_resource_len(pdev, 0);
    Vbase = (unsigned long)ioremap(Pbase, len);

    /* print the board memory */
    printk("Pbase addr: 0x%lx\n", Pbase);
    printk("memory size: %ld\n", len);
    printk("Vbase addr: 0x%lx\n", Vbase);
    /* end */

    pci_set_master(pdev);

    /* read pcie config */
    printk("read the VID and DID:\n");
    pci_read_config_word(pdev, 0x0, &val);
    printk("VID: %d\n", val);
    pci_read_config_word(pdev, 0x2, &val);
    printk("DID: %d\n", val);
    /* end */

    /* alloc  dma buffer */
    dmaVaddr = (unsigned long)pci_alloc_consistent(pdev, DMA_BUFF_SIZE, &dmaBusAddr);


    if ((err = register_netdev(netdev))) {
        printk("register_netdev failed\n");
        pci_free_consistent(pdev, DMA_BUFF_SIZE, (void*)dmaVaddr, dmaBusAddr);
        if (Vbase) {
            iounmap((void*)Vbase);
            Vbase = 0;
        }
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
        return err;
    }



    return 0;
}
コード例 #14
0
ファイル: peak_pci.c プロジェクト: AICP/kernel_moto_shamu
static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct sja1000_priv *priv;
	struct peak_pci_chan *chan;
	struct net_device *dev, *prev_dev;
	void __iomem *cfg_base, *reg_base;
	u16 sub_sys_id, icr;
	int i, err, channels;

	err = pci_enable_device(pdev);
	if (err)
		return err;

	err = pci_request_regions(pdev, DRV_NAME);
	if (err)
		goto failure_disable_pci;

	err = pci_read_config_word(pdev, 0x2e, &sub_sys_id);
	if (err)
		goto failure_release_regions;

	dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n",
		pdev->vendor, pdev->device, sub_sys_id);

	err = pci_write_config_word(pdev, 0x44, 0);
	if (err)
		goto failure_release_regions;

	if (sub_sys_id >= 12)
		channels = 4;
	else if (sub_sys_id >= 10)
		channels = 3;
	else if (sub_sys_id >= 4)
		channels = 2;
	else
		channels = 1;

	cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE);
	if (!cfg_base) {
		dev_err(&pdev->dev, "failed to map PCI resource #0\n");
		err = -ENOMEM;
		goto failure_release_regions;
	}

	reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels);
	if (!reg_base) {
		dev_err(&pdev->dev, "failed to map PCI resource #1\n");
		err = -ENOMEM;
		goto failure_unmap_cfg_base;
	}

	/* Set GPIO control register */
	writew(0x0005, cfg_base + PITA_GPIOICR + 2);
	/* Enable all channels of this card */
	writeb(0x00, cfg_base + PITA_GPIOICR);
	/* Toggle reset */
	writeb(0x05, cfg_base + PITA_MISC + 3);
	mdelay(5);
	/* Leave parport mux mode */
	writeb(0x04, cfg_base + PITA_MISC + 3);

	icr = readw(cfg_base + PITA_ICR + 2);

	for (i = 0; i < channels; i++) {
		dev = alloc_sja1000dev(sizeof(struct peak_pci_chan));
		if (!dev) {
			err = -ENOMEM;
			goto failure_remove_channels;
		}

		priv = netdev_priv(dev);
		chan = priv->priv;

		chan->cfg_base = cfg_base;
		priv->reg_base = reg_base + i * PEAK_PCI_CHAN_SIZE;

		priv->read_reg = peak_pci_read_reg;
		priv->write_reg = peak_pci_write_reg;
		priv->post_irq = peak_pci_post_irq;

		priv->can.clock.freq = PEAK_PCI_CAN_CLOCK;
		priv->ocr = PEAK_PCI_OCR;
		priv->cdr = PEAK_PCI_CDR;
		/* Neither a slave nor a single device distributes the clock */
		if (channels == 1 || i > 0)
			priv->cdr |= CDR_CLK_OFF;

		/* Setup interrupt handling */
		priv->irq_flags = IRQF_SHARED;
		dev->irq = pdev->irq;

		chan->icr_mask = peak_pci_icr_masks[i];
		icr |= chan->icr_mask;

		SET_NETDEV_DEV(dev, &pdev->dev);

		/* Create chain of SJA1000 devices */
		chan->prev_dev = pci_get_drvdata(pdev);
		pci_set_drvdata(pdev, dev);

		/*
		 * PCAN-ExpressCard needs some additional i2c init.
		 * This must be done *before* register_sja1000dev() but
		 * *after* devices linkage
		 */
		if (pdev->device == PEAK_PCIEC_DEVICE_ID) {
			err = peak_pciec_probe(pdev, dev);
			if (err) {
				dev_err(&pdev->dev,
					"failed to probe device (err %d)\n",
					err);
				goto failure_free_dev;
			}
		}

		err = register_sja1000dev(dev);
		if (err) {
			dev_err(&pdev->dev, "failed to register device\n");
			goto failure_free_dev;
		}

		dev_info(&pdev->dev,
			 "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
			 dev->name, priv->reg_base, chan->cfg_base, dev->irq);
	}

	/* Enable interrupts */
	writew(icr, cfg_base + PITA_ICR + 2);

	return 0;

failure_free_dev:
	pci_set_drvdata(pdev, chan->prev_dev);
	free_sja1000dev(dev);

failure_remove_channels:
	/* Disable interrupts */
	writew(0x0, cfg_base + PITA_ICR + 2);

	chan = NULL;
	for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
		priv = netdev_priv(dev);
		chan = priv->priv;
		prev_dev = chan->prev_dev;

		unregister_sja1000dev(dev);
		free_sja1000dev(dev);
	}

	/* free any PCIeC resources too */
	if (chan && chan->pciec_card)
		peak_pciec_remove(chan->pciec_card);

	pci_iounmap(pdev, reg_base);

failure_unmap_cfg_base:
	pci_iounmap(pdev, cfg_base);

failure_release_regions:
	pci_release_regions(pdev);

failure_disable_pci:
	pci_disable_device(pdev);

	return err;
}
コード例 #15
0
ファイル: pci.c プロジェクト: andi34/Dhollmen_Kernel
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	void __iomem *mem;
	struct ath_softc *sc;
	struct ieee80211_hw *hw;
	u8 csz;
	u16 subsysid;
	u32 val;
	int ret = 0;
	char hw_name[64];

	if (pci_enable_device(pdev))
		return -EIO;

	ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
		goto err_dma;
	}

	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		printk(KERN_ERR "ath9k: 32-bit DMA consistent "
			"DMA enable failed\n");
		goto err_dma;
	}

	/*
	 * Cache line size is used to size and align various
	 * structures used to communicate with the hardware.
	 */
	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
	if (csz == 0) {
		/*
		 * Linux 2.4.18 (at least) writes the cache line size
		 * register as a 16-bit wide register which is wrong.
		 * We must have this setup properly for rx buffer
		 * DMA to work so force a reasonable value here if it
		 * comes up zero.
		 */
		csz = L1_CACHE_BYTES / sizeof(u32);
		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
	}
	/*
	 * The default setting of latency timer yields poor results,
	 * set it to the value used by other systems. It may be worth
	 * tweaking this setting more.
	 */
	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);

	pci_set_master(pdev);

	/*
	 * Disable the RETRY_TIMEOUT register (0x41) to keep
	 * PCI Tx retries from interfering with C3 CPU state.
	 */
	pci_read_config_dword(pdev, 0x40, &val);
	if ((val & 0x0000ff00) != 0)
		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);

	ret = pci_request_region(pdev, 0, "ath9k");
	if (ret) {
		dev_err(&pdev->dev, "PCI memory region reserve error\n");
		ret = -ENODEV;
		goto err_region;
	}

	mem = pci_iomap(pdev, 0, 0);
	if (!mem) {
		printk(KERN_ERR "PCI memory map error\n") ;
		ret = -EIO;
		goto err_iomap;
	}

	hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
	if (!hw) {
		dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
		ret = -ENOMEM;
		goto err_alloc_hw;
	}

	SET_IEEE80211_DEV(hw, &pdev->dev);
	pci_set_drvdata(pdev, hw);

	sc = hw->priv;
	sc->hw = hw;
	sc->dev = &pdev->dev;
	sc->mem = mem;

	/* Will be cleared in ath9k_start() */
	sc->sc_flags |= SC_OP_INVALID;

	ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
	if (ret) {
		dev_err(&pdev->dev, "request_irq failed\n");
		goto err_irq;
	}

	sc->irq = pdev->irq;

	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
	ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
	if (ret) {
		dev_err(&pdev->dev, "Failed to initialize device\n");
		goto err_init;
	}

	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
		   hw_name, (unsigned long)mem, pdev->irq);

	return 0;

err_init:
	free_irq(sc->irq, sc);
err_irq:
	ieee80211_free_hw(hw);
err_alloc_hw:
	pci_iounmap(pdev, mem);
err_iomap:
	pci_release_region(pdev, 0);
err_region:
	/* Nothing */
err_dma:
	pci_disable_device(pdev);
	return ret;
}
コード例 #16
0
ファイル: pdc202xx.c プロジェクト: dmgerman/linux-pre-history
static char * pdc202xx_info (char *buf, struct pci_dev *dev)
{
	char *p = buf;

	u32 bibma  = pci_resource_start(dev, 4);
	u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
	u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
	u8 hi = 0, lo = 0;

        /*
         * at that point bibma+0x2 et bibma+0xa are byte registers
         * to investigate:
         */
	u8 c0	= inb_p((unsigned short)bibma + 0x02);
	u8 c1	= inb_p((unsigned short)bibma + 0x0a);

	u8 sc11	= inb_p((unsigned short)bibma + 0x11);
	u8 sc1a	= inb_p((unsigned short)bibma + 0x1a);
	u8 sc1b	= inb_p((unsigned short)bibma + 0x1b);
	u8 sc1c	= inb_p((unsigned short)bibma + 0x1c); 
	u8 sc1d	= inb_p((unsigned short)bibma + 0x1d);
	u8 sc1e	= inb_p((unsigned short)bibma + 0x1e);
	u8 sc1f	= inb_p((unsigned short)bibma + 0x1f);

	pci_read_config_word(dev, 0x50, &reg50h);
	pci_read_config_dword(dev, 0x60, &reg60h);
	pci_read_config_dword(dev, 0x64, &reg64h);
	pci_read_config_dword(dev, 0x68, &reg68h);
	pci_read_config_dword(dev, 0x6c, &reg6ch);

	switch(dev->device) {
		case PCI_DEVICE_ID_PROMISE_20267:
			p += sprintf(p, "\n                                PDC20267 Chipset.\n");
			break;
		case PCI_DEVICE_ID_PROMISE_20265:
			p += sprintf(p, "\n                                PDC20265 Chipset.\n");
			break;
		case PCI_DEVICE_ID_PROMISE_20262:
			p += sprintf(p, "\n                                PDC20262 Chipset.\n");
			break;
		case PCI_DEVICE_ID_PROMISE_20246:
			p += sprintf(p, "\n                                PDC20246 Chipset.\n");
			reg50h |= 0x0c00;
			break;
		default:
			p += sprintf(p, "\n                                PDC202XX Chipset.\n");
			break;
	}

	p += sprintf(p, "------------------------------- General Status ---------------------------------\n");
	p += sprintf(p, "Burst Mode                           : %sabled\n", (sc1f & 0x01) ? "en" : "dis");
	p += sprintf(p, "Host Mode                            : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal");
	p += sprintf(p, "Bus Clocking                         : %s\n",
		((sc1f & 0xC0) == 0xC0) ? "100 External" :
		((sc1f & 0x80) == 0x80) ? "66 External" :
		((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
	p += sprintf(p, "IO pad select                        : %s mA\n",
		((sc1c & 0x03) == 0x03) ? "10" :
		((sc1c & 0x02) == 0x02) ? "8" :
		((sc1c & 0x01) == 0x01) ? "6" :
		((sc1c & 0x00) == 0x00) ? "4" : "??");
	SPLIT_BYTE(sc1e, hi, lo);
	p += sprintf(p, "Status Polling Period                : %d\n", hi);
	p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
	p += sprintf(p, "                %s                         %s\n",
		(c0&0x80)?"disabled":"enabled ",
		(c1&0x80)?"disabled":"enabled ");
	p += sprintf(p, "66 Clocking     %s                         %s\n",
		(sc11&0x02)?"enabled ":"disabled",
		(sc11&0x08)?"enabled ":"disabled");
	p += sprintf(p, "           Mode %s                      Mode %s\n",
		(sc1a & 0x01) ? "MASTER" : "PCI   ",
		(sc1b & 0x01) ? "MASTER" : "PCI   ");
	p += sprintf(p, "                %s                     %s\n",
		(sc1d & 0x08) ? "Error       " :
		((sc1d & 0x05) == 0x05) ? "Not My INTR " :
		(sc1d & 0x04) ? "Interrupting" :
		(sc1d & 0x02) ? "FIFO Full   " :
		(sc1d & 0x01) ? "FIFO Empty  " : "????????????",
		(sc1d & 0x80) ? "Error       " :
		((sc1d & 0x50) == 0x50) ? "Not My INTR " :
		(sc1d & 0x40) ? "Interrupting" :
		(sc1d & 0x20) ? "FIFO Full   " :
		(sc1d & 0x10) ? "FIFO Empty  " : "????????????");
	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
		(c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no ");
	p += sprintf(p, "DMA Mode:       %s           %s          %s            %s\n",
		pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)),
		pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)),
		pdc202xx_ultra_verbose(reg68h, (reg50h & smask)),
		pdc202xx_ultra_verbose(reg6ch, (reg50h & smask)));
	p += sprintf(p, "PIO Mode:       %s            %s           %s            %s\n",
		pdc202xx_pio_verbose(reg60h),pdc202xx_pio_verbose(reg64h),
		pdc202xx_pio_verbose(reg68h),pdc202xx_pio_verbose(reg6ch));
#if 0
	p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
#endif
	return (char *)p;
}
コード例 #17
0
ファイル: siimage.c プロジェクト: wxlong/Test
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
	u8 ultra5[]		= { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
	u16 dma[]		= { 0x2208, 0x10C2, 0x10C1 };

	ide_hwif_t *hwif	= HWIF(drive);
	u16 ultra = 0, multi	= 0;
	u8 mode = 0, unit	= drive->select.b.unit;
	u8 speed		= ide_rate_filter(siimage_ratemask(drive), xferspeed);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
				    ((hwif->mmio) ? 0xF4 : 0x84) :
				    ((hwif->mmio) ? 0xB4 : 0x80));
				    
	unsigned long ma	= siimage_seldev(drive, 0x08);
	unsigned long ua	= siimage_seldev(drive, 0x0C);

	if (hwif->mmio) {
		scsc = hwif->INB(base + 0x4A);
		mode = hwif->INB(base + addr_mask);
		multi = hwif->INW(ma);
		ultra = hwif->INW(ua);
	} else {
		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
		pci_read_config_word(hwif->pci_dev, ma, &multi);
		pci_read_config_word(hwif->pci_dev, ua, &ultra);
	}

	mode &= ~((unit) ? 0x30 : 0x03);
	ultra &= ~0x3F;
	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;

	scsc = is_sata(hwif) ? 1 : scsc;

	switch(speed) {
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_1:
		case XFER_PIO_0:
			siimage_tuneproc(drive, (speed - XFER_PIO_0));
			mode |= ((unit) ? 0x10 : 0x01);
			break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_MW_DMA_0:
			multi = dma[speed - XFER_MW_DMA_0];
			mode |= ((unit) ? 0x20 : 0x02);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		case XFER_UDMA_6:
		case XFER_UDMA_5:
		case XFER_UDMA_4:
		case XFER_UDMA_3:
		case XFER_UDMA_2:
		case XFER_UDMA_1:
		case XFER_UDMA_0:
			multi = dma[2];
			ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) :
					   (ultra5[speed - XFER_UDMA_0]));
			mode |= ((unit) ? 0x30 : 0x03);
			config_siimage_chipset_for_pio(drive, 0);
			break;
		default:
			return 1;
	}

	if (hwif->mmio) {
		hwif->OUTB(mode, base + addr_mask);
		hwif->OUTW(multi, ma);
		hwif->OUTW(ultra, ua);
	} else {
		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
		pci_write_config_word(hwif->pci_dev, ma, multi);
		pci_write_config_word(hwif->pci_dev, ua, ultra);
	}
	return (ide_config_drive_speed(drive, speed));
}
コード例 #18
0
ファイル: pata_radisys.c プロジェクト: 08opt/linux
static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
	struct pci_dev *dev	= to_pci_dev(ap->host->dev);
	u16 idetm_data;
	u8 udma_enable;

	static const	 /* ISP  RTC */
	u8 timings[][2]	= { { 0, 0 },
			    { 0, 0 },
			    { 1, 1 },
			    { 2, 2 },
			    { 3, 3 }, };

	/*
	 * MWDMA is driven by the PIO timings. We must also enable
	 * IORDY unconditionally.
	 */

	pci_read_config_word(dev, 0x40, &idetm_data);
	pci_read_config_byte(dev, 0x48, &udma_enable);

	if (adev->dma_mode < XFER_UDMA_0) {
		unsigned int mwdma	= adev->dma_mode - XFER_MW_DMA_0;
		const unsigned int needed_pio[3] = {
			XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
		};
		int pio = needed_pio[mwdma] - XFER_PIO_0;
		int control = 3;	/* IORDY|TIME0 */

		/* If the drive MWDMA is faster than it can do PIO then
		   we must force PIO0 for PIO cycles. */

		if (adev->pio_mode < needed_pio[mwdma])
			control = 1;

		/* Mask out the relevant control and timing bits we will load. Also
		   clear the other drive TIME register as a precaution */

		idetm_data &= 0xCCCC;
		idetm_data |= control << (4 * adev->devno);
		idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8);

		udma_enable &= ~(1 << adev->devno);
	} else {
		u8 udma_mode;

		/* UDMA66 on: UDMA 33 and 66 are switchable via register 0x4A */

		pci_read_config_byte(dev, 0x4A, &udma_mode);

		if (adev->xfer_mode == XFER_UDMA_2)
			udma_mode &= ~(2 << (adev->devno * 4));
		else /* UDMA 4 */
			udma_mode |= (2 << (adev->devno * 4));

		pci_write_config_byte(dev, 0x4A, udma_mode);

		udma_enable |= (1 << adev->devno);
	}
	pci_write_config_word(dev, 0x40, idetm_data);
	pci_write_config_byte(dev, 0x48, udma_enable);

	/* Track which port is configured */
	ap->private_data = adev;
}
コード例 #19
0
static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
				const struct pci_device_id *id)
{
	unsigned char temp;

	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
	    (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
		srvrworks_csb5_delay = 1;

	/* On some motherboards, it was reported that accessing the SMBus
	   caused severe hardware problems */
	if (dmi_check_system(piix4_dmi_blacklist)) {
		dev_err(&PIIX4_dev->dev,
			"Accessing the SMBus on this system is unsafe!\n");
		return -EPERM;
	}

	/* Don't access SMBus on IBM systems which get corrupted eeproms */
	if (dmi_check_system(piix4_dmi_ibm) &&
			PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
		dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
			"may corrupt your serial eeprom! Refusing to load "
			"module!\n");
		return -EPERM;
	}

	/* Determine the address of the SMBus areas */
	if (force_addr) {
		piix4_smba = force_addr & 0xfff0;
		force = 0;
	} else {
		pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
		piix4_smba &= 0xfff0;
		if(piix4_smba == 0) {
			dev_err(&PIIX4_dev->dev, "SMBus base address "
				"uninitialized - upgrade BIOS or use "
				"force_addr=0xaddr\n");
			return -ENODEV;
		}
	}

	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
		return -ENODEV;

	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
			piix4_smba);
		return -EBUSY;
	}

	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);

	/* If force_addr is set, we program the new address here. Just to make
	   sure, we disable the PIIX4 first. */
	if (force_addr) {
		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe);
		pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba);
		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01);
		dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to "
			"new address %04x!\n", piix4_smba);
	} else if ((temp & 1) == 0) {
		if (force) {
			/* This should never need to be done, but has been
			 * noted that many Dell machines have the SMBus
			 * interface on the PIIX4 disabled!? NOTE: This assumes
			 * I/O space and other allocations WERE done by the
			 * Bios!  Don't complain if your hardware does weird
			 * things after enabling this. :') Check for Bios
			 * updates before resorting to this.
			 */
			pci_write_config_byte(PIIX4_dev, SMBHSTCFG,
					      temp | 1);
			dev_printk(KERN_NOTICE, &PIIX4_dev->dev,
				"WARNING: SMBus interface has been "
				"FORCEFULLY ENABLED!\n");
		} else {
			dev_err(&PIIX4_dev->dev,
				"Host SMBus controller not enabled!\n");
			release_region(piix4_smba, SMBIOSIZE);
			piix4_smba = 0;
			return -ENODEV;
		}
	}

	if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
		dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
	else if ((temp & 0x0E) == 0)
		dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
	else
		dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
			"(or code out of date)!\n");

	pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
	dev_info(&PIIX4_dev->dev,
		 "SMBus Host Controller at 0x%x, revision %d\n",
		 piix4_smba, temp);

	return 0;
}
コード例 #20
0
ファイル: pci-octeon.c プロジェクト: garyvan/openwrt-1.6
/*
 * Called to perform platform specific PCI setup
 */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
	uint16_t config;
	uint32_t dconfig;
	int pos;
	/*
	 * Force the Cache line setting to 64 bytes. The standard
	 * Linux bus scan doesn't seem to set it. Octeon really has
	 * 128 byte lines, but Intel bridges get really upset if you
	 * try and set values above 64 bytes. Value is specified in
	 * 32bit words.
	 */
	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
	/* Set latency timers for all devices */
	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);

	/* Enable reporting System errors and parity errors on all devices */
	/* Enable parity checking and error reporting */
	pci_read_config_word(dev, PCI_COMMAND, &config);
	config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
	pci_write_config_word(dev, PCI_COMMAND, config);

	if (dev->subordinate) {
		/* Set latency timers on sub bridges */
		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 64);
		/* More bridge error detection */
		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
		config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
	}

	/* Enable the PCIe normal error reporting */
	config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
	config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
	config |= PCI_EXP_DEVCTL_FERE;	/* Fatal Error Reporting */
	config |= PCI_EXP_DEVCTL_URRE;	/* Unsupported Request */
	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, config);

	/* Find the Advanced Error Reporting capability */
	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
	if (pos) {
		/* Clear Uncorrectable Error Status */
		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
				      &dconfig);
		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
				       dconfig);
		/* Enable reporting of all uncorrectable errors */
		/* Uncorrectable Error Mask - turned on bits disable errors */
		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
		/*
		 * Leave severity at HW default. This only controls if
		 * errors are reported as uncorrectable or
		 * correctable, not if the error is reported.
		 */
		/* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
		/* Clear Correctable Error Status */
		pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
		pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
		/* Enable reporting of all correctable errors */
		/* Correctable Error Mask - turned on bits disable errors */
		pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
		/* Advanced Error Capabilities */
		pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
		/* ECRC Generation Enable */
		if (config & PCI_ERR_CAP_ECRC_GENC)
			config |= PCI_ERR_CAP_ECRC_GENE;
		/* ECRC Check Enable */
		if (config & PCI_ERR_CAP_ECRC_CHKC)
			config |= PCI_ERR_CAP_ECRC_CHKE;
		pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
		/* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
		/* Report all errors to the root complex */
		pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
				       PCI_ERR_ROOT_CMD_COR_EN |
				       PCI_ERR_ROOT_CMD_NONFATAL_EN |
				       PCI_ERR_ROOT_CMD_FATAL_EN);
		/* Clear the Root status register */
		pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
		pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
	}

	dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops;

	return 0;
}
コード例 #21
0
ファイル: ehci-pci.c プロジェクト: AvengerMoJo/apc-8750
static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
{
	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
	u16 pmc_enable = 0;
 	//CharlesTu,for PM high memory
	pci_read_config_word(pdev, 0x84, &pmc_enable);
	pmc_enable &= ~0x03;
	pci_write_config_word(pdev, 0x84, pmc_enable);

	// maybe restore FLADJ

	if (time_before(jiffies, ehci->next_statechange))
		msleep(100);

	/* Mark hardware accessible again as we are out of D3 state by now */
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
	/*CharlesTu,2011.01,21,move ahead,due to vbus lost when suspend
	* when resume ehci hub activate ,type= HUB_RESET_RESUME
	*/
  usb_root_hub_lost_power(hcd->self.root_hub);
	/* If CF is still set and we aren't resuming from hibernation
	 * then we maintained PCI Vaux power.
	 * Just undo the effect of ehci_pci_suspend().
	 */
	if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF &&
				!hibernated) {
		int	mask = INTR_MASK;

		if (!hcd->self.root_hub->do_remote_wakeup)
			mask &= ~STS_PCD;
		ehci_writel(ehci, mask, &ehci->regs->intr_enable);
		ehci_readl(ehci, &ehci->regs->intr_enable);
		return 0;
	}
  //CharlesTu
	//usb_root_hub_lost_power(hcd->self.root_hub);

	/* Else reset, to cope with power loss or flush-to-storage
	 * style "resume" having let BIOS kick in during reboot.
	 */
	(void) ehci_halt(ehci);
	(void) ehci_reset(ehci);
	(void) ehci_pci_reinit(ehci, pdev);

	/* emptying the schedule aborts any urbs */
	spin_lock_irq(&ehci->lock);
	if (ehci->reclaim)
		end_unlink_async(ehci);
	ehci_work(ehci);
	spin_unlock_irq(&ehci->lock);

	ehci_writel(ehci, ehci->command, &ehci->regs->command);
	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */

	/* here we "know" root ports should always stay powered */
	ehci_port_power(ehci, 1);

	hcd->state = HC_STATE_SUSPENDED;
	return 0;
}
コード例 #22
0
ファイル: conf_space_header.c プロジェクト: Abhi1919/ath
static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
{
	struct xen_pcibk_dev_data *dev_data;
	int err;
	u16 val;
	struct pci_cmd_info *cmd = data;

	dev_data = pci_get_drvdata(dev);
	if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG DRV_NAME ": %s: enable\n",
			       pci_name(dev));
		err = pci_enable_device(dev);
		if (err)
			return err;
		if (dev_data)
			dev_data->enable_intx = 1;
	} else if (pci_is_enabled(dev) && !is_enable_cmd(value)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG DRV_NAME ": %s: disable\n",
			       pci_name(dev));
		pci_disable_device(dev);
		if (dev_data)
			dev_data->enable_intx = 0;
	}

	if (!dev->is_busmaster && is_master_cmd(value)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG DRV_NAME ": %s: set bus master\n",
			       pci_name(dev));
		pci_set_master(dev);
	} else if (dev->is_busmaster && !is_master_cmd(value)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG DRV_NAME ": %s: clear bus master\n",
			       pci_name(dev));
		pci_clear_master(dev);
	}

	if (!(cmd->val & PCI_COMMAND_INVALIDATE) &&
	    (value & PCI_COMMAND_INVALIDATE)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG
			       DRV_NAME ": %s: enable memory-write-invalidate\n",
			       pci_name(dev));
		err = pci_set_mwi(dev);
		if (err) {
			pr_warn("%s: cannot enable memory-write-invalidate (%d)\n",
				pci_name(dev), err);
			value &= ~PCI_COMMAND_INVALIDATE;
		}
	} else if ((cmd->val & PCI_COMMAND_INVALIDATE) &&
		   !(value & PCI_COMMAND_INVALIDATE)) {
		if (unlikely(verbose_request))
			printk(KERN_DEBUG
			       DRV_NAME ": %s: disable memory-write-invalidate\n",
			       pci_name(dev));
		pci_clear_mwi(dev);
	}

	cmd->val = value;

	if (!permissive && (!dev_data || !dev_data->permissive))
		return 0;

	/* Only allow the guest to control certain bits. */
	err = pci_read_config_word(dev, offset, &val);
	if (err || val == value)
		return err;

	value &= PCI_COMMAND_GUEST;
	value |= val & ~PCI_COMMAND_GUEST;

	return pci_write_config_word(dev, offset, value);
}
コード例 #23
0
ファイル: ata_generic.c プロジェクト: cilynx/dd-wrt
static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	u16 command;
	static const struct ata_port_info info = {
		.sht = &generic_sht,
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = ATA_UDMA5,
		.port_ops = &generic_port_ops
	};
	const struct ata_port_info *ppi[] = { &info, NULL };

	/* Don't use the generic entry unless instructed to do so */
	if (id->driver_data == 1 && all_generic_ide == 0)
		return -ENODEV;

	/* Devices that need care */
	if (dev->vendor == PCI_VENDOR_ID_UMC &&
	    dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
	    (!(PCI_FUNC(dev->devfn) & 1)))
		return -ENODEV;

	if (dev->vendor == PCI_VENDOR_ID_OPTI &&
	    dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
	    (!(PCI_FUNC(dev->devfn) & 1)))
		return -ENODEV;

	/* Don't re-enable devices in generic mode or we will break some
	   motherboards with disabled and unused IDE controllers */
	pci_read_config_word(dev, PCI_COMMAND, &command);
	if (!(command & PCI_COMMAND_IO))
		return -ENODEV;

	if (dev->vendor == PCI_VENDOR_ID_AL)
	    	ata_pci_clear_simplex(dev);

	return ata_pci_init_one(dev, ppi);
}

static struct pci_device_id ata_generic[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), },
	{ PCI_DEVICE(PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), },
	{ PCI_DEVICE(PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8673F), },
	{ PCI_DEVICE(PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886A), },
	{ PCI_DEVICE(PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886BF), },
	{ PCI_DEVICE(PCI_VENDOR_ID_HINT,   PCI_DEVICE_ID_HINT_VXPROII_IDE), },
	{ PCI_DEVICE(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C561), },
	{ PCI_DEVICE(PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558), },
	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), },
	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), },
	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2),  },
	/* Must come last. If you add entries adjust this table appropriately */
	{ PCI_ANY_ID,		PCI_ANY_ID,			   PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
	{ 0, },
};

static struct pci_driver ata_generic_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= ata_generic,
	.probe 		= ata_generic_init_one,
	.remove		= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend	= ata_pci_device_suspend,
	.resume		= ata_pci_device_resume,
#endif
};

static int __init ata_generic_init(void)
{
	return pci_register_driver(&ata_generic_pci_driver);
}


static void __exit ata_generic_exit(void)
{
	pci_unregister_driver(&ata_generic_pci_driver);
}
コード例 #24
0
int sis5595_detect(struct i2c_adapter *adapter, int address,
		   unsigned short flags, int kind)
{
	int i;
	struct i2c_client *new_client;
	struct sis5595_data *data;
	int err = 0;
	const char *type_name = "sis5595";
	const char *client_name = "SIS5595 chip";
	char val;
	u16 a;

	/* Make sure we are probing the ISA bus!!  */
	if (!i2c_is_isa_adapter(adapter)) {
		printk
		    ("sis5595.o: sis5595_detect called for an I2C bus adapter?!?\n");
		return 0;
	}

	if(force_addr)
		address = force_addr & ~(SIS5595_EXTENT - 1);
	if (check_region(address, SIS5595_EXTENT)) {
		printk("sis5595.o: region 0x%x already in use!\n", address);
		return -ENODEV;
	}
	if(force_addr) {
		printk("sis5595.o: forcing ISA address 0x%04X\n", address);
		if (PCIBIOS_SUCCESSFUL !=
		    pci_write_config_word(s_bridge, SIS5595_BASE_REG, address))
			return -ENODEV;
		if (PCIBIOS_SUCCESSFUL !=
		    pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a))
			return -ENODEV;
		if ((a & ~(SIS5595_EXTENT - 1)) != address) {
			/* doesn't work for some chips? */
			printk("sis5595.o: force address failed\n");
			return -ENODEV;
		}
	}

	if (PCIBIOS_SUCCESSFUL !=
	    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val))
		return -ENODEV;
	if((val & 0x80) == 0) {
		printk("sis5595.o: enabling sensors\n");
		if (PCIBIOS_SUCCESSFUL !=
		    pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG,
		                      val | 0x80))
			return -ENODEV;
		if (PCIBIOS_SUCCESSFUL !=
		    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val))
			return -ENODEV;
		if((val & 0x80) == 0) {	/* doesn't work for some chips! */
			printk("sis5595.o: sensors enable failed - not supported?\n");
			return -ENODEV;
		}
	}

	if (!(new_client = kmalloc(sizeof(struct i2c_client) +
				   sizeof(struct sis5595_data),
				   GFP_KERNEL))) {
		return -ENOMEM;
	}

	data = (struct sis5595_data *) (new_client + 1);
	new_client->addr = address;
	init_MUTEX(&data->lock);
	new_client->data = data;
	new_client->adapter = adapter;
	new_client->driver = &sis5595_driver;
	new_client->flags = 0;

	/* Reserve the ISA region */
	request_region(address, SIS5595_EXTENT, type_name);

	/* Check revision and pin registers to determine whether 3 or 4 voltages */
	pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision));
	if(data->revision < REV2MIN) {
		data->maxins = 3;
	} else {
		pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val);
		if(val & 0x80)
			/* 3 voltages, 1 temp */
			data->maxins = 3;
		else
			/* 4 voltages, no temps */
			data->maxins = 4;
	}

	/* Fill in the remaining client fields and put it into the global list */
	strcpy(new_client->name, client_name);

	new_client->id = sis5595_id++;
	data->valid = 0;
	init_MUTEX(&data->update_lock);

	/* Tell the I2C layer a new client has arrived */
	if ((err = i2c_attach_client(new_client)))
		goto ERROR3;

	/* Register a new directory entry with module sensors */
	if ((i = i2c_register_entry((struct i2c_client *) new_client,
					type_name,
					sis5595_dir_table_template,
					THIS_MODULE)) < 0) {
		err = i;
		goto ERROR4;
	}
	data->sysctl_id = i;

	/* Initialize the SIS5595 chip */
	sis5595_init_client(new_client);
	return 0;

      ERROR4:
	i2c_detach_client(new_client);
      ERROR3:
	release_region(address, SIS5595_EXTENT);
	kfree(new_client);
	return err;
}
static int __init init_l440gx(void)
{
	struct pci_dev *dev, *pm_dev;
	struct resource *pm_iobase;
	__u16 word;

	dev = pci_find_device(PCI_VENDOR_ID_INTEL, 
		PCI_DEVICE_ID_INTEL_82371AB_0, NULL);


	pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 
		PCI_DEVICE_ID_INTEL_82371AB_3, NULL);

	if (!dev || !pm_dev) {
		printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n");
		return -ENODEV;
	}


	l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);

	if (!l440gx_map.map_priv_1) {
		printk(KERN_WARNING "Failed to ioremap L440GX flash region\n");
		return -ENOMEM;
	}

	printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1);

	/* Setup the pm iobase resource 
	 * This code should move into some kind of generic bridge
	 * driver but for the moment I'm content with getting the
	 * allocation correct. 
	 */
	pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
	if (!(pm_iobase->flags & IORESOURCE_IO)) {
		pm_iobase->name = "pm iobase";
		pm_iobase->start = 0;
		pm_iobase->end = 63;
		pm_iobase->flags = IORESOURCE_IO;

		/* Put the current value in the resource */
		pci_read_config_dword(pm_dev, 0x40, &iobase);
		iobase &= ~1;
		pm_iobase->start += iobase & ~1;
		pm_iobase->end += iobase & ~1;

		/* Allocate the resource region */
		if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) {
			printk(KERN_WARNING "Could not allocate pm iobase resource\n");
			iounmap((void *)l440gx_map.map_priv_1);
			return -ENXIO;
		}
	}
	/* Set the iobase */
	iobase = pm_iobase->start;
	pci_write_config_dword(pm_dev, 0x40, iobase | 1);
	

	/* Set XBCS# */
	pci_read_config_word(dev, 0x4e, &word);
	word |= 0x4;
        pci_write_config_word(dev, 0x4e, word);

	/* Supply write voltage to the chip */
	l440gx_set_vpp(&l440gx_map, 1);

	/* Enable the gate on the WE line */
	outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
	
       	printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");

	mymtd = do_map_probe("jedec_probe", &l440gx_map);
	if (!mymtd) {
		printk(KERN_NOTICE "JEDEC probe on BIOS chip failed. Using ROM\n");
		mymtd = do_map_probe("map_rom", &l440gx_map);
	}
	if (mymtd) {
		mymtd->module = THIS_MODULE;

		add_mtd_device(mymtd);
		return 0;
	}

	iounmap((void *)l440gx_map.map_priv_1);
	return -ENXIO;
}
コード例 #26
0
ファイル: cmd_pci.c プロジェクト: Apaisal/u-boot
static int
pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
{
	ulong	i;
	int	nbytes;
	uint	val4;
	ushort  val2;
	u_char	val1;

	/* Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do {
		printf("%08lx:", addr);
		if (size == 4) {
			pci_read_config_dword(bdf, addr, &val4);
			printf(" %08x", val4);
		}
		else if (size == 2) {
			pci_read_config_word(bdf, addr, &val2);
			printf(" %04x", val2);
		}
		else {
			pci_read_config_byte(bdf, addr, &val1);
			printf(" %02x", val1);
		}

		nbytes = readline (" ? ");
		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
			/* <CR> pressed as only input, don't modify current
			 * location and move to next. "-" pressed will go back.
			 */
			if (incrflag)
				addr += nbytes ? -size : size;
			nbytes = 1;
#ifdef CONFIG_BOOT_RETRY_TIME
			reset_cmd_timeout(); /* good enough to not time out */
#endif
		}
#ifdef CONFIG_BOOT_RETRY_TIME
		else if (nbytes == -2) {
			break;	/* timed out, exit the command	*/
		}
#endif
		else {
			char *endp;
			i = simple_strtoul(console_buffer, &endp, 16);
			nbytes = endp - console_buffer;
			if (nbytes) {
#ifdef CONFIG_BOOT_RETRY_TIME
				/* good enough to not time out
				 */
				reset_cmd_timeout();
#endif
				pci_cfg_write (bdf, addr, size, i);
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

	return 0;
}
コード例 #27
0
/* Detect whether a compatible device can be found, and initialize it. */
int vt596_setup(void)
{
	unsigned char temp;

	struct pci_dev *VT596_dev = NULL;

	/* First check whether we can access PCI at all */
	if (pci_present() == 0)
		return(-ENODEV);

	/* Look for a supported device/function */
	do {
		if((VT596_dev = pci_find_device(PCI_VENDOR_ID_VIA, num->dev,
					        VT596_dev)))
			break;
	} while ((++num)->dev);

	if (VT596_dev == NULL)
		return(-ENODEV);
	printk("i2c-viapro.o: Found Via %s device\n", num->name);

/* Determine the address of the SMBus areas */
	smb_cf_hstcfg = num->hstcfg;
	if (force_addr) {
		vt596_smba = force_addr & 0xfff0;
		force = 0;
	} else {
		if ((pci_read_config_word(VT596_dev, num->base, &vt596_smba))
		    || !(vt596_smba & 0x1)) {
			/* try 2nd address and config reg. for 596 */
			if((num->dev == PCI_DEVICE_ID_VIA_82C596_3) &&
			   (!pci_read_config_word(VT596_dev, SMBBA2, &vt596_smba)) &&
			   (vt596_smba & 0x1)) {
				smb_cf_hstcfg = 0x84;
			} else {
			        /* no matches at all */
			        printk("i2c-viapro.o: Cannot configure SMBus "
				       "I/O Base address\n");
			        return(-ENODEV);
			}
		}
		vt596_smba &= 0xfff0;
		if(vt596_smba == 0) {
			printk(KERN_ERR "i2c-viapro.o: SMBus base address"
			   "uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
			return -ENODEV;
		}
	}

	if (check_region(vt596_smba, 8)) {
		printk("i2c-viapro.o: SMBus region 0x%x already in use!\n",
		        vt596_smba);
		return(-ENODEV);
	}

	pci_read_config_byte(VT596_dev, SMBHSTCFG, &temp);
/* If force_addr is set, we program the new address here. Just to make
   sure, we disable the VT596 first. */
	if (force_addr) {
		pci_write_config_byte(VT596_dev, SMBHSTCFG, temp & 0xfe);
		pci_write_config_word(VT596_dev, num->base, vt596_smba);
		pci_write_config_byte(VT596_dev, SMBHSTCFG, temp | 0x01);
		printk
		    ("i2c-viapro.o: WARNING: SMBus interface set to new "
		     "address 0x%04x!\n", vt596_smba);
	} else if ((temp & 1) == 0) {
		if (force) {
/* NOTE: This assumes I/O space and other allocations WERE
   done by the Bios!  Don't complain if your hardware does weird 
   things after enabling this. :') Check for Bios updates before
   resorting to this.  */
			pci_write_config_byte(VT596_dev, SMBHSTCFG,
					      temp | 1);
			printk
			    ("i2c-viapro.o: enabling SMBus device\n");
		} else {
			printk
			    ("SMBUS: Error: Host SMBus controller not enabled! - "
			     "upgrade BIOS or use force=1\n");
			return(-ENODEV);
		}
	}

	/* Everything is happy, let's grab the memory and set things up. */
	request_region(vt596_smba, 8, "viapro-smbus");

#ifdef DEBUG
	if ((temp & 0x0E) == 8)
		printk("i2c-viapro.o: using Interrupt 9 for SMBus.\n");
	else if ((temp & 0x0E) == 0)
		printk("i2c-viapro.o: using Interrupt SMI# for SMBus.\n");
	else
		printk
		    ("i2c-viapro.o: Illegal Interrupt configuration (or code out "
		     "of date)!\n");

	pci_read_config_byte(VT596_dev, SMBREV, &temp);
	printk("i2c-viapro.o: SMBREV = 0x%X\n", temp);
	printk("i2c-viapro.o: VT596_smba = 0x%X\n", vt596_smba);
#endif				/* DEBUG */

	return(0);
}
コード例 #28
0
/* Detect whether a ALI1535 can be found, and initialize it, where necessary.
   Note the differences between kernels with the old PCI BIOS interface and
   newer kernels with the real PCI interface. In compat.h some things are
   defined to make the transition easier. */
static int ali1535_setup(struct pci_dev *dev)
{
	int retval = -ENODEV;
	unsigned char temp;

	/* Check the following things:
		- SMB I/O address is initialized
		- Device is enabled
		- We can use the addresses
	*/

	/* Determine the address of the SMBus area */
	pci_read_config_word(dev, SMBBA, &ali1535_smba);
	ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
	if (ali1535_smba == 0) {
		dev_warn(&dev->dev,
			"ALI1535_smb region uninitialized - upgrade BIOS?\n");
		goto exit;
	}

	if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb")) {
		dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
			ali1535_smba);
		goto exit;
	}

	/* check if whole device is enabled */
	pci_read_config_byte(dev, SMBCFG, &temp);
	if ((temp & ALI1535_SMBIO_EN) == 0) {
		dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
		goto exit_free;
	}

	/* Is SMB Host controller enabled? */
	pci_read_config_byte(dev, SMBHSTCFG, &temp);
	if ((temp & 1) == 0) {
		dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
		goto exit_free;
	}

	/* set SMB clock to 74KHz as recommended in data sheet */
	pci_write_config_byte(dev, SMBCLK, 0x20);

	/*
	  The interrupt routing for SMB is set up in register 0x77 in the
	  1533 ISA Bridge device, NOT in the 7101 device.
	  Don't bother with finding the 1533 device and reading the register.
	if ((....... & 0x0F) == 1)
		dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n");
	*/
	pci_read_config_byte(dev, SMBREV, &temp);
	dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
	dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba);

	retval = 0;
exit:
	return retval;

exit_free:
	release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
	return retval;
}
コード例 #29
0
ファイル: piix.c プロジェクト: ivucica/linux
static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= hwif->pci_dev;
	u8 maslave		= hwif->channel ? 0x42 : 0x40;
	u8 speed		= ide_rate_filter(piix_ratemask(drive), xferspeed);
	int a_speed		= 3 << (drive->dn * 4);
	int u_flag		= 1 << drive->dn;
	int v_flag		= 0x01 << drive->dn;
	int w_flag		= 0x10 << drive->dn;
	int u_speed		= 0;
	int			sitre;
	u16			reg4042, reg4a;
	u8			reg48, reg54, reg55;

	pci_read_config_word(dev, maslave, &reg4042);
	sitre = (reg4042 & 0x4000) ? 1 : 0;
	pci_read_config_byte(dev, 0x48, &reg48);
	pci_read_config_word(dev, 0x4a, &reg4a);
	pci_read_config_byte(dev, 0x54, &reg54);
	pci_read_config_byte(dev, 0x55, &reg55);

	switch(speed) {
		case XFER_UDMA_4:
		case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
		case XFER_UDMA_5:
		case XFER_UDMA_3:
		case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
		case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_SW_DMA_2:	break;
		case XFER_PIO_4:
		case XFER_PIO_3:
		case XFER_PIO_2:
		case XFER_PIO_0:	break;
		default:		return -1;
	}

	if (speed >= XFER_UDMA_0) {
		if (!(reg48 & u_flag))
			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
		if (speed == XFER_UDMA_5) {
			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
		} else {
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
		}
		if ((reg4a & a_speed) != u_speed)
			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
		if (speed > XFER_UDMA_2) {
			if (!(reg54 & v_flag))
				pci_write_config_byte(dev, 0x54, reg54 | v_flag);
		} else
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
	} else {
		if (reg48 & u_flag)
			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
		if (reg4a & a_speed)
			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
		if (reg54 & v_flag)
			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
		if (reg55 & w_flag)
			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
	}

	piix_tune_drive(drive, piix_dma_2_pio(speed));
	return (ide_config_drive_speed(drive, speed));
}
コード例 #30
0
ファイル: ymfpci.c プロジェクト: kzlin129/tt-gpl
static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
					   const struct pci_device_id *pci_id)
{
	static int dev;
	snd_card_t *card;
	struct resource *fm_res = NULL;
	struct resource *mpu_res = NULL;
	ymfpci_t *chip;
	opl3_t *opl3;
	char *str;
	int err;
	u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	switch (pci_id->device) {
	case 0x0004: str = "YMF724"; break;
	case 0x000d: str = "YMF724F"; break;
	case 0x000a: str = "YMF740"; break;
	case 0x000c: str = "YMF740C"; break;
	case 0x0010: str = "YMF744"; break;
	case 0x0012: str = "YMF754"; break;
	default: str = "???"; break;
	}

	legacy_ctrl = 0;
	legacy_ctrl2 = 0x0800;	/* SBEN = 0, SMOD = 01, LAD = 0 */

	if (pci_id->device >= 0x0010) { /* YMF 744/754 */
		if (fm_port[dev] == 1) {
			/* auto-detect */
			fm_port[dev] = pci_resource_start(pci, 1);
		}
		if (fm_port[dev] > 0 &&
		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
			pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
		}
		if (mpu_port[dev] == 1) {
			/* auto-detect */
			mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
		}
		if (mpu_port[dev] > 0 &&
		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_MEN;
			pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
		}
	} else {
		switch (fm_port[dev]) {
		case 0x388: legacy_ctrl2 |= 0; break;
		case 0x398: legacy_ctrl2 |= 1; break;
		case 0x3a0: legacy_ctrl2 |= 2; break;
		case 0x3a8: legacy_ctrl2 |= 3; break;
		default: fm_port[dev] = 0; break;
		}
		if (fm_port[dev] > 0 &&
		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
		} else {
			legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
			fm_port[dev] = 0;
		}
		switch (mpu_port[dev]) {
		case 0x330: legacy_ctrl2 |= 0 << 4; break;
		case 0x300: legacy_ctrl2 |= 1 << 4; break;
		case 0x332: legacy_ctrl2 |= 2 << 4; break;
		case 0x334: legacy_ctrl2 |= 3 << 4; break;
		default: mpu_port[dev] = 0; break;
		}
		if (mpu_port[dev] > 0 &&
		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_MEN;
		} else {
			legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
			mpu_port[dev] = 0;
		}
	}
	if (mpu_res) {
		legacy_ctrl |= YMFPCI_LEGACY_MIEN;
		legacy_ctrl2 |= YMFPCI_LEGACY2_IMOD;
	}
	pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
	pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
	pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
	if ((err = snd_ymfpci_create(card, pci,
				     old_legacy_ctrl,
			 	     &chip)) < 0) {
		snd_card_free(card);
		if (mpu_res) {
			release_resource(mpu_res);
			kfree_nocheck(mpu_res);
		}
		if (fm_res) {
			release_resource(fm_res);
			kfree_nocheck(fm_res);
		}
		return err;
	}
	chip->fm_res = fm_res;
	chip->mpu_res = mpu_res;
	strcpy(card->driver, str);
	sprintf(card->shortname, "Yamaha DS-XG (%s)", str);
	sprintf(card->longname, "%s at 0x%lx, irq %i",
		card->shortname,
		chip->reg_area_phys,
		chip->irq);
	if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_timer(chip, 0)) < 0) {
		snd_card_free(card);
		return err;
	}
	if (chip->mpu_res) {
		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
					       mpu_port[dev], 1,
					       pci->irq, 0, &chip->rawmidi)) < 0) {
			printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
			legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
		}
	}
	if (chip->fm_res) {
		if ((err = snd_opl3_create(card,
					   fm_port[dev],
					   fm_port[dev] + 2,
					   OPL3_HW_OPL3, 1, &opl3)) < 0) {
			printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]);
			legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
			snd_card_free(card);
			snd_printk("cannot create opl3 hwdep\n");
			return err;
		}
	}

	snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2);

	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	pci_set_drvdata(pci, card);
	dev++;
	return 0;
}