示例#1
0
static void  mask_irq(unsigned int irq)
{
    outl(inl(GIMR0) & (~(1 << irq)),GIMR0);
    inl(GIMR0);
}
示例#2
0
文件: smi.c 项目: AdriDlu/coreboot
void southbridge_smm_init(void)
{
	u32 smi_en;
	u16 pm1_en;
	u32 gpe0_en;

#if CONFIG_ELOG
	/* Log events from chipset before clearing */
	pch_log_state();
#endif

	printk(BIOS_DEBUG, "Initializing southbridge SMI...");

	pmbase = pci_read_config32(PCI_DEV(0, 0x1f, 0),
				   PMBASE) & 0xff80;

	printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);

	smi_en = inl(pmbase + SMI_EN);
	if (smi_en & APMC_EN) {
		printk(BIOS_INFO, "SMI# handler already enabled?\n");
		return;
	}

	printk(BIOS_DEBUG, "\n");
	dump_smi_status(reset_smi_status());
	dump_pm1_status(reset_pm1_status());
	dump_gpe0_status(reset_gpe0_status());
	dump_alt_gp_smi_status(reset_alt_gp_smi_status());
	dump_tco_status(reset_tco_status());

	/* Disable GPE0 PME_B0 */
	gpe0_en = inl(pmbase + GPE0_EN);
	gpe0_en &= ~PME_B0_EN;
	outl(gpe0_en, pmbase + GPE0_EN);

	pm1_en = 0;
	pm1_en |= PWRBTN_EN;
	pm1_en |= GBL_EN;
	outw(pm1_en, pmbase + PM1_EN);

	/* Enable SMI generation:
	 *  - on TCO events
	 *  - on APMC writes (io 0xb2)
	 *  - on writes to SLP_EN (sleep states)
	 *  - on writes to GBL_RLS (bios commands)
	 * No SMIs:
	 *  - on microcontroller writes (io 0x62/0x66)
	 */

	smi_en = 0; /* reset SMI enables */

#if 0
	smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN;
#endif
	smi_en |= TCO_EN;
	smi_en |= APMC_EN;
#if DEBUG_PERIODIC_SMIS
	/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using
	 * periodic SMIs.
	 */
	smi_en |= PERIODIC_EN;
#endif
	smi_en |= SLP_SMI_EN;
#if 0
	smi_en |= BIOS_EN;
#endif

	/* The following need to be on for SMIs to happen */
	smi_en |= EOS | GBL_SMI_EN;

	outl(smi_en, pmbase + SMI_EN);
}
示例#3
0
#include <linux/interrupt.h>
//#include <linux/input.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>

#include <asm/arch/w55fa93_ts.h>
#include <asm/arch/w55fa93_reg.h>
#undef BIT
#include <linux/input.h>


#define INTERVAL_TIME  HZ/50	
/* For  touch panel from channel 5 and 6*/
#define SET_WT_MODE	 do{\ 
								outl( (inl(REG_ADC_CON) & ~(WT_INT_EN |  LVD_INT | ADC_INT_EN | ADC_TSC_MODE)  |\
								ADC_TSC_MODE), REG_ADC_CON);\
						}while(0)
#define SET_WT_MODE_I	 do{\
								outl( (inl(REG_ADC_CON) & ~(WT_INT_EN  |  LVD_INT |ADC_INT_EN | ADC_TSC_MODE) | \
								(ADC_TSC_MODE | WT_INT_EN)), REG_ADC_CON);\							
							}while(0)
#define SET_AUTO_MODE    do{\
								outl( (inl(REG_ADC_CON) & ~(WT_INT_EN |  LVD_INT | ADC_INT_EN | ADC_TSC_MODE)  |\
								(ADC_INT_EN | (2<<14) |ADC_CONV ) ), REG_ADC_CON);\
							}while(0)

/* For low voltage detection from channel 2 or 3 or 4*/
#define SET_NORMAL_AIN2  do{\
								outl( (ADC_INT_EN | ADC_CON_ADC_EN | ADC_CONV | ADC_INT | (2<<9)), \
								REG_ADC_CON);\
static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int new_options, retval = -EINVAL;
	int new_heartbeat;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static const struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT |
					WDIOF_KEEPALIVEPING |
					WDIOF_MAGICCLOSE,
		.firmware_version =	0,
		.identity =		DRV_NAME,
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

	case WDIOC_SETOPTIONS:
	{
		if (get_user(new_options, p))
			return -EFAULT;

		if (new_options & WDIOS_DISABLECARD) {
			iTCO_wdt_stop();
			retval = 0;
		}
		if (new_options & WDIOS_ENABLECARD) {
			iTCO_wdt_keepalive();
			iTCO_wdt_start();
			retval = 0;
		}
		return retval;
	}
	case WDIOC_KEEPALIVE:
		iTCO_wdt_keepalive();
		return 0;

	case WDIOC_SETTIMEOUT:
	{
		if (get_user(new_heartbeat, p))
			return -EFAULT;
		if (iTCO_wdt_set_heartbeat(new_heartbeat))
			return -EINVAL;
		iTCO_wdt_keepalive();
		/* Fall */
	}
	case WDIOC_GETTIMEOUT:
		return put_user(heartbeat, p);
	case WDIOC_GETTIMELEFT:
	{
		int time_left;
		if (iTCO_wdt_get_timeleft(&time_left))
			return -EINVAL;
		return put_user(time_left, p);
	}
	default:
		return -ENOTTY;
	}
}

/*
 *	Kernel Interfaces
 */

static const struct file_operations iTCO_wdt_fops = {
	.owner =		THIS_MODULE,
	.llseek =		no_llseek,
	.write =		iTCO_wdt_write,
	.unlocked_ioctl =	iTCO_wdt_ioctl,
	.open =			iTCO_wdt_open,
	.release =		iTCO_wdt_release,
};

static struct miscdevice iTCO_wdt_miscdev = {
	.minor =	WATCHDOG_MINOR,
	.name =		"watchdog",
	.fops =		&iTCO_wdt_fops,
};

/*
 *	Reboot notifier
 */

static int TCO_reboot_notifier(struct notifier_block *this,
			   unsigned long code,
			   void *another_unused)
{
	if (code == SYS_HALT || code == SYS_POWER_OFF) {
		iTCO_wdt_set_reset_type(TCO_POLICY_HALT);
	}

	iTCO_wdt_last_kick(5);

#ifdef CONFIG_DEBUG_FS
	if (iTCO_wdt_private.panic_reboot_notifier) {
		BUG();
	}
#endif

	return NOTIFY_DONE;
}

static irqreturn_t tco_irq_handler(int irq, void *arg)
{
	unsigned long val32;

	pr_warn("[SHTDWN] %s, WATCHDOG TIMEOUT HANDLER!\n", __func__);

	/* reduce the timeout to the minimum, but sufficient for tracing */
	iTCO_wdt_set_heartbeat(15);
	iTCO_wdt_keepalive();

	trigger_all_cpu_backtrace();
	panic("Kernel Watchdog");

	/* This code should not be reached */

	return IRQ_HANDLED;
}

/*
 *	Init & exit routines
 */

static int iTCO_wdt_init(struct pci_dev *pdev,
		const struct pci_device_id *ent, struct platform_device *dev)
{
	int ret;
	u32 base_address;
	unsigned long val32;

	/*
	 *      Find the ACPI/PM base I/O address which is the base
	 *      for the TCO registers (TCOBASE=ACPIBASE + 0x60)
	 *      ACPIBASE is bits [15:7] from 0x40-0x43
	 */
	pci_read_config_dword(pdev, 0x40, &base_address);
	base_address &= 0x0000ff80;
	if (base_address == 0x00000000) {
		/* Something's wrong here, ACPIBASE has to be set */
		pr_err("failed to get TCOBASE address, device disabled by hardware/BIOS\n");
		return -ENODEV;
	}
	iTCO_wdt_private.iTCO_version =
			iTCO_chipset_info[ent->driver_data].iTCO_version;
	iTCO_wdt_private.ACPIBASE = base_address;
	iTCO_wdt_private.pdev = pdev;

	pci_read_config_dword(pdev, 0x44, &pmc_base_address);
	pmc_base_address &= 0xFFFFFE00;

	/*
	 * Disable watchdog on command-line demand
	 */
	if (strstr(saved_command_line, "disable_kernel_watchdog=1")) {
		pr_warn("disable_kernel_watchdog=1 watchdog will not be started\n");
		iTCO_wdt_private.enable = false;
		/* Set the NO_REBOOT bit to prevent later reboots */
		iTCO_wdt_set_NO_REBOOT_bit();
		/* Ensure Wdt is well stopped in case started by IAFW */
		iTCO_wdt_stop();
	} else {
		iTCO_wdt_private.enable = true;
		/* Check chipset's NO_REBOOT bit */
		if (iTCO_wdt_unset_NO_REBOOT_bit()) {
			pr_err("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
			ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
			goto out;
		}
	}

	/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
	if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
		pr_err("I/O address 0x%04lx already in use, device disabled\n",
		       SMI_EN);
		ret = -EIO;
		goto out;
	}
	if (!request_region(SMI_STS, 4,	"iTCO_wdt")) {
		pr_err("I/O address 0x%04lx already in use, device disabled\n",
				SMI_STS);
		ret = -EIO;
		goto unreg_smi_sts;
	}

	if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
		/* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
		val32 = inl(SMI_EN);
		val32 &= ~TCO_EN_BIT;	/* Turn off TCO watchdog timer */
		outl(val32, SMI_EN);
	}

	/* The TCO I/O registers reside in a 32-byte range pointed to
	   by the TCOBASE value */
	if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) {
		pr_err("I/O address 0x%04lx already in use, device disabled\n",
		       TCOBASE);
		ret = -EIO;
		goto unreg_smi_en;
	}

	pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
		iTCO_chipset_info[ent->driver_data].name,
		iTCO_chipset_info[ent->driver_data].iTCO_version,
		TCOBASE);

	/* Check that the heartbeat value is within it's range;
	   if not reset to the default */
	if (iTCO_wdt_set_heartbeat(heartbeat)) {
		iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
		pr_info("timeout value out of range, using %d\n", heartbeat);
	}

	ret = misc_register(&iTCO_wdt_miscdev);
	if (ret != 0) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       WATCHDOG_MINOR, ret);
		goto unreg_region;
	}

	pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
		heartbeat, nowayout);

	/* Reset OS policy */
	iTCO_wdt_set_reset_type(TCO_POLICY_NORM);

	ret = acpi_register_gsi(NULL, TCO_WARNING_IRQ,
				ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH);
	if (ret < 0) {
		pr_err("failed to configure TCO warning IRQ %d\n", TCO_WARNING_IRQ);
		goto misc_unreg;
	}
	ret = request_irq(TCO_WARNING_IRQ, tco_irq_handler, 0, "tco_watchdog", NULL);
	if (ret < 0) {
		pr_err("failed to request TCO warning IRQ %d\n", TCO_WARNING_IRQ);
		goto gsi_unreg;
	}

	/* Clear old TCO timeout status */
	val32 = TCO_TIMEOUT_BIT | SECOND_TO_STS_BIT;
	outl(val32, TCO1_STS);
	/* Clear the SMI status */
	outl(TCO_STS_BIT, SMI_STS);

	/* Enable SMI for TCO */
	val32 = inl(SMI_EN);
	val32 |= TCO_EN_BIT;
	outl(val32, SMI_EN);
	/* then ensure that PMC is ready to handle next SMI */
	val32 |= EOS_BIT;
	outl(val32, SMI_EN);

	reboot_notifier.notifier_call = TCO_reboot_notifier;
	reboot_notifier.priority = 1;
	ret = register_reboot_notifier(&reboot_notifier);
	if (ret)
		/* We continue as reboot notifier is not critical for
			 * watchdog */
		pr_err("cannot register reboot notifier %d\n", ret);

	return 0;

gsi_unreg:
	acpi_unregister_gsi(TCO_WARNING_IRQ);
misc_unreg:
	misc_deregister(&iTCO_wdt_miscdev);
unreg_region:
	release_region(TCOBASE, 0x20);
unreg_smi_sts:
	release_region(SMI_STS, 4);
unreg_smi_en:
	release_region(SMI_EN, 4);
out:
	iTCO_wdt_private.ACPIBASE = 0;
	return ret;
}
示例#5
0
static uint64_t get_acpi_pm_tick(void) { return (uint64_t)inl(pmtmr_ioport); }
示例#6
0
static int
bvm_dbg_getc(void)
{

	return (inl(bvm_dbg_port));
}
示例#7
0
static void i82801dx_power_options(struct device *dev)
{
	u8 reg8;
	u16 reg16, pmbase;
	u32 reg32;
	const char *state;

	int pwr_on = CONFIG_MAINBOARD_POWER_FAILURE_STATE;
	int nmi_option;

	/* Which state do we want to goto after g3 (power restored)?
	 * 0 == S0 Full On
	 * 1 == S5 Soft Off
	 *
	 * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
	 */
	pwr_on = MAINBOARD_POWER_ON;
	get_option(&pwr_on, "power_on_after_fail");

	reg8 = pci_read_config8(dev, GEN_PMCON_3);
	reg8 &= 0xfe;
	switch (pwr_on) {
		case MAINBOARD_POWER_OFF:
			reg8 |= 1;
			state = "off";
			break;
		case MAINBOARD_POWER_ON:
			reg8 &= ~1;
			state = "on";
			break;
		case MAINBOARD_POWER_KEEP:
			reg8 &= ~1;
			state = "state keep";
			break;
		default:
			state = "undefined";
	}

	reg8 &= ~(1 << 3);	/* minimum asssertion is 1 to 2 RTCCLK */

	pci_write_config8(dev, GEN_PMCON_3, reg8);
	printk(BIOS_INFO, "Set power %s after power failure.\n", state);

	/* Set up NMI on errors. */
	reg8 = inb(0x61);
	reg8 &= 0x0f;		/* Higher Nibble must be 0 */
	reg8 &= ~(1 << 3);	/* IOCHK# NMI Enable */
	// reg8 &= ~(1 << 2);	/* PCI SERR# Enable */
	reg8 |= (1 << 2); /* PCI SERR# Disable for now */
	outb(reg8, 0x61);

	reg8 = inb(0x70);
	nmi_option = NMI_OFF;
	get_option(&nmi_option, "nmi");
	if (nmi_option) {
		printk(BIOS_INFO, "NMI sources enabled.\n");
		reg8 &= ~(1 << 7);	/* Set NMI. */
	} else {
		printk(BIOS_INFO, "NMI sources disabled.\n");
		reg8 |= (1 << 7);	/* Disable NMI. */
	}
	outb(reg8, 0x70);

	/* Set SMI# rate down and enable CPU_SLP# */
	reg16 = pci_read_config16(dev, GEN_PMCON_1);
	reg16 &= ~(3 << 0);	// SMI# rate 1 minute
	reg16 |= (1 << 5);	// CPUSLP_EN Desktop only
	pci_write_config16(dev, GEN_PMCON_1, reg16);

	pmbase = pci_read_config16(dev, 0x40) & 0xfffe;

	/* Set up power management block and determine sleep mode */
	reg32 = inl(pmbase + 0x04); // PM1_CNT

	reg32 &= ~(7 << 10);	// SLP_TYP
	reg32 |= (1 << 0);	// SCI_EN
	outl(reg32, pmbase + 0x04);
}
示例#8
0
static void lpc_init(device_t dev)
{
	uint8_t byte;
	uint8_t byte_old;
	int on;
	int nmi_option;

	printk(BIOS_DEBUG, "LPC_INIT -------->\n");
	pc_keyboard_init();

	lpc_usb_legacy_init(dev);
	lpc_common_init(dev);

	/* power after power fail */


	on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
	get_option(&on, "power_on_after_fail");
	byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
	byte &= ~0x40;
	if (!on) {
		byte |= 0x40;
	}
	pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
	printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");

	/* Throttle the CPU speed down for testing */
	on = SLOW_CPU_OFF;
	get_option(&on, "slow_cpu");
	if(on) {
		uint16_t pm10_bar;
		uint32_t dword;
		pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
		outl(((on<<1)+0x10)  ,(pm10_bar + 0x10));
		dword = inl(pm10_bar + 0x10);
		on = 8-on;
		printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
				(on*12)+(on>>1),(on&1)*5);
	}

        /* Enable Error reporting */
        /* Set up sync flood detected */
        byte = pci_read_config8(dev, 0x47);
        byte |= (1 << 1);
        pci_write_config8(dev, 0x47, byte);

        /* Set up NMI on errors */
        byte = inb(0x70); // RTC70
        byte_old = byte;
        nmi_option = NMI_OFF;
        get_option(&nmi_option, "nmi");
        if (nmi_option) {
                byte &= ~(1 << 7); /* set NMI */
        } else {
                byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
        }
        if( byte != byte_old) {
                outb(byte, 0x70);
        }

        /* Initialize the real time clock */
        cmos_init(0);

        /* Initialize isa dma */
        isa_dma_init();

        printk(BIOS_DEBUG, "LPC_INIT <--------\n");
}
示例#9
0
DLLEXPORT unsigned int hal_inl(unsigned long port)
{
	return inl(port);
}
示例#10
0
/*==========================================================================*
 * Name:         smp_prepare_cpus (old smp_boot_cpus)
 *
 * Description:  This routine boot up APs.
 *
 * Born on Date: 2002.02.05
 *
 * Arguments:    NONE
 *
 * Returns:      void (cannot fail)
 *
 * Modification log:
 * Date       Who Description
 * ---------- --- --------------------------------------------------------
 * 2003-06-24 hy  modify for linux-2.5.69
 *
 *==========================================================================*/
void __init smp_prepare_cpus(unsigned int max_cpus)
{
	int phys_id;
	unsigned long nr_cpu;

	nr_cpu = inl(M32R_FPGA_NUM_OF_CPUS_PORTL);
	if (nr_cpu > NR_CPUS) {
		printk(KERN_INFO "NUM_OF_CPUS reg. value [%ld] > NR_CPU [%d]",
			nr_cpu, NR_CPUS);
		goto smp_done;
	}
	for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)
		physid_set(phys_id, phys_cpu_present_map);

	show_mp_info(nr_cpu);

	init_ipi_lock();

	/*
	 * Setup boot CPU information
	 */
	smp_store_cpu_info(0); /* Final full version of the data */
	smp_tune_scheduling();

	/*
	 * If SMP should be disabled, then really disable it!
	 */
	if (!max_cpus) {
		printk(KERN_INFO "SMP mode deactivated by commandline.\n");
		goto smp_done;
	}

	/*
	 * Now scan the CPU present map and fire up the other CPUs.
	 */
	Dprintk("CPU present map : %lx\n", physids_coerce(phys_cpu_present_map));

	for (phys_id = 0 ; phys_id < NR_CPUS ; phys_id++) {
		/*
		 * Don't even attempt to start the boot CPU!
		 */
		if (phys_id == bsp_phys_id)
			continue;

		if (!physid_isset(phys_id, phys_cpu_present_map))
			continue;

		if ((max_cpus >= 0) && (max_cpus <= cpucount + 1))
			continue;

		do_boot_cpu(phys_id);

		/*
		 * Make sure we unmap all failed CPUs
		 */
		if (physid_to_cpu(phys_id) == -1) {
			physid_clear(phys_id, phys_cpu_present_map);
			printk("phys CPU#%d not responding - " \
				"cannot use it.\n", phys_id);
		}
	}

smp_done:
	Dprintk("Boot done.\n");
}
示例#11
0
static int dhahelper_ioctl(struct inode *inode, struct file *file,
    unsigned int cmd, unsigned long arg)
{
    if (dhahelper_verbosity > 1)
	printk(KERN_DEBUG "dhahelper: ioctl(cmd=%x, arg=%lx)\n",
	    cmd, arg);

    if (MINOR(inode->i_rdev) != 0)
	return -ENXIO;

    switch(cmd)
    {
	case DHAHELPER_GET_VERSION:
	{
	    int version = API_VERSION;

	    if (copy_to_user((int *)arg, &version, sizeof(int)))
	    {
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");
		return -EFAULT;
	    }

	    break;
	}
	case DHAHELPER_PORT:
	{
	    dhahelper_port_t port;

	    if (copy_from_user(&port, (dhahelper_port_t *)arg, sizeof(dhahelper_port_t)))
	    {
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");
		return -EFAULT;
	    }

	    switch(port.operation)
	    {
		case PORT_OP_READ:
		{
		    switch(port.size)
		    {
			case 1:
			    port.value = inb(port.addr);
			    break;
			case 2:
			    port.value = inw(port.addr);
			    break;
			case 4:
			    port.value = inl(port.addr);
			    break;
			default:
			    if (dhahelper_verbosity > 0)
				printk(KERN_ERR "dhahelper: invalid port read size (%d)\n",
				    port.size);
			    return -EINVAL;
		    }
		    break;
		}
		case PORT_OP_WRITE:
		{
		    switch(port.size)
		    {
			case 1:
			    outb(port.value, port.addr);
			    break;
			case 2:
			    outw(port.value, port.addr);
			    break;
			case 4:
			    outl(port.value, port.addr);
			    break;
			default:
			    if (dhahelper_verbosity > 0)
				printk(KERN_ERR "dhahelper: invalid port write size (%d)\n",
				    port.size);
			    return -EINVAL;
		    }
		    break;
		}
		default:
		    if (dhahelper_verbosity > 0)
		        printk(KERN_ERR "dhahelper: invalid port operation (%d)\n",
		    	    port.operation);
		    return -EINVAL;
	    }

	    /* copy back only if read was performed */
	    if (port.operation == PORT_OP_READ)
	    if (copy_to_user((dhahelper_port_t *)arg, &port, sizeof(dhahelper_port_t)))
	    {
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");
		return -EFAULT;
	    }

	    break;
	}
	case DHAHELPER_MEMORY:
	{
	    dhahelper_memory_t mem;

	    if (copy_from_user(&mem, (dhahelper_memory_t *)arg, sizeof(dhahelper_memory_t)))
	    {
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");
		return -EFAULT;
	    }

	    switch(mem.operation)
	    {
		case MEMORY_OP_MAP:
		{
#if 1
		    memcpy(&last_mem_request, &mem, sizeof(dhahelper_memory_t));
#else
		    mem.ret = do_mmap(file, mem.start, mem.size, PROT_READ|PROT_WRITE,
			MAP_SHARED, mem.offset);
#endif

		    break;
		}
		case MEMORY_OP_UNMAP:
		    break;
		default:
		    if (dhahelper_verbosity > 0)
			printk(KERN_ERR "dhahelper: invalid memory operation (%d)\n",
			    mem.operation);
		    return -EINVAL;
	    }

	    if (copy_to_user((dhahelper_memory_t *)arg, &mem, sizeof(dhahelper_memory_t)))
	    {
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");
		return -EFAULT;
	    }

	    break;
	}
	default:
    	    if (dhahelper_verbosity > 0)
		printk(KERN_ERR "dhahelper: invalid ioctl (%x)\n", cmd);
	    return -EINVAL;
    }

    return 0;
}
示例#12
0
文件: ac3200.c 项目: ivucica/linux
static int __init ac_probe1(int ioaddr, struct net_device *dev)
{
	int i, retval;

	if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
		return -EBUSY;

	if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
		retval = -ENODEV;
		goto out;
	}

	if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
		retval = -ENODEV;
		goto out;
	}

#ifndef final_version
	printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
		   " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
		   inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
		   inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
#endif

	printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
	for(i = 0; i < 6; i++)
		printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i));

#if 0
	/* Check the vendor ID/prefix. Redundant after checking the EISA ID */
	if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
		|| inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
		|| inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
		printk(", not found (invalid prefix).\n");
		retval = -ENODEV;
		goto out;
	}
#endif

	/* Assign and allocate the interrupt now. */
	if (dev->irq == 0) {
		dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
		printk(", using");
	} else {
		dev->irq = irq_canonicalize(dev->irq);
		printk(", assigning");
	}

	retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
	if (retval) {
		printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
		goto out1;
	}

	printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);

	dev->base_addr = ioaddr;

#ifdef notyet
	if (dev->mem_start)	{		/* Override the value from the board. */
		for (i = 0; i < 7; i++)
			if (addrmap[i] == dev->mem_start)
				break;
		if (i >= 7)
			i = 0;
		outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
	}
#endif

	dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
	dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));

	printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
			dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);

	/*
	 *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
	 *  the card mem within the region covered by `normal' RAM  !!!
	 *
	 *  ioremap() will fail in that case.
	 */
	ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100);
	if (!ei_status.mem) {
		printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
		printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
		printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
		retval = -EINVAL;
		goto out1;
	}
	printk("ac3200.c: remapped %dkB card memory to virtual address %p\n",
			AC_STOP_PG/4, ei_status.mem);

	dev->mem_start = (unsigned long)ei_status.mem;
	dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256;

	ei_status.name = "AC3200";
	ei_status.tx_start_page = AC_START_PG;
	ei_status.rx_start_page = AC_START_PG + TX_PAGES;
	ei_status.stop_page = AC_STOP_PG;
	ei_status.word16 = 1;

	if (ei_debug > 0)
		printk(version);

	ei_status.reset_8390 = &ac_reset_8390;
	ei_status.block_input = &ac_block_input;
	ei_status.block_output = &ac_block_output;
	ei_status.get_8390_hdr = &ac_get_8390_hdr;

	dev->open = &ac_open;
	dev->stop = &ac_close_card;
#ifdef CONFIG_NET_POLL_CONTROLLER
	dev->poll_controller = ei_poll;
#endif
	NS8390_init(dev, 0);

	retval = register_netdev(dev);
	if (retval)
		goto out2;
	return 0;
out2:
	if (ei_status.reg0)
		iounmap(ei_status.mem);
out1:
	free_irq(dev->irq, dev);
out:
	release_region(ioaddr, AC_IO_EXTENT);
	return retval;
}
示例#13
0
文件: iTCO_wdt.c 项目: 19Dan01/linux
static int iTCO_wdt_probe(struct platform_device *dev)
{
	int ret = -ENODEV;
	unsigned long val32;
	struct lpc_ich_info *ich_info = dev_get_platdata(&dev->dev);

	if (!ich_info)
		goto out;

	spin_lock_init(&iTCO_wdt_private.io_lock);

	iTCO_wdt_private.tco_res =
		platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_TCO);
	if (!iTCO_wdt_private.tco_res)
		goto out;

	iTCO_wdt_private.smi_res =
		platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_SMI);
	if (!iTCO_wdt_private.smi_res)
		goto out;

	iTCO_wdt_private.iTCO_version = ich_info->iTCO_version;
	iTCO_wdt_private.dev = dev;
	iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent);

	/*
	 * Get the Memory-Mapped GCS or PMC register, we need it for the
	 * NO_REBOOT flag (TCO v2 and v3).
	 */
	if (iTCO_wdt_private.iTCO_version >= 2) {
		iTCO_wdt_private.gcs_pmc_res = platform_get_resource(dev,
							IORESOURCE_MEM,
							ICH_RES_MEM_GCS_PMC);

		if (!iTCO_wdt_private.gcs_pmc_res)
			goto out;

		if (!request_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
			resource_size(iTCO_wdt_private.gcs_pmc_res), dev->name)) {
			ret = -EBUSY;
			goto out;
		}
		iTCO_wdt_private.gcs_pmc = ioremap(iTCO_wdt_private.gcs_pmc_res->start,
			resource_size(iTCO_wdt_private.gcs_pmc_res));
		if (!iTCO_wdt_private.gcs_pmc) {
			ret = -EIO;
			goto unreg_gcs_pmc;
		}
	}

	/* Check chipset's NO_REBOOT bit */
	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
		pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
		goto unmap_gcs_pmc;
	}

	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
	iTCO_wdt_set_NO_REBOOT_bit();

	/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
	if (!request_region(iTCO_wdt_private.smi_res->start,
			resource_size(iTCO_wdt_private.smi_res), dev->name)) {
		pr_err("I/O address 0x%04llx already in use, device disabled\n",
		       (u64)SMI_EN);
		ret = -EBUSY;
		goto unmap_gcs_pmc;
	}
	if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
		/*
		 * Bit 13: TCO_EN -> 0
		 * Disables TCO logic generating an SMI#
		 */
		val32 = inl(SMI_EN);
		val32 &= 0xffffdfff;	/* Turn off SMI clearing watchdog */
		outl(val32, SMI_EN);
	}

	if (!request_region(iTCO_wdt_private.tco_res->start,
			resource_size(iTCO_wdt_private.tco_res), dev->name)) {
		pr_err("I/O address 0x%04llx already in use, device disabled\n",
		       (u64)TCOBASE);
		ret = -EBUSY;
		goto unreg_smi;
	}

	pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n",
		ich_info->name, ich_info->iTCO_version, (u64)TCOBASE);

	/* Clear out the (probably old) status */
	if (iTCO_wdt_private.iTCO_version == 3) {
		outl(0x20008, TCO1_STS);
	} else {
		outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
		outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
		outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
	}

	iTCO_wdt_watchdog_dev.bootstatus = 0;
	iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT;
	watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout);
	iTCO_wdt_watchdog_dev.parent = &dev->dev;

	/* Make sure the watchdog is not running */
	iTCO_wdt_stop(&iTCO_wdt_watchdog_dev);

	/* Check that the heartbeat value is within it's range;
	   if not reset to the default */
	if (iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, heartbeat)) {
		iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, WATCHDOG_TIMEOUT);
		pr_info("timeout value out of range, using %d\n",
			WATCHDOG_TIMEOUT);
	}

	ret = watchdog_register_device(&iTCO_wdt_watchdog_dev);
	if (ret != 0) {
		pr_err("cannot register watchdog device (err=%d)\n", ret);
		goto unreg_tco;
	}

	pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
		heartbeat, nowayout);

	return 0;

unreg_tco:
	release_region(iTCO_wdt_private.tco_res->start,
			resource_size(iTCO_wdt_private.tco_res));
unreg_smi:
	release_region(iTCO_wdt_private.smi_res->start,
			resource_size(iTCO_wdt_private.smi_res));
unmap_gcs_pmc:
	if (iTCO_wdt_private.iTCO_version >= 2)
		iounmap(iTCO_wdt_private.gcs_pmc);
unreg_gcs_pmc:
	if (iTCO_wdt_private.iTCO_version >= 2)
		release_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
				resource_size(iTCO_wdt_private.gcs_pmc_res));
out:
	iTCO_wdt_private.tco_res = NULL;
	iTCO_wdt_private.smi_res = NULL;
	iTCO_wdt_private.gcs_pmc_res = NULL;
	iTCO_wdt_private.gcs_pmc = NULL;

	return ret;
}
示例#14
0
int
pci_mode_detect(void)
{

#ifdef PCI_CONF_MODE
#if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
	return (pci_mode = PCI_CONF_MODE);
#else
#error Invalid PCI configuration mode.
#endif
#else
	u_int32_t sav, val;
	int i;
	pcireg_t idreg;

	if (pci_mode != -1)
		return (pci_mode);

#if NBIOS > 0
	/*
	 * If we have PCI info passed from the BIOS, use the mode given there
	 * for all of this code.  If not, pass on through to the previous tests
	 * to try and divine the correct mode.
	 */
	if (bios_pciinfo != NULL) {
		if (bios_pciinfo->pci_chars & 0x2)
			return (pci_mode = 2);

		if (bios_pciinfo->pci_chars & 0x1)
			return (pci_mode = 1);

		/* We should never get here, but if we do, fall through... */
	}
#endif

	/*
	 * We try to divine which configuration mode the host bridge wants.
	 *
	 * This should really be done using the PCI BIOS.  If we get here, the
	 * PCI BIOS does not exist, or the boot blocks did not provide the
	 * information.
	 */

	sav = inl(PCI_MODE1_ADDRESS_REG);

	pci_mode = 1; /* assume this for now */
	/*
	 * catch some known buggy implementations of mode 1
	 */
	for (i = 0; i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]);
	     i++) {
		pcitag_t t;

		if (!pcim1_quirk_tbl[i].tag)
			break;
		t.mode1 = pcim1_quirk_tbl[i].tag;
		idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
		if (idreg == pcim1_quirk_tbl[i].id) {
#ifdef DEBUG
			printf("known mode 1 PCI chipset (%08x)\n",
			       idreg);
#endif
			return (pci_mode);
		}
	}

	/*
	 * Strong check for standard compliant mode 1:
	 * 1. bit 31 ("enable") can be set
	 * 2. byte/word access does not affect register
 	 */
	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
	outb(PCI_MODE1_ADDRESS_REG + 3, 0);
	outw(PCI_MODE1_ADDRESS_REG + 2, 0);
	val = inl(PCI_MODE1_ADDRESS_REG);
	if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
#ifdef DEBUG
		printf("pci_mode_detect: mode 1 enable failed (%x)\n",
		       val);
#endif
		goto not1;
	}
	outl(PCI_MODE1_ADDRESS_REG, 0);
	val = inl(PCI_MODE1_ADDRESS_REG);
	if ((val & 0x80fffffc) != 0)
		goto not1;
	return (pci_mode);
not1:
	outl(PCI_MODE1_ADDRESS_REG, sav);
 
	/*
	 * This mode 2 check is quite weak (and known to give false
	 * positives on some Compaq machines).
	 * However, this doesn't matter, because this is the
	 * last test, and simply no PCI devices will be found if
	 * this happens.
	 */
	outb(PCI_MODE2_ENABLE_REG, 0);
	outb(PCI_MODE2_FORWARD_REG, 0);
	if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
	    inb(PCI_MODE2_FORWARD_REG) != 0)
		goto not2;
	return (pci_mode = 2);
not2:
	return (pci_mode = 0);
#endif
}
示例#15
0
文件: lpc.c 项目: mytbk/coreboot
static void pch_power_options(device_t dev)
{
	u8 reg8;
	u16 reg16, pmbase;
	u32 reg32;
	const char *state;
	/* Get the chip configuration */
	config_t *config = dev->chip_info;

	int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
	int nmi_option;

	/* Which state do we want to goto after g3 (power restored)?
	 * 0 == S0 Full On
	 * 1 == S5 Soft Off
	 *
	 * If the option is not existent (Laptops), use Kconfig setting.
	 */
	get_option(&pwr_on, "power_on_after_fail");

	reg16 = pci_read_config16(dev, GEN_PMCON_3);
	reg16 &= 0xfffe;
	switch (pwr_on) {
	case MAINBOARD_POWER_OFF:
		reg16 |= 1;
		state = "off";
		break;
	case MAINBOARD_POWER_ON:
		reg16 &= ~1;
		state = "on";
		break;
	case MAINBOARD_POWER_KEEP:
		reg16 &= ~1;
		state = "state keep";
		break;
	default:
		state = "undefined";
	}

	reg16 &= ~(3 << 4);	/* SLP_S4# Assertion Stretch 4s */
	reg16 |= (1 << 3);	/* SLP_S4# Assertion Stretch Enable */

	reg16 &= ~(1 << 10);
	reg16 |= (1 << 11);	/* SLP_S3# Min Assertion Width 50ms */

	reg16 |= (1 << 12);	/* Disable SLP stretch after SUS well */

	pci_write_config16(dev, GEN_PMCON_3, reg16);
	printk(BIOS_INFO, "Set power %s after power failure.\n", state);

	/* Set up NMI on errors. */
	reg8 = inb(0x61);
	reg8 &= 0x0f;		/* Higher Nibble must be 0 */
	reg8 &= ~(1 << 3);	/* IOCHK# NMI Enable */
	// reg8 &= ~(1 << 2);	/* PCI SERR# Enable */
	reg8 |= (1 << 2); /* PCI SERR# Disable for now */
	outb(reg8, 0x61);

	reg8 = inb(0x70);
	nmi_option = NMI_OFF;
	get_option(&nmi_option, "nmi");
	if (nmi_option) {
		printk(BIOS_INFO, "NMI sources enabled.\n");
		reg8 &= ~(1 << 7);	/* Set NMI. */
	} else {
		printk(BIOS_INFO, "NMI sources disabled.\n");
		reg8 |= ( 1 << 7);	/* Can't mask NMI from PCI-E and NMI_NOW */
	}
	outb(reg8, 0x70);

	/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
	reg16 = pci_read_config16(dev, GEN_PMCON_1);
	reg16 &= ~(3 << 0);	// SMI# rate 1 minute
	reg16 &= ~(1 << 10);	// Disable BIOS_PCI_EXP_EN for native PME
#if DEBUG_PERIODIC_SMIS
	/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using
	 * periodic SMIs.
	 */
	reg16 |= (3 << 0); // Periodic SMI every 8s
#endif
	pci_write_config16(dev, GEN_PMCON_1, reg16);

	// Set the board's GPI routing.
	pch_gpi_routing(dev);

	pmbase = pci_read_config16(dev, 0x40) & 0xfffe;

	outl(config->gpe0_en, pmbase + GPE0_EN);
	outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);

	/* Set up power management block and determine sleep mode */
	reg32 = inl(pmbase + 0x04); // PM1_CNT
	reg32 &= ~(7 << 10);	// SLP_TYP
	reg32 |= (1 << 0);	// SCI_EN
	outl(reg32, pmbase + 0x04);

	/* Clear magic status bits to prevent unexpected wake */
	reg32 = RCBA32(0x3310);
	reg32 |= (1 << 4)|(1 << 5)|(1 << 0);
	RCBA32(0x3310) = reg32;

	reg32 = RCBA32(0x3f02);
	reg32 &= ~0xf;
	RCBA32(0x3f02) = reg32;
}
示例#16
0
/* prepare playback callback */
static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream)
{
	ca0106_t *emu = snd_pcm_substream_chip(substream);
	snd_pcm_runtime_t *runtime = substream->runtime;
	ca0106_pcm_t *epcm = runtime->private_data;
	int channel = epcm->channel_id;
	u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
	u32 hcfg_mask = HCFG_PLAYBACK_S32_LE;
	u32 hcfg_set = 0x00000000;
	u32 hcfg;
	u32 reg40_mask = 0x30000 << (channel<<1);
	u32 reg40_set = 0;
	u32 reg40;
	/* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
	u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
	u32 reg71_set = 0;
	u32 reg71;
	int i;
	
        //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
        //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
	//snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
	/* Rate can be set per channel. */
	/* reg40 control host to fifo */
	/* reg71 controls DAC rate. */
	switch (runtime->rate) {
	case 44100:
		reg40_set = 0x10000 << (channel<<1);
		reg71_set = 0x01010000; 
		break;
        case 48000:
		reg40_set = 0;
		reg71_set = 0; 
		break;
	case 96000:
		reg40_set = 0x20000 << (channel<<1);
		reg71_set = 0x02020000; 
		break;
	case 192000:
		reg40_set = 0x30000 << (channel<<1);
		reg71_set = 0x03030000; 
		break;
	default:
		reg40_set = 0;
		reg71_set = 0; 
		break;
	}
	/* Format is a global setting */
	/* FIXME: Only let the first channel accessed set this. */
	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S16_LE:
		hcfg_set = 0;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		hcfg_set = HCFG_PLAYBACK_S32_LE;
		break;
	default:
		hcfg_set = 0;
		break;
	}
	hcfg = inl(emu->port + HCFG) ;
	hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
	outl(hcfg, emu->port + HCFG);
	reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
	reg40 = (reg40 & ~reg40_mask) | reg40_set;
	snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
	reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
	reg71 = (reg71 & ~reg71_mask) | reg71_set;
	snd_ca0106_ptr_write(emu, 0x71, 0, reg71);

	/* FIXME: Check emu->buffer.size before actually writing to it. */
        for(i=0; i < runtime->periods; i++) {
		table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
		table_base[(i*2)+1]=period_size_bytes<<16;
	}
 
	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
	snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
	snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
	/* FIXME  test what 0 bytes does. */
	snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
	snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
	snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
	snd_ca0106_ptr_write(emu, 0x08, channel, 0);
        snd_ca0106_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
#if 0
	snd_ca0106_ptr_write(emu, SPCS0, 0,
			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
			       SPCS_GENERATIONSTATUS | 0x00001200 |
			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
	}
示例#17
0
文件: gpio.c 项目: MrTomasz/coreboot
/* Early mainboard specific GPIO setup. */
static void mb_gpio_init(void)
{
	device_t dev;
	uint16_t port;
	uint32_t set_gpio;

	/* Southbridge GPIOs. */
	/* Set the LPC device statically. */
	dev = PCI_DEV(0x0, 0x1f, 0x0);

	/* Set the value for GPIO base address register and enable GPIO. */
	pci_write_config32(dev, GPIO_BASE, (ICH_IO_BASE_ADDR | 1));
	pci_write_config8(dev, GPIO_CNTL, 0x10);

	/* Set GPIO23 to high, this enables the LAN controller. */
	udelay(10);
	set_gpio = inl(ICH_IO_BASE_ADDR + 0x0c);
	set_gpio |= 1 << 23;
	outl(set_gpio, ICH_IO_BASE_ADDR + 0x0c);

	/* Disable AC97 Modem */
	pci_write_config8(dev, 0xf2, 0x40);

	/* Super I/O GPIOs. */
	dev = PME_DEV;
	port = dev >> 8;

	/* Enter the configuration state. */
	outb(0x55, port);
	pnp_set_logical_device(dev);
	pnp_set_enable(dev, 0);
	pnp_set_iobase(dev, PNP_IDX_IO0, PME_IO_BASE_ADDR);
	pnp_set_enable(dev, 1);

	/* GP21 - LED_RED */
	outl(0x01, PME_IO_BASE_ADDR + 0x2c);

	/* GP30 - FAN2_TACH */
	outl(0x05, PME_IO_BASE_ADDR + 0x33);

	/* GP31 - FAN1_TACH */
	outl(0x05, PME_IO_BASE_ADDR + 0x34);

	/* GP32 - FAN2_CTRL */
	outl(0x04, PME_IO_BASE_ADDR + 0x35);

	/* GP33 - FAN1_CTRL */
	outl(0x04, PME_IO_BASE_ADDR + 0x36);

	/* GP34 - AUD_MUTE_OUT_R */
	outl(0x00, PME_IO_BASE_ADDR + 0x37);

	/* GP36 - KBRST */
	outl(0x00, PME_IO_BASE_ADDR + 0x39);

	/* GP37 - A20GATE */
	outl(0x00, PME_IO_BASE_ADDR + 0x3a);

	/* GP42 - GPIO_PME_OUT */
	outl(0x00, PME_IO_BASE_ADDR + 0x3d);

	/* GP50 - SER2_RI */
	outl(0x05, PME_IO_BASE_ADDR + 0x3f);

	/* GP51 - SER2_DCD */
	outl(0x05, PME_IO_BASE_ADDR + 0x40);

	/* GP52 - SER2_RX */
	outl(0x05, PME_IO_BASE_ADDR + 0x41);

	/* GP53 - SER2_TX */
	outl(0x04, PME_IO_BASE_ADDR + 0x42);

	/* GP55 - SER2_RTS */
	outl(0x04, PME_IO_BASE_ADDR + 0x44);

	/* GP56 - SER2_CTS */
	outl(0x05, PME_IO_BASE_ADDR + 0x45);

	/* GP57 - SER2_DTR */
	outl(0x04, PME_IO_BASE_ADDR + 0x46);

	/* GP60 - LED_GREEN */
	outl(0x01, PME_IO_BASE_ADDR + 0x47);

	/* GP61 - LED_YELLOW */
	outl(0x01, PME_IO_BASE_ADDR + 0x48);

	/* GP3 */
	outl(0xc0, PME_IO_BASE_ADDR + 0x4d);

	/* GP4 */
	outl(0x04, PME_IO_BASE_ADDR + 0x4e);

	/* FAN1 */
	outl(0x01, PME_IO_BASE_ADDR + 0x56);

	/* FAN2 */
	outl(0x01, PME_IO_BASE_ADDR + 0x57);

	/* Fan Control */
	outl(0x50, PME_IO_BASE_ADDR + 0x58);

	/* Fan1 Tachometer */
	outl(0xff, PME_IO_BASE_ADDR + 0x59);

	/* Fan2 Tachometer */
	outl(0xff, PME_IO_BASE_ADDR + 0x5a);

	/* LED1 */
	outl(0x00, PME_IO_BASE_ADDR + 0x5d);

	/* LED2 */
	outl(0x00, PME_IO_BASE_ADDR + 0x5e);

	/* Keyboard Scan Code */
	outl(0x00, PME_IO_BASE_ADDR + 0x5f);

	/* Exit the configuration state. */
	outb(0xaa, port);
}
示例#18
0
u_int32_t
x86_bus_space_io_read_4(bus_space_handle_t h, bus_size_t o)
{
	return (inl(h + o));
}
示例#19
0
static void
netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_char val, sval;
	long flags;

	if (!cs) {
		printk(KERN_WARNING "NETjet-S: Spurious interrupt!\n");
		return;
	}
	if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) &
		NETJET_ISACIRQ)) {
		val = NETjet_ReadIC(cs, ISAC_ISTA);
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "tiger: i1 %x %x", sval, val);
		if (val) {
			isac_interrupt(cs, val);
			NETjet_WriteIC(cs, ISAC_MASK, 0xFF);
			NETjet_WriteIC(cs, ISAC_MASK, 0x0);
		}
	}
	save_flags(flags);
	cli();
	/* start new code 13/07/00 GE */
	/* set bits in sval to indicate which page is free */
	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
		/* the 2nd write page is free */
		sval = 0x08;
	else	/* the 1st write page is free */
		sval = 0x04;	
	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
		/* the 2nd read page is free */
		sval = sval | 0x02;
	else	/* the 1st read page is free */
		sval = sval | 0x01;	
	if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
	{
		if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
			restore_flags(flags);
			return;
		}
		cs->hw.njet.irqstat0 = sval;
		restore_flags(flags);
		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != 
			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
			/* we have a read dma int */
			read_tiger(cs);
		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
			/* we have a write dma int */
			write_tiger(cs);
		/* end new code 13/07/00 GE */
		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
	} else
		restore_flags(flags);

/*	if (!testcnt--) {
		cs->hw.njet.dmactrl = 0;
		byteout(cs->hw.njet.base + NETJET_DMACTRL,
			cs->hw.njet.dmactrl);
		byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
	}
*/
}
示例#20
0
static void
sis900_transmit(struct nic  *nic,
                const char  *d,     
                unsigned int t,     
                unsigned int s,     
                const char  *p)     
{
    u32 status, to, nstype;
    u32 tx_status;
    
    
    outl(TxDIS, ioaddr + cr);

    
    outl((u32) &txd, ioaddr + txdp); 
    if (sis900_debug > 1)
        printf("sis900_transmit: TX descriptor register loaded with: %X\n", 
               inl(ioaddr + txdp));

    memcpy(txb, d, ETH_ALEN);
    memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
    nstype = htons(t);
    memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
    memcpy(txb + ETH_HLEN, p, s);

    s += ETH_HLEN;
    s &= DSIZE;

    if (sis900_debug > 1)
        printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);

    
    while (s < ETH_ZLEN)  
        txb[s++] = '\0';

    
    txd.bufptr = (u32) &txb[0];
    txd.cmdsts = (u32) OWN | s;

    
    outl(TxENA, ioaddr + cr);

    if (sis900_debug > 1)
        printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);

    to = currticks() + TX_TIMEOUT;

    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
         ;

    if (currticks() >= to) {
        printf("sis900_transmit: TX Timeout! Tx status %X.\n", tx_status);
    }
    
    if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
        
        printf("sis900_transmit: Transmit error, Tx status %X.\n", tx_status);
    }
    
    outl(0, ioaddr + imr);
}
示例#21
0
/****************************************************************
 *	Name:	Irq_Handler	:LOCAL
 *
 *	Description:	Interrupt handler.
 *
 *	Parameters:		irq		- Hardware IRQ number.
 *					dev_id	-
 *					regs	-
 *
 *	Returns:		TRUE if drive is not ready in time.
 *
 ****************************************************************/
static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
	{
	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
	PADAPTER2000		padapter;		// Pointer to adapter control structure
	PDEV2000			pdev;
	Scsi_Cmnd		   *SCpnt;
	UCHAR				tag = 0;
	UCHAR				tag0;
	ULONG				error;
	int					pun;
	int					bus;
	int					z;
    unsigned long		flags;


	DEB(printk ("\npci2000 received interrupt "));
	for ( z = 0; z < NumAdapters;  z++ )										// scan for interrupt to process
		{
		if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
			{
			tag = inb_p (HOSTDATA(PsiHost[z])->tag);
			if (  tag )
				{
				shost = PsiHost[z];
				break;
				}
			}
		}

	if ( !shost )
		{
		DEB (printk ("\npci2000: not my interrupt"));
		goto out;
		}

	spin_lock_irqsave(&shost->host_lock, flags);
	padapter = HOSTDATA(shost);

	tag0 = tag & 0x7F;															// mask off the error bit
	for ( bus = 0;  bus < MAX_BUS;  bus++ )										// scan the busses
    	{
		for ( pun = 0;  pun < MAX_UNITS;  pun++ )								// scan the targets
    		{
			pdev = &padapter->dev[bus][pun];
			if ( !pdev->tag )
    			continue;
			if ( pdev->tag == tag0 )											// is this it?
				{
				pdev->tag = 0;
				SCpnt = pdev->SCpnt;
				goto unmapProceed;
    			}
			}
    	}

	outb_p (0xFF, padapter->tag);												// clear the op interrupt
	outb_p (CMD_DONE, padapter->cmd);											// complete the op
	goto irq_return;;															// done, but, with what?

unmapProceed:;
	if ( !bus )
		{
		switch ( SCpnt->cmnd[0] )
			{
			case SCSIOP_TEST_UNIT_READY:
				pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
				goto irqProceed;
			case SCSIOP_READ_CAPACITY:
				pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE);
				goto irqProceed;
			case SCSIOP_VERIFY:
			case SCSIOP_START_STOP_UNIT:
			case SCSIOP_MEDIUM_REMOVAL:
				goto irqProceed;
			}
		}
	if ( SCpnt->SCp.have_data_in )
		pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
	else 
		{
		if ( SCpnt->use_sg )
			pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
		}

irqProceed:;
	if ( tag & ERR08_TAGGED )												// is there an error here?
		{
		if ( WaitReady (padapter) )
			{
			OpDone (SCpnt, DID_TIME_OUT << 16);
			goto irq_return;;
			}

		outb_p (tag0, padapter->mb0);										// get real error code
		outb_p (CMD_ERROR, padapter->cmd);
		if ( WaitReady (padapter) )											// wait for controller to suck up the op
			{
			OpDone (SCpnt, DID_TIME_OUT << 16);
			goto irq_return;;
			}

		error = inl (padapter->mb0);										// get error data
		outb_p (0xFF, padapter->tag);										// clear the op interrupt
		outb_p (CMD_DONE, padapter->cmd);									// complete the op

		DEB (printk ("status: %lX ", error));
		if ( error == 0x00020002 )											// is this error a check condition?
			{
			if ( bus )														// are we doint SCSI commands?
				{
				OpDone (SCpnt, (DID_OK << 16) | 2);
				goto irq_return;;
				}
			if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY )
				OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);	// test caller we have sense data too
			else
				OpDone (SCpnt, DID_ERROR << 16);
			goto irq_return;;
			}
		OpDone (SCpnt, DID_ERROR << 16);
		goto irq_return;;
		}

	outb_p (0xFF, padapter->tag);											// clear the op interrupt
	outb_p (CMD_DONE, padapter->cmd);										// complete the op
	OpDone (SCpnt, DID_OK << 16);

irq_return:
    spin_unlock_irqrestore(&shost->host_lock, flags);
out:;
}
示例#22
0
static inline unsigned int snd_via82xx_codec_xread(struct via82xx_modem *chip)
{
	return inl(VIAREG(chip, AC97));
}
示例#23
0
static int pcidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret = 0;
	struct pcidev_struct *pcidev = (struct pcidev_struct *)file->private_data;
	if (!pcidev)
		return -EIO;
	switch(cmd) {
	case PCIDEV_IOCTL_FIND: {
		struct pcidev_find_struct *find;
		struct pci_dev *dev;
		unsigned long vendorID, deviceID;
		int idx;
		if (pcidev->dev)
			return -EIO; // only alloc once for now
		if (!access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct pcidev_find_struct)))
			return -EFAULT;
		find = (struct pcidev_find_struct *)arg;
		__get_user(vendorID, &find->vendorID);
		__get_user(deviceID, &find->deviceID);
		__put_user(-1, &find->bus);
		__put_user(-1, &find->device);
		__put_user(-1, &find->func);
		dev = pci_find_device(vendorID, deviceID, NULL);
		if (!dev)
			return -ENOENT;
		if (pci_enable_device(dev)) {
			printk(KERN_WARNING "pcidev: Could not enable the PCI device.\n");
			return -EIO;
		}
		if (pci_set_dma_mask(dev, 0xffffffff))
			printk(KERN_WARNING "pcidev: only limited PCI busmaster DMA support.\n");
		pci_set_master(dev);
		printk(KERN_INFO "pcidev: device found at %x:%x.%d\n", 
				dev->bus->number, PCI_SLOT(dev->devfn), 
				PCI_FUNC(dev->devfn));
		ret = pci_request_regions(dev, pcidev_name);
		if (ret < 0)
			break;
		for (idx = 0; idx < PCIDEV_COUNT_RESOURCES; idx++) {
			if (pci_resource_flags(dev, idx) & IORESOURCE_MEM) {
				long len = pci_resource_len(dev, idx);
				unsigned long mapped_start = (unsigned long)ioremap(pci_resource_start(dev, idx), len);
				__put_user(mapped_start, &find->resources[idx].start);
				__put_user(mapped_start + len - 1, &find->resources[idx].end);
				pcidev->mapped_mem[idx] = (void *)mapped_start;
			}
			else {
				pcidev->mapped_mem[idx] = NULL;
				__put_user(pci_resource_start(dev, idx), &find->resources[idx].start);
				__put_user(pci_resource_end(dev, idx), &find->resources[idx].end);
			}
			__put_user(pci_resource_flags(dev, idx), &find->resources[idx].flags);
		}
		pcidev->dev = dev;
		__put_user(dev->bus->number, &find->bus);
		__put_user(PCI_SLOT(dev->devfn), &find->device);
		__put_user(PCI_FUNC(dev->devfn), &find->func);
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_READ_CONFIG_BYTE: 
	case PCIDEV_IOCTL_READ_CONFIG_WORD: 
	case PCIDEV_IOCTL_READ_CONFIG_DWORD: {
		struct pcidev_io_struct *io;
		unsigned long address, value;
		if (!pcidev->dev)
			return -EIO;
		if (!access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		__put_user(-1, &io->value);
		printk(KERN_DEBUG "pcidev: reading config address %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_READ_CONFIG_BYTE:
			ret = pci_read_config_byte(pcidev->dev, address, (u8 *)&value);
			break;
		case PCIDEV_IOCTL_READ_CONFIG_WORD:
			ret = pci_read_config_word(pcidev->dev, address, (u16 *)&value);
			break;
		case PCIDEV_IOCTL_READ_CONFIG_DWORD:
			ret = pci_read_config_dword(pcidev->dev, address, (u32 *)&value);
			break;
		}
		if (ret < 0)
			return ret;
		__put_user(value, &io->value);
		break;
	}
	case PCIDEV_IOCTL_WRITE_CONFIG_BYTE: 
	case PCIDEV_IOCTL_WRITE_CONFIG_WORD: 
	case PCIDEV_IOCTL_WRITE_CONFIG_DWORD: {
		struct pcidev_io_struct *io;
		unsigned long address, value;
		if (!pcidev->dev)
			return -EIO;
		if (!access_ok(VERIFY_READ, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		__get_user(value, &io->value);
		/*
		 * Next tests prevent the pcidev user from remapping
		 * the PCI host device since this could cause great 
		 * trouble because we don't own those I/O resources.
		 * If the pcidev wants to remap a device he needs to
		 * emulate the mapping himself and not bother the host
		 * kernel about it.
		 */
		if (address == PCI_INTERRUPT_PIN) {
			printk(KERN_WARNING "pcidev: not allowed to set irq pin!\n");
			return -EIO;
		}
		if (address == PCI_INTERRUPT_LINE) {
			printk(KERN_WARNING "pcidev: not allowed to set irq line!\n");
			return -EIO;
		}
		if (PCI_BASE_ADDRESS_0 <= address && (address & ~3UL) <= PCI_BASE_ADDRESS_5) {
			printk(KERN_WARNING "pcidev: now allowed to change base address %d\n", 
					(int)((address & ~3UL) - PCI_BASE_ADDRESS_0) / 4);
			return -EIO;
		}
		printk(KERN_DEBUG "pcidev: writing config address %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_WRITE_CONFIG_BYTE:
			ret = pci_write_config_byte(pcidev->dev, address, (u8)value);
			break;
		case PCIDEV_IOCTL_WRITE_CONFIG_WORD:
			ret = pci_write_config_word(pcidev->dev, address, (u16)value);
			break;
		case PCIDEV_IOCTL_WRITE_CONFIG_DWORD:
			ret = pci_write_config_dword(pcidev->dev, address, (u32)value);
			break;
		}
		break;
	}
	case PCIDEV_IOCTL_INTERRUPT: {
		u8 irq;
		if (!pcidev->dev)
			return -EIO;
		ret = pci_read_config_byte(pcidev->dev, PCI_INTERRUPT_PIN, &irq);
		if (ret < 0)
			break;
		if (!irq)
			return -EIO;
		ret = pci_read_config_byte(pcidev->dev, PCI_INTERRUPT_LINE, &irq);
		if (ret < 0)
			break;
		if (arg & 1) {
			pcidev->pid = current->pid; // our dev_id
			printk(KERN_INFO "pcidev: enabling IRQ %d\n", irq);
			ret = request_irq(irq, pcidev_irqhandler, SA_SHIRQ,
					pcidev_name, (void *)current->pid);
		}
		else {
			if (!pcidev->pid)
				return -EIO;
			printk(KERN_INFO "pcidev: disabling IRQ %d\n", irq);
			free_irq(irq, (void *)pcidev->pid);
			pcidev->pid = 0;
			ret = 0;
		}
		break;
	}
	/*
	 * Next ioctl is only for testing purposes.
	 */
	case PCIDEV_IOCTL_INTERRUPT_TEST: {
		ret = -EIO;
		if (!pcidev->dev)
			break;
		if (!pcidev->pid)
			break;
		if (pcidev->irq_timer.function)
			del_timer_sync(&pcidev->irq_timer);
		pcidev->irq_timer.function = NULL;
		if (arg & 1) {
			init_timer(&pcidev->irq_timer);
			pcidev->irq_timer.function = irq_test_timer;
			pcidev->irq_timer.data = (unsigned long)pcidev;
			pcidev->irq_timer.expires = jiffies + HZ;
			add_timer(&pcidev->irq_timer);
		}
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_READ_IO_BYTE: 
	case PCIDEV_IOCTL_READ_IO_WORD: 
	case PCIDEV_IOCTL_READ_IO_DWORD: {
		/*
		 * We should probably check access rights against
		 * the PCI resource list... but who cares for a 
		 * security hole more or less :)
		 */
		struct pcidev_io_struct *io;
		unsigned long address, value = -1;
		if (!access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		printk(KERN_DEBUG "pcidev: reading I/O port %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_READ_IO_BYTE:
			value = inb(address);
			break;
		case PCIDEV_IOCTL_READ_IO_WORD:
			value = inw(address);
			break;
		case PCIDEV_IOCTL_READ_IO_DWORD:
			value = inl(address);
			break;
		}
		__put_user(value, &io->value);
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_WRITE_IO_BYTE: 
	case PCIDEV_IOCTL_WRITE_IO_WORD: 
	case PCIDEV_IOCTL_WRITE_IO_DWORD: {
		struct pcidev_io_struct *io;
		unsigned long address, value;
		if (!access_ok(VERIFY_READ, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		__get_user(value, &io->value);
		printk(KERN_DEBUG "pcidev: writing I/O port %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_WRITE_IO_BYTE:
			outb(value, address);
			break;
		case PCIDEV_IOCTL_WRITE_IO_WORD:
			outw(value, address);
			break;
		case PCIDEV_IOCTL_WRITE_IO_DWORD:
			outl(value, address);
			break;
		}
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_READ_MEM_BYTE: 
	case PCIDEV_IOCTL_READ_MEM_WORD: 
	case PCIDEV_IOCTL_READ_MEM_DWORD: {
		struct pcidev_io_struct *io;
		unsigned long address, value = -1;
		if (!access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		printk(KERN_DEBUG "pcidev: reading memory %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_READ_MEM_BYTE:
			value = readb((unsigned char *)address);
			break;
		case PCIDEV_IOCTL_READ_MEM_WORD:
			value = readw((unsigned short *)address);
			break;
		case PCIDEV_IOCTL_READ_MEM_DWORD:
			value = readl((unsigned int *)address);
			break;
		}
		__put_user(value, &io->value);
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_WRITE_MEM_BYTE: 
	case PCIDEV_IOCTL_WRITE_MEM_WORD:
	case PCIDEV_IOCTL_WRITE_MEM_DWORD: {
		struct pcidev_io_struct *io;
		unsigned long address, value;
		if (!access_ok(VERIFY_READ, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		__get_user(value, &io->value);
		printk(KERN_DEBUG "pcidev: writing memory %#x\n", (int)address);
		switch(cmd) {
		case PCIDEV_IOCTL_WRITE_MEM_BYTE:
			writeb(value, (unsigned char *)address);
			break;
		case PCIDEV_IOCTL_WRITE_MEM_WORD:
			writew(value, (unsigned short *)address);
			break;
		case PCIDEV_IOCTL_WRITE_MEM_DWORD:
			writel(value, (unsigned int *)address);
			break;
		}
		ret = 0;
		break;
	}
	case PCIDEV_IOCTL_PROBE_CONFIG_DWORD: {
		/*
		 * This ioctl allows for probing a config space value.
		 * This can be used for base address size probing
		 */
		struct pcidev_io_struct *io;
		unsigned long address, value, orig_value;
		if (!pcidev->dev)
			return -EIO;
		if (!access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct pcidev_io_struct)))
			return -EFAULT;
		io = (struct pcidev_io_struct *)arg;
		__get_user(address, &io->address);
		__get_user(value, &io->value);
		__put_user(-1, &io->value);
		printk(KERN_INFO "pcidev: probing config space address: %#x\n", (int)address);
		ret = pci_read_config_dword(pcidev->dev, address, (u32 *)&orig_value);
		if (ret < 0)
			break;
		pci_write_config_dword(pcidev->dev, address, (u32)value);
		pci_read_config_dword(pcidev->dev, address, (u32 *)&value);
		ret = pci_write_config_dword(pcidev->dev, address, (u32)orig_value);
		if (ret < 0)
			break;
		__put_user(value, &io->value);
		break;
	}
	default:
		ret = -ENOTTY;
	}
	return ret;
}
示例#24
0
文件: r8169.c 项目: HobbesOSR/kitten
static err_t r8169_hw_init( struct netif * const netif ) {
	r8169_device_t *dev = netif->state;
	uint64_t paddr;

	if( r8169_debug ) {
		printk("Initializing r8169 hardware\n");
	}

	// Figure out where the r8169 registers are mapped into (physical) memory
	pcicfg_bar_decode(&dev->pci_dev->cfg, 0, &dev->mem_bar);
	dev->mmio_paddr = dev->mem_bar.address;
	dev->mmio_vaddr = (vaddr_t) __va(dev->mmio_paddr);

	if( r8169_debug ) {
		printk("R8169 mmio_paddr:   0x%lx\n", dev->mmio_paddr);
		printk("R8169 mmio_vaddr:   0x%lx\n", dev->mmio_vaddr);
	}

	// Figure out where the r8169 I/O ports are located
	pcicfg_bar_decode(&dev->pci_dev->cfg, 4, &dev->io_bar);
	dev->io_base   = dev->io_bar.address;

	dev->cur_tx = 0;
	dev->cur_rx = 0;

	outw(0x0000, IOADDR(dev, R8169_IMR));

	/* Reset the chip */
	outb(CmdReset, IOADDR(dev, R8169_CR));
  
	outw(0xffff, IOADDR(dev, R8169_ISR));

	/* Setup PHY */
	PHYOUT(MII_CTRL_ANE | MII_CTRL_DM | MII_CTRL_SP_1000, MII_CTRL);
	PHYOUT(MII_1000C_FULL | MII_1000C_HALF, MII_1000_CTRL);

	/* Unlock Config[01234] and BMCR register writes */
	outb(R9346CR_EEM_CONFIG, IOADDR(dev, R8169_9346CR));
  
	outw(CPLUS_MULRW, IOADDR(dev, R8169_CPLUSCR));
	outb(0x00, IOADDR(dev, R8169_INTRMIT));

	/* Enable Tx/Rx before setting transfer thresholds */
	outb(CmdRxEnb | CmdTxEnb, IOADDR(dev, R8169_CR));
 
	/* Allocate Rx Buffers */
	for( unsigned int i = 0; i < RX_RING_SIZE; i++ ) {
		paddr = __pa(dev->rx_buf + (i * RX_BUF_SIZE));
		dev->rx_ring[i].addr_lo = paddr & 0xfffffffful;
		dev->rx_ring[i].addr_hi = paddr >> 32;
		dev->rx_ring[i].opts1 = (1 << 31) | ((i==RX_RING_SIZE-1) ? (1 << 30) : 0) | RX_BUF_SIZE; 
		dev->rx_ring[i].opts2 = 0; 
	}

	/* Initialize Rx */
	outw(RX_BUF_SIZE, IOADDR(dev, R8169_RMS));
	outl(RCR_RXFTH_UNLIM | RCR_MXDMA_1024, IOADDR(dev, R8169_RCR));
	paddr = __pa(dev->rx_ring);
	outl(paddr & 0xfffffffful, IOADDR(dev, R8169_RDSAR_LO));
	outl(paddr >> 32, IOADDR(dev, R8169_RDSAR_HI));

	/* Allocate Tx Buffers */
	for( unsigned int i = 0; i < TX_RING_SIZE; i++ ) {
		paddr = __pa(dev->tx_buf + (i * TX_BUF_SIZE));
		dev->tx_ring[i].addr_lo = paddr & 0xfffffffful;
		dev->tx_ring[i].addr_hi = paddr >> 32;
		dev->tx_ring[i].opts1 = ((i==TX_RING_SIZE-1) ? (1 << 30) : 0); 
		dev->tx_ring[i].opts2 = 0; 
	}

	/* Initialize Tx */
	outw((TX_BUF_SIZE>>7)+1, IOADDR(dev, R8169_MTPS));
	outl(TCR_MXDMA_2048 | TCR_IFG_STD, IOADDR(dev, R8169_TCR));
	paddr = __pa(dev->tx_ring);
	outl(paddr & 0xfffffffful, IOADDR(dev, R8169_TNPDS_LO));
	outl(paddr >> 32, IOADDR(dev, R8169_TNPDS_HI));

	/* Allocate Tx Buffers */
	for( unsigned int i = 0; i < TX_RING_SIZE; i++ ) {
		paddr = __pa(dev->tx_hi_buf + (i * TX_BUF_SIZE));
		dev->tx_hi_ring[i].addr_lo = paddr & 0xfffffffful;
		dev->tx_hi_ring[i].addr_hi = paddr >> 32;
		dev->tx_hi_ring[i].opts1 = ((i==TX_RING_SIZE-1) ? (1 << 30) : 0); 
		dev->tx_hi_ring[i].opts2 = 0; 
	}

	/* Initialize Tx */
	outw((TX_BUF_SIZE>>7)+1, IOADDR(dev, R8169_MTPS));
	outl(TCR_MXDMA_2048 | TCR_IFG_STD, IOADDR(dev, R8169_TCR));
	paddr = __pa(dev->tx_hi_ring);
	outl(paddr & 0xfffffffful, IOADDR(dev, R8169_THPDS_LO));
	outl(paddr >> 32, IOADDR(dev, R8169_THPDS_HI));

	/* Lock Config[01234] and BMCR register writes */
	outb(R9346CR_EEM_CONFIG, IOADDR(dev, R8169_9346CR));
 
	/* missed packet counter */
	outl(0, IOADDR(dev, R8169_TCTR));
  
	// r8169_set_rx_mode does some stuff here.
	outl(inl(IOADDR(dev, R8169_RCR)) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys, 
	     IOADDR(dev, R8169_RCR));
  
	// Set Multicast address to all 1's
	for( unsigned int i = 0; i < 8; i++ ) {
		outb(0xff, IOADDR(dev, R8169_MAR7) + i);
	}
  
	/* Read in the MAC address */
	dev->mac_addr[0] = inb(IOADDR(dev, R8169_IDR0));
	dev->mac_addr[1] = inb(IOADDR(dev, R8169_IDR1));
	dev->mac_addr[2] = inb(IOADDR(dev, R8169_IDR2));
	dev->mac_addr[3] = inb(IOADDR(dev, R8169_IDR3));
	dev->mac_addr[4] = inb(IOADDR(dev, R8169_IDR4));
	dev->mac_addr[5] = inb(IOADDR(dev, R8169_IDR5));
  
	if( r8169_debug ) {
		printk("R8169 MAC Addr (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x)\n", 
		       dev->mac_addr[0],
		       dev->mac_addr[1],
		       dev->mac_addr[2],
		       dev->mac_addr[3],
		       dev->mac_addr[4],
		       dev->mac_addr[5]);
	}

	/* no early-rx interrupts */
	outw(inw(IOADDR(dev, R8169_MULINT)) & 0xf000, IOADDR(dev, R8169_MULINT));

	/* make sure RxTx has started */
	if( !(inb(IOADDR(dev, R8169_CR)) & CmdRxEnb) || !(inb(IOADDR(dev, R8169_CR)) & CmdTxEnb) )
		outb(CmdRxEnb | CmdTxEnb, IOADDR(dev, R8169_CR));
	
	irq_request(R8169_IDTVEC, &r8169_interrupt, 0, "r8169", NULL);

	/* Enable all known interrupts by setting the interrupt mask. */
	outw(r8169_intr_mask, IOADDR(dev, R8169_IMR));

	netif->mtu		= R8169_MTU;
	netif->flags		= 0
		| NETIF_FLAG_LINK_UP
		| NETIF_FLAG_UP
		| NETIF_FLAG_ETHARP
		;

	netif->hwaddr_len	= 6;
	netif->hwaddr[0]	= dev->mac_addr[0];
	netif->hwaddr[1]	= dev->mac_addr[1];
	netif->hwaddr[2]	= dev->mac_addr[2];
	netif->hwaddr[3]	= dev->mac_addr[3];
	netif->hwaddr[4]	= dev->mac_addr[4];
	netif->hwaddr[5]	= dev->mac_addr[5];
  
	netif->name[0]		= 'e';
	netif->name[1]		= 'n';
  
	netif->linkoutput     = r8169_tx;

	netif->output		= etharp_output;
  
	if( r8169_debug ) {
		printk("r8169 initialized\n");
	}

	return ERR_OK;
}
示例#25
0
int mainboard_io_trap_handler(int smif)
{
	u8 reg8;
	u32 reg32;

	switch (smif) {
	case 0x2b:
		printk(BIOS_DEBUG, "CPU power state switch\n");
		// TODO, move to CPU handler?
		break;
	case 0x3d:
		printk(BIOS_DEBUG, "Enable C-State SMM coordination\n");
		// TODO, move to CPU handler?
		break;
	case 0x46:
		printk(BIOS_DEBUG, "S3 DTS SMI (completely re-enable DTS)\n");
		// TODO, move to CPU handler?
		break;
	case 0x47:
		printk(BIOS_DEBUG, "S4 DTS SMI (Update NVS DTS temperature)\n");
		// TODO, move to CPU handler?
		break;
	case 0xc0:
		printk(BIOS_DEBUG, "Disable RF\n");
		// TODO
		break;
	case 0xd0:
		printk(BIOS_DEBUG, "ACBS LAN Power on\n");
		// TODO
		break;
	case 0xd1:
		printk(BIOS_DEBUG, "ACBS LAN Power off\n");
		// TODO
		break;
	case 0xd2:
		printk(BIOS_DEBUG, "Check AC status\n");
		// TODO
		break;
	case 0xd3:
		printk(BIOS_DEBUG, "Enable Bluetooth\n");
		// TODO
		break;
	case 0xd4:
		printk(BIOS_DEBUG, "Disable Bluetooth\n");
		// TODO
		break;
	case 0xd5:
		printk(BIOS_DEBUG, "Set Brightness\n");
		reg8 = gnvs->brtl;
		printk(BIOS_DEBUG, "brtl: %x\n", reg8);
		ec_write(0x17, reg8);
		break;
	case 0xd6:
		printk(BIOS_DEBUG, "Get Brightness\n");
		reg8 = ec_read(0x17);
		printk(BIOS_DEBUG, "brtl: %x\n", reg8);
		gnvs->brtl = reg8;
		break;
	case 0xd7:
		printk(BIOS_DEBUG, "Get ECO mode status\n");
		// TODO
		break;
	case 0xd8:
		printk(BIOS_DEBUG, "Get sunlight readable status\n");
		// TODO
		break;
	case 0xd9:
		printk(BIOS_DEBUG, "Get docking connection\n");
		// TODO
		break;
	case 0xda:
		printk(BIOS_DEBUG, "Power off docking\n");
		// TODO
		break;
	case 0xdc:
		printk(BIOS_DEBUG, "EC: Turn on LED on ECO enable\n");
		// TODO
		break;
	case 0xdd:
		printk(BIOS_DEBUG, "EC: Turn off LED on ECO disable\n");
		// TODO
		break;
	case 0xde:
		printk(BIOS_DEBUG, "LAN power off\n");
		reg32 = inl(DEFAULT_GPIOBASE + GP_LVL);
		reg32 |= (1 << 24);			// Disable LAN Power
		outl(reg32, DEFAULT_GPIOBASE + GP_LVL);
		break;
	case 0xdf:
		printk(BIOS_DEBUG, "RF enable\n");
		// TODO
		break;
	case 0xe0:
		printk(BIOS_DEBUG, "Get RTC wake flag\n");
		// TODO
		break;
	case 0xe1:
		printk(BIOS_DEBUG, "Hotkey function\n");
		// TODO
		break;
	case 0xe3:
		printk(BIOS_DEBUG, "ECO disable\n");
		// TODO
		break;
	default:
		return 0;
	}

	/* gnvs->smif:
	 *   On success, the IO Trap Handler returns 0
	 *   On failure, the IO Trap Handler returns a value != 0
	 */
	gnvs->smif = 0;
	return 1;
}
示例#26
0
HPT_U32  os_inl  (void *port) { return inl((unsigned)(HPT_UPTR)port); }
static inline u32 read_pmtmr(void)
{
	/* mask the output to 24 bits */
	return inl(pmtmr_ioport) & ACPI_PM_MASK;
}
示例#28
0
static long archread(struct chan *c, void *a, long n, int64_t offset)
{
	char *buf, *p;
	int port;
	uint16_t *sp;
	uint32_t *lp;
	IOMap *map;
	Rdwrfn *fn;

	switch ((uint32_t) c->qid.path) {

		case Qdir:
			return devdirread(c, a, n, archdir, narchdir, devgen);

		case Qgdb:
			p = gdbactive ? "1" : "0";
			return readstr(offset, a, n, p);
		case Qiob:
			port = offset;
			checkport(offset, offset + n);
			for (p = a; port < offset + n; port++)
				*p++ = inb(port);
			return n;

		case Qiow:
			if (n & 1)
				error(EINVAL, NULL);
			checkport(offset, offset + n);
			sp = a;
			for (port = offset; port < offset + n; port += 2)
				*sp++ = inw(port);
			return n;

		case Qiol:
			if (n & 3)
				error(EINVAL, NULL);
			checkport(offset, offset + n);
			lp = a;
			for (port = offset; port < offset + n; port += 4)
				*lp++ = inl(port);
			return n;

		case Qioalloc:
			break;

		case Qrealmem:
			printk("readmem %p %p %p %p %p\n",offset, a, n, KADDR(0), 1048576);
			return readmem(offset, a, n, KADDR(0), 1048576);
			break;

		default:
			if (c->qid.path < narchdir && (fn = readfn[c->qid.path]))
				return fn(c, a, n, offset);
			error(EPERM, NULL);
			break;
	}

	if ((buf = kzmalloc(n, 0)) == NULL)
		error(ENOMEM, NULL);
	p = buf;
	n = n / Linelen;
	offset = offset / Linelen;

	switch ((uint32_t) c->qid.path) {
		case Qioalloc:
			spin_lock(&(&iomap)->lock);
			for (map = iomap.map; n > 0 && map != NULL; map = map->next) {
				if (offset-- > 0)
					continue;
				snprintf(p, n * Linelen, "%#8p %#8p %-12.12s\n", map->start,
						 map->end - 1, map->tag);
				p += Linelen;
				n--;
			}
			spin_unlock(&(&iomap)->lock);
			break;
		case Qmapram:
			error(ENOSYS, NULL);
			break;
	}

	n = p - buf;
	memmove(a, buf, n);
	kfree(buf);

	return n;
}
示例#29
0
int main (int argc, char *argv[])
{
	struct pci_access *pacc;
	struct pci_dev *dev;
	struct pci_filter filter;
	char *msg;
	uint16_t command;
	int v1_1 = 0, i2c;

	if (argc != 2 &&
	    ((argc != 3) ||
	     (!(v1_1 = !strcmp(argv[2], "1.1")) && strcmp(argv[2], "1.0")))) {
		fprintf(stderr,
			"VT6307 OHCI mode config\n"
			"Version 0.9\n"
			"Copyright (C) 2007 Krzysztof Halasa <*****@*****.**>\n"
			"\n"
			"Usage: vt6307ohciver <pci_device> [ 1.0 | 1.1 ]\n");
		exit(1);
	}

	if (iopl(3)) {
		fprintf(stderr, "iopl() failed (must be root)\n");
		exit(1);
	}

	pacc = pci_alloc();
	pci_filter_init(pacc, &filter);
	if ((msg = pci_filter_parse_slot(&filter, argv[1]))) {
		fprintf(stderr, "Invalid pci_device\n");
		exit(1);
	}

	filter.vendor = VENDOR_ID;
	filter.device = DEVICE_ID;

	pci_init(pacc);
	pci_scan_bus(pacc);

	for (dev = pacc->devices; dev; dev = dev->next)
		if (pci_filter_match(&filter, dev))
			break;

	if (!dev) {
		fprintf(stderr, "Device %s not found\n", argv[2]);
		exit(1);
	}

	pci_fill_info(dev, PCI_FILL_BASES | PCI_FILL_SIZES);

	if (dev->size[0] != MEM_SIZE || dev->size[1] != IO_SIZE) {
		fprintf(stderr, "Unexpected MEM/IO region size, is it"
			" VT6307 chip?\n");
		exit(1);
	}

	command = pci_read_word(dev, PCI_COMMAND);

	if ((command & PCI_COMMAND_IO) == 0) {
		fprintf(stderr, "Device disabled, trying to enable it\n");
		pci_write_word(dev, PCI_COMMAND, command | PCI_COMMAND_IO);
	}

	io_ports = dev->base_addr[1] & PCI_BASE_ADDRESS_IO_MASK;

	i2c = (inl(io_ports + 0x20) & 0x80) ? 0 : 1;

	fprintf(stderr, "I/O region #1 is at %04X\n", io_ports);
	fprintf(stderr, "It seems your VT6307 chip is connected to %s "
		"EEPROM\n", i2c ? "I^2C (24c01 or similar)" : "93c46");

	if (argc == 3) {
		/* enable direct access to pins */
		outl_p(inl(io_ports) | 0x80, io_ports);
		if (i2c)
			write_i2c(0x22, v1_1 ? 8 : 0);
		else
			write_4w(0x11, v1_1 ? 8 : 0);
		/* disable direct access to pins */
		outl_p(0x20, io_ports + 0x20);
		fprintf(stderr, "Please reboot\n");
	} else
		display(dev->base_addr[0] & PCI_BASE_ADDRESS_MEM_MASK);

	if ((command & PCI_COMMAND_IO) == 0) {
		fprintf(stderr, "Disabling device\n");
		pci_write_word(dev, PCI_COMMAND, command);
	}

	exit(0);
}
示例#30
0
static void  unmask_irq(unsigned int irq)
{
    outl((inl(GIMR0) | (1 << irq)),GIMR0);
    inl(GIMR0);
}