static inline int superio_inb(int reg)
{
	outb(reg, REG);
	return inb(VAL);
}
示例#2
0
static void
el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
{
    int boguscount = 0;
    unsigned short int *buf;
    unsigned short word;

    int end_of_ring = dev->rmem_end;

    /* Maybe enable shared memory just be to be safe... nahh.*/
    if (dev->mem_start) {	/* Use the shared memory. */
        ring_offset -= (EL2_MB1_START_PG<<8);
        if (dev->mem_start + ring_offset + count > end_of_ring) {
            /* We must wrap the input move. */
            int semi_count = end_of_ring - (dev->mem_start + ring_offset);
            memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count);
            count -= semi_count;
            memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
        } else {
            /* Packet is in one chunk -- we can copy + cksum. */
            eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0);
        }
        return;
    }

    /*
     *  No shared memory, use programmed I/O.
     */
    word = (unsigned short) ring_offset;
    outb(word>>8, E33G_DMAAH);
    outb(word&0xFF, E33G_DMAAL);

    outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
           | ECNTRL_START, E33G_CNTRL);

    /*
     *  Here I also try to get data as fast as possible. I am betting that I
     *  can read one extra byte without clobbering anything in the kernel because
     *  this would only occur on an odd byte-count and allocation of skb->data
     *  is word-aligned. Variable 'count' is NOT checked. Caller must check
     *  for a valid count.
     *  [This is currently quite safe.... but if one day the 3c503 explodes
     *   you know where to come looking ;)]
     */

    buf =  (unsigned short int *) skb->data;
    count =  (count + 1) >> 1;
    for(;;)
    {
        boguscount = 0x1000;
        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
        {
            if(!boguscount--)
            {
                printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
                el2_reset_8390(dev);
                goto blocked;
            }
        }
        if(count > WRD_COUNT)
        {
            insw(E33G_FIFOH, buf, WRD_COUNT);
            buf   += WRD_COUNT;
            count -= WRD_COUNT;
        }
        else
        {
            insw(E33G_FIFOH, buf, count);
            break;
        }
    }
blocked:
    ;
    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
    return;
}
static int snd_es1688_probe(es1688_t *chip)
{
	unsigned long flags;
	unsigned short major, minor, hw;
	int i;

	/*
	 *  initialization sequence
	 */

	spin_lock_irqsave(&chip->reg_lock, flags);	/* Some ESS1688 cards need this */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
	inb(ES1688P(chip, ENABLE0));	/* ENABLE0 */

	if (snd_es1688_reset(chip) < 0) {
		snd_printdd("ESS: [0x%lx] reset failed... 0x%x\n", chip->port, inb(ES1688P(chip, READ)));
		spin_unlock_irqrestore(&chip->reg_lock, flags);
		return -ENODEV;
	}
	snd_es1688_dsp_command(chip, 0xe7);	/* return identification */

	for (i = 1000, major = minor = 0; i; i--) {
		if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) {
			if (major == 0) {
				major = inb(ES1688P(chip, READ));
			} else {
				minor = inb(ES1688P(chip, READ));
			}
		}
	}

	spin_unlock_irqrestore(&chip->reg_lock, flags);

	snd_printdd("ESS: [0x%lx] found.. major = 0x%x, minor = 0x%x\n", chip->port, major, minor);

	chip->version = (major << 8) | minor;
	if (!chip->version)
		return -ENODEV;	/* probably SB */

	hw = ES1688_HW_AUTO;
	switch (chip->version & 0xfff0) {
	case 0x4880:
		snd_printk("[0x%lx] ESS: AudioDrive ES488 detected, but driver is in another place\n", chip->port);
		return -ENODEV;
	case 0x6880:
		hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688;
		break;
	default:
		snd_printk("[0x%lx] ESS: unknown AudioDrive chip with version 0x%x (Jazz16 soundcard?)\n", chip->port, chip->version);
		return -ENODEV;
	}

	spin_lock_irqsave(&chip->reg_lock, flags);
	snd_es1688_write(chip, 0xb1, 0x10);	/* disable IRQ */
	snd_es1688_write(chip, 0xb2, 0x00);	/* disable DMA */
	spin_unlock_irqrestore(&chip->reg_lock, flags);

	/* enable joystick, but disable OPL3 */
	spin_lock_irqsave(&chip->mixer_lock, flags);
	snd_es1688_mixer_write(chip, 0x40, 0x01);
	spin_unlock_irqrestore(&chip->mixer_lock, flags);

	return 0;
}
示例#4
0
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
	u32 val;

	/* In Hudson RRG, PMIOxD2[5:4] is "Drive strength control for
	 *  LpcClk[1:0]".  To be consistent with Parmer, setting to 4mA
	 *  even though the register is not documented in the Kabini BKDG.
	 *  Otherwise the serial output is bad code.
	 */
	outb(0xD2, 0xcd6);
	outb(0x00, 0xcd7);

	val = agesawrapper_amdinitmmio();

	hudson_lpc_port80();

	if (!cpu_init_detectedx && boot_cpu()) {
		post_code(0x30);

		post_code(0x31);
		console_init();
	}

	/* Halt if there was a built in self test failure */
	post_code(0x34);
	report_bist_failure(bist);

	/* Load MPB */
	val = cpuid_eax(1);
	printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val);
	printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx);

	/* On Larne, after LpcClkDrvSth is set, it needs some time to be stable, because of the buffer ICS551M */
	int i;
	for(i = 0; i < 200000; i++)
		val = inb(0xcd6);

	post_code(0x37);
	val = agesawrapper_amdinitreset();
	if(val) {
		printk(BIOS_DEBUG, "agesawrapper_amdinitreset failed: %x \n", val);
	}

	post_code(0x38);
	printk(BIOS_DEBUG, "Got past yangtze_early_setup\n");

	post_code(0x39);

	val = agesawrapper_amdinitearly ();
	if(val) {
		printk(BIOS_DEBUG, "agesawrapper_amdinitearly failed: %x \n", val);
	}
	printk(BIOS_DEBUG, "Got past agesawrapper_amdinitearly\n");

	int s3resume = acpi_is_wakeup_early() && acpi_s3_resume_allowed();
	if (!s3resume) {
		post_code(0x40);
		val = agesawrapper_amdinitpost ();
		if(val) {
			printk(BIOS_DEBUG, "agesawrapper_amdinitpost failed: %x \n", val);
		}
		printk(BIOS_DEBUG, "Got past agesawrapper_amdinitpost\n");

		post_code(0x41);
		val = agesawrapper_amdinitenv ();
		if(val) {
			printk(BIOS_DEBUG, "agesawrapper_amdinitenv failed: %x \n", val);
		}
		printk(BIOS_DEBUG, "Got past agesawrapper_amdinitenv\n");
		/* TODO: Disable cache is not ok. */
		disable_cache_as_ram();
	} else { /* S3 detect */
		printk(BIOS_INFO, "S3 detected\n");

		post_code(0x60);
		printk(BIOS_DEBUG, "agesawrapper_amdinitresume ");
		val = agesawrapper_amdinitresume();
		if (val)
			printk(BIOS_DEBUG, "error level: %x \n", val);
		else
			printk(BIOS_DEBUG, "passed.\n");

		printk(BIOS_DEBUG, "agesawrapper_amds3laterestore ");
		val = agesawrapper_amds3laterestore ();
		if (val)
			printk(BIOS_DEBUG, "error level: %x \n", val);
		else
			printk(BIOS_DEBUG, "passed.\n");

		post_code(0x61);
		prepare_for_resume();
	}

	outb(0xEA, 0xCD6);
	outb(0x1, 0xcd7);

	post_code(0x50);
	copy_and_run();

	post_code(0x54);  /* Should never see this post code. */
}
示例#5
0
/* Probe for the Etherlink II card at I/O port base IOADDR,
   returning non-zero on success.  If found, set the station
   address and memory parameters in DEVICE. */
__initfunc(int
           el2_probe1(struct device *dev, int ioaddr))
{
    int i, iobase_reg, membase_reg, saved_406, wordlength;
    static unsigned version_printed = 0;
    unsigned long vendor_id;

    /* Reset and/or avoid any lurking NE2000 */
    if (inb(ioaddr + 0x408) == 0xff) {
        mdelay(1);
        return ENODEV;
    }

    /* We verify that it's a 3C503 board by checking the first three octets
       of its ethernet address. */
    iobase_reg = inb(ioaddr+0x403);
    membase_reg = inb(ioaddr+0x404);
    /* ASIC location registers should be 0 or have only a single bit set. */
    if (   (iobase_reg  & (iobase_reg - 1))
            || (membase_reg & (membase_reg - 1))) {
        return ENODEV;
    }
    saved_406 = inb_p(ioaddr + 0x406);
    outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
    outb_p(ECNTRL_THIN, ioaddr + 0x406);
    /* Map the station addr PROM into the lower I/O ports. We now check
       for both the old and new 3Com prefix */
    outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
    vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
    if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
        /* Restore the register we frobbed. */
        outb(saved_406, ioaddr + 0x406);
        return ENODEV;
    }

    if (load_8390_module("3c503.c"))
        return -ENOSYS;

    /* We should have a "dev" from Space.c or the static module table. */
    if (dev == NULL) {
        printk("3c503.c: Passed a NULL device.\n");
        dev = init_etherdev(0, 0);
    }

    if (ei_debug  &&  version_printed++ == 0)
        printk(version);

    dev->base_addr = ioaddr;
    /* Allocate dev->priv and fill in 8390 specific dev fields. */
    if (ethdev_init(dev)) {
        printk ("3c503: unable to allocate memory for dev->priv.\n");
        return -ENOMEM;
    }

    printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);

    /* Retrieve and print the ethernet address. */
    for (i = 0; i < 6; i++)
        printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));

    /* Map the 8390 back into the window. */
    outb(ECNTRL_THIN, ioaddr + 0x406);

    /* Check for EL2/16 as described in tech. man. */
    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
    outb_p(0, ioaddr + EN0_DCFG);
    outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
    wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);

    /* Probe for, turn on and clear the board's shared memory. */
    if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
    outb(EGACFR_NORM, ioaddr + 0x405);	/* Enable RAM */

    /* This should be probed for (or set via an ioctl()) at run-time.
       Right now we use a sleazy hack to pass in the interface number
       at boot-time via the low bits of the mem_end field.  That value is
       unused, and the low bits would be discarded even if it was used. */
#if defined(EI8390_THICK) || defined(EL2_AUI)
    ei_status.interface_num = 1;
#else
    ei_status.interface_num = dev->mem_end & 0xf;
#endif
    printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");

    if ((membase_reg & 0xf0) == 0) {
        dev->mem_start = 0;
        ei_status.name = "3c503-PIO";
    } else {
        dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
                         ((membase_reg & 0xA0) ? 0x4000 : 0);

#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
#ifdef EL2MEMTEST
        /* This has never found an error, but someone might care.
           Note that it only tests the 2nd 8kB on 16kB 3c503/16
           cards between card addr. 0x2000 and 0x3fff. */
        {   /* Check the card's memory. */
            unsigned long mem_base = dev->mem_start;
            unsigned int test_val = 0xbbadf00d;
            writel(0xba5eba5e, mem_base);
            for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
                writel(test_val, mem_base + i);
                if (readl(mem_base) != 0xba5eba5e
                        || readl(mem_base + i) != test_val) {
                    printk("3c503: memory failure or memory address conflict.\n");
                    dev->mem_start = 0;
                    ei_status.name = "3c503-PIO";
                    break;
                }
                test_val += 0x55555555;
                writel(0, mem_base + i);
            }
        }
#endif  /* EL2MEMTEST */

        dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;

        if (wordlength) {	/* No Tx pages to skip over to get to Rx */
            dev->rmem_start = dev->mem_start;
            ei_status.name = "3c503/16";
        } else {
            dev->rmem_start = TX_PAGES*256 + dev->mem_start;
            ei_status.name = "3c503";
        }
    }

    /*
    Divide up the memory on the card. This is the same regardless of
    whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
    we use the entire 8k of bank1 for an Rx ring. We only use 3k
    of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
    (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
    5kB for an Rx ring.  */

    if (wordlength) {
        ei_status.tx_start_page = EL2_MB0_START_PG;
        ei_status.rx_start_page = EL2_MB1_START_PG;
    } else {
        ei_status.tx_start_page = EL2_MB1_START_PG;
        ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
    }

    /* Finish setting the board's parameters. */
    ei_status.stop_page = EL2_MB1_STOP_PG;
    ei_status.word16 = wordlength;
    ei_status.reset_8390 = &el2_reset_8390;
    ei_status.get_8390_hdr = &el2_get_8390_hdr;
    ei_status.block_input = &el2_block_input;
    ei_status.block_output = &el2_block_output;

    request_region(ioaddr, EL2_IO_EXTENT, ei_status.name);

    if (dev->irq == 2)
        dev->irq = 9;
    else if (dev->irq > 5 && dev->irq != 9) {
        printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
               dev->irq);
        dev->irq = 0;
    }

    ei_status.saved_irq = dev->irq;

    dev->start = 0;
    dev->open = &el2_open;
    dev->stop = &el2_close;

    if (dev->mem_start)
        printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
               dev->name, ei_status.name, (wordlength+1)<<3,
               dev->mem_start, dev->mem_end-1);

    else
    {
        ei_status.tx_start_page = EL2_MB1_START_PG;
        ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
        printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
               dev->name, ei_status.name, (wordlength+1)<<3);
    }
    return 0;
}
示例#6
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);
}
示例#7
0
/** serial_is_transmit_fifo_empty:
*  Checks whether the transmit FIFO queue is empty or not for the given COM
*  port.
*
*  @param  com The COM port
*  @return 0 if the transmit FIFO queue is not empty
*          1 if the transmit FIFO queue is empty
*/
int serial_is_transmit_fifo_empty(unsigned int com)
{
	/* 0x20 = 0010 0000 */
	return inb(SERIAL_LINE_STATUS_PORT(com)) & 0x20;
}
示例#8
0
static void wbsd_fill_fifo(struct wbsd_host *host)
{
    struct mmc_data *data = host->mrq->cmd->data;
    char *buffer;
    int i, fsr, fifo;

    /*
     * Check that we aren't being called after the
     * entire buffer has been transfered.
     */
    if (host->num_sg == 0)
        return;

    buffer = wbsd_sg_to_buffer(host) + host->offset;

    /*
     * Fill the fifo. This has a tendency to loop longer
     * than the FIFO length (usually one block).
     */
    while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) {
        /*
         * The size field in the FSR is broken so we have to
         * do some guessing.
         */
        if (fsr & WBSD_FIFO_EMPTY)
            fifo = 0;
        else if (fsr & WBSD_FIFO_EMTHRE)
            fifo = 8;
        else
            fifo = 15;

        for (i = 16; i > fifo; i--) {
            outb(*buffer, host->base + WBSD_DFR);
            buffer++;
            host->offset++;
            host->remain--;

            data->bytes_xfered++;

            /*
             * End of scatter list entry?
             */
            if (host->remain == 0) {
                /*
                 * Get next entry. Check if last.
                 */
                if (!wbsd_next_sg(host))
                    return;

                buffer = wbsd_sg_to_buffer(host);
            }
        }
    }

    /*
     * The controller stops sending interrupts for
     * 'FIFO empty' under certain conditions. So we
     * need to be a bit more pro-active.
     */
    tasklet_schedule(&host->fifo_tasklet);
}
示例#9
0
/* hardware access */
HPT_U8   os_inb  (void *port) { return inb((unsigned)(HPT_UPTR)port); }
示例#10
0
static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index)
{
    outb(index, host->base + WBSD_IDXR);
    return inb(host->base + WBSD_DATAR);
}
示例#11
0
static void wbsd_empty_fifo(struct wbsd_host *host)
{
    struct mmc_data *data = host->mrq->cmd->data;
    char *buffer;
    int i, fsr, fifo;

    /*
     * Handle excessive data.
     */
    if (host->num_sg == 0)
        return;

    buffer = wbsd_sg_to_buffer(host) + host->offset;

    /*
     * Drain the fifo. This has a tendency to loop longer
     * than the FIFO length (usually one block).
     */
    while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) {
        /*
         * The size field in the FSR is broken so we have to
         * do some guessing.
         */
        if (fsr & WBSD_FIFO_FULL)
            fifo = 16;
        else if (fsr & WBSD_FIFO_FUTHRE)
            fifo = 8;
        else
            fifo = 1;

        for (i = 0; i < fifo; i++) {
            *buffer = inb(host->base + WBSD_DFR);
            buffer++;
            host->offset++;
            host->remain--;

            data->bytes_xfered++;

            /*
             * End of scatter list entry?
             */
            if (host->remain == 0) {
                /*
                 * Get next entry. Check if last.
                 */
                if (!wbsd_next_sg(host))
                    return;

                buffer = wbsd_sg_to_buffer(host);
            }
        }
    }

    /*
     * This is a very dirty hack to solve a
     * hardware problem. The chip doesn't trigger
     * FIFO threshold interrupts properly.
     */
    if ((data->blocks * data->blksz - data->bytes_xfered) < 16)
        tasklet_schedule(&host->fifo_tasklet);
}
示例#12
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;
}
示例#13
0
void flushreadfifo (int card)
{
	while(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
		inb(sc_adapter[card]->ioport[FIFO_READ]);
}
示例#14
0
/* Read from Data Register */
static inline void __sc1200wdt_read_data(unsigned char index,
						unsigned char *data)
{
	outb_p(index, PMIR);
	*data = inb(PMDR);
}
示例#15
0
static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
{
    dtl1_info_t *info = dev_inst;
    unsigned int iobase;
    unsigned char msr;
    int boguscount = 0;
    int iir, lsr;
    irqreturn_t r = IRQ_NONE;

    if (!info || !info->hdev)
        /* our irq handler is shared */
        return IRQ_NONE;

    iobase = info->p_dev->resource[0]->start;

    spin_lock(&(info->lock));

    iir = inb(iobase + UART_IIR) & UART_IIR_ID;
    while (iir) {

        r = IRQ_HANDLED;
        /* Clear interrupt */
        lsr = inb(iobase + UART_LSR);

        switch (iir) {
        case UART_IIR_RLSI:
            BT_ERR("RLSI");
            break;
        case UART_IIR_RDI:
            /* Receive interrupt */
            dtl1_receive(info);
            break;
        case UART_IIR_THRI:
            if (lsr & UART_LSR_THRE) {
                /* Transmitter ready for data */
                dtl1_write_wakeup(info);
            }
            break;
        default:
            BT_ERR("Unhandled IIR=%#x", iir);
            break;
        }

        /* Make sure we don't stay here too long */
        if (boguscount++ > 100)
            break;

        iir = inb(iobase + UART_IIR) & UART_IIR_ID;

    }

    msr = inb(iobase + UART_MSR);

    if (info->ri_latch ^ (msr & UART_MSR_RI)) {
        info->ri_latch = msr & UART_MSR_RI;
        clear_bit(XMIT_WAITING, &(info->tx_state));
        dtl1_write_wakeup(info);
        r = IRQ_HANDLED;
    }

    spin_unlock(&(info->lock));

    return r;
}
示例#16
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;
}
示例#17
0
static int dtl1_open(dtl1_info_t *info)
{
    unsigned long flags;
    unsigned int iobase = info->p_dev->resource[0]->start;
    struct hci_dev *hdev;

    spin_lock_init(&(info->lock));

    skb_queue_head_init(&(info->txq));

    info->rx_state = RECV_WAIT_NSH;
    info->rx_count = NSHL;
    info->rx_skb = NULL;

    set_bit(XMIT_WAITING, &(info->tx_state));

    /* Initialize HCI device */
    hdev = hci_alloc_dev();
    if (!hdev) {
        BT_ERR("Can't allocate HCI device");
        return -ENOMEM;
    }

    info->hdev = hdev;

    hdev->bus = HCI_PCCARD;
    hdev->driver_data = info;
    SET_HCIDEV_DEV(hdev, &info->p_dev->dev);

    hdev->open     = dtl1_hci_open;
    hdev->close    = dtl1_hci_close;
    hdev->flush    = dtl1_hci_flush;
    hdev->send     = dtl1_hci_send_frame;
    hdev->destruct = dtl1_hci_destruct;
    hdev->ioctl    = dtl1_hci_ioctl;

    hdev->owner = THIS_MODULE;

    spin_lock_irqsave(&(info->lock), flags);

    /* Reset UART */
    outb(0, iobase + UART_MCR);

    /* Turn off interrupts */
    outb(0, iobase + UART_IER);

    /* Initialize UART */
    outb(UART_LCR_WLEN8, iobase + UART_LCR);	/* Reset DLAB */
    outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);

    info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
                     & UART_MSR_RI;

    /* Turn on interrupts */
    outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);

    spin_unlock_irqrestore(&(info->lock), flags);

    /* Timeout before it is safe to send the first HCI packet */
    msleep(2000);

    /* Register HCI device */
    if (hci_register_dev(hdev) < 0) {
        BT_ERR("Can't register HCI device");
        info->hdev = NULL;
        hci_free_dev(hdev);
        return -ENODEV;
    }

    return 0;
}
示例#18
0
static int znet_send_packet(struct sk_buff *skb, struct device *dev)
{
	int ioaddr = dev->base_addr;

	if (znet_debug > 4)
		printk(KERN_DEBUG "%s: ZNet_send_packet(%d).\n", dev->name, dev->tbusy);

	/* Transmitter timeout, likely just recovery after suspending the machine. */
	if (dev->tbusy) {
		ushort event, tx_status, rx_offset, state;
		int tickssofar = jiffies - dev->trans_start;
		if (tickssofar < 10)
			return 1;
		outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
		outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
		outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
		outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
		printk(KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
			   " resetting.\n", dev->name, event, tx_status, rx_offset, state);
		if (tx_status == 0x0400)
		  printk(KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
				 dev->name);
		outb(CMD0_RESET, ioaddr);
		hardware_init(dev);
	}

	if (skb == NULL) {
		dev_tint(dev);
		return 0;
	}

	/* Check that the part hasn't reset itself, probably from suspend. */
	outb(CMD0_STAT0, ioaddr);
	if (inw(ioaddr) == 0x0010
		&& inw(ioaddr) == 0x0000
		&& inw(ioaddr) == 0x0010)
	  hardware_init(dev);

	/* Block a timer-based transmit from overlapping.  This could better be
	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
	if (set_bit(0, (void*)&dev->tbusy) != 0)
		printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
	else {
		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
		unsigned char *buf = (void *)(skb+1);
		ushort *tx_link = zn.tx_cur - 1;
		ushort rnd_len = (length + 1)>>1;

		{
			short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
			unsigned addr = inb(dma_port);
			addr |= inb(dma_port) << 8;
			addr <<= 1;
			if (((int)zn.tx_cur & 0x1ffff) != addr)
			  printk(KERN_WARNING "Address mismatch at Tx: %#x vs %#x.\n",
					 (int)zn.tx_cur & 0xffff, addr);
			zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
		}

		if (zn.tx_cur >= zn.tx_end)
		  zn.tx_cur = zn.tx_start;
		*zn.tx_cur++ = length;
		if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
			int semi_cnt = (zn.tx_end - zn.tx_cur)<<1; /* Cvrt to byte cnt. */
			memcpy(zn.tx_cur, buf, semi_cnt);
			rnd_len -= semi_cnt>>1;
			memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
			zn.tx_cur = zn.tx_start + rnd_len;
		} else {
示例#19
0
void udelay(unsigned int usecs)
{
	load_timer2((usecs * TICKS_PER_MS) / 1000);
	while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
}
示例#20
0
/* ----------------------------------------------------------------------------
mace_rx
	Receives packets.
---------------------------------------------------------------------------- */
static int mace_rx(struct net_device *dev, unsigned char RxCnt)
{
  mace_private *lp = netdev_priv(dev);
  unsigned int ioaddr = dev->base_addr;
  unsigned char rx_framecnt;
  unsigned short rx_status;

  while (
    ((rx_framecnt = inb(ioaddr + AM2150_RCV_FRAME_COUNT)) > 0) &&
    (rx_framecnt <= 12) && /* rx_framecnt==0xFF if card is extracted. */
    (RxCnt--)
  ) {
    rx_status = inw(ioaddr + AM2150_RCV);

    pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
	  " 0x%X.\n", dev->name, rx_framecnt, rx_status);

    if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
      lp->linux_stats.rx_errors++;
      if (rx_status & MACE_RCVFS_OFLO) {
        lp->mace_stats.oflo++;
      }
      if (rx_status & MACE_RCVFS_CLSN) {
        lp->mace_stats.clsn++;
      }
      if (rx_status & MACE_RCVFS_FRAM) {
	lp->mace_stats.fram++;
      }
      if (rx_status & MACE_RCVFS_FCS) {
        lp->mace_stats.fcs++;
      }
    } else {
      short pkt_len = (rx_status & ~MACE_RCVFS_RCVSTS) - 4;
        /* Auto Strip is off, always subtract 4 */
      struct sk_buff *skb;

      lp->mace_stats.rfs_rntpc += inb(ioaddr + AM2150_RCV);
        /* runt packet count */
      lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
        /* rcv collision count */

      pr_debug("    receiving packet size 0x%X rx_status"
	    " 0x%X.\n", pkt_len, rx_status);

      skb = dev_alloc_skb(pkt_len+2);

      if (skb != NULL) {
	skb_reserve(skb, 2);
	insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1);
	if (pkt_len & 1)
	    *(skb_tail_pointer(skb) - 1) = inb(ioaddr + AM2150_RCV);
	skb->protocol = eth_type_trans(skb, dev);
	
	netif_rx(skb); /* Send the packet to the upper (protocol) layers. */

	lp->linux_stats.rx_packets++;
	lp->linux_stats.rx_bytes += pkt_len;
	outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
	continue;
      } else {
	pr_debug("%s: couldn't allocate a sk_buff of size"
	      " %d.\n", dev->name, pkt_len);
	lp->linux_stats.rx_dropped++;
      }
    }
示例#21
0
static void btuart_receive(btuart_info_t *info)
{
    unsigned int iobase;
    int boguscount = 0;

    if (!info) {
        BT_ERR("Unknown device");
        return;
    }

    iobase = info->link.io.BasePort1;

    do {
        info->hdev->stat.byte_rx++;

        /* Allocate packet */
        if (info->rx_skb == NULL) {
            info->rx_state = RECV_WAIT_PACKET_TYPE;
            info->rx_count = 0;
            if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
                BT_ERR("Can't allocate mem for new packet");
                return;
            }
        }

        if (info->rx_state == RECV_WAIT_PACKET_TYPE) {

            info->rx_skb->dev = (void *) info->hdev;
            bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);

            switch (bt_cb(info->rx_skb)->pkt_type) {

            case HCI_EVENT_PKT:
                info->rx_state = RECV_WAIT_EVENT_HEADER;
                info->rx_count = HCI_EVENT_HDR_SIZE;
                break;

            case HCI_ACLDATA_PKT:
                info->rx_state = RECV_WAIT_ACL_HEADER;
                info->rx_count = HCI_ACL_HDR_SIZE;
                break;

            case HCI_SCODATA_PKT:
                info->rx_state = RECV_WAIT_SCO_HEADER;
                info->rx_count = HCI_SCO_HDR_SIZE;
                break;

            default:
                /* Unknown packet */
                BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
                info->hdev->stat.err_rx++;
                clear_bit(HCI_RUNNING, &(info->hdev->flags));

                kfree_skb(info->rx_skb);
                info->rx_skb = NULL;
                break;

            }

        } else {

            *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
            info->rx_count--;

            if (info->rx_count == 0) {

                int dlen;
                struct hci_event_hdr *eh;
                struct hci_acl_hdr *ah;
                struct hci_sco_hdr *sh;


                switch (info->rx_state) {

                case RECV_WAIT_EVENT_HEADER:
                    eh = (struct hci_event_hdr *)(info->rx_skb->data);
                    info->rx_state = RECV_WAIT_DATA;
                    info->rx_count = eh->plen;
                    break;

                case RECV_WAIT_ACL_HEADER:
                    ah = (struct hci_acl_hdr *)(info->rx_skb->data);
                    dlen = __le16_to_cpu(ah->dlen);
                    info->rx_state = RECV_WAIT_DATA;
                    info->rx_count = dlen;
                    break;

                case RECV_WAIT_SCO_HEADER:
                    sh = (struct hci_sco_hdr *)(info->rx_skb->data);
                    info->rx_state = RECV_WAIT_DATA;
                    info->rx_count = sh->dlen;
                    break;

                case RECV_WAIT_DATA:
                    hci_recv_frame(info->rx_skb);
                    info->rx_skb = NULL;
                    break;

                }

            }

        }

        /* Make sure we don't stay here too long */
        if (boguscount++ > 16)
            break;

    } while (inb(iobase + UART_LSR) & UART_LSR_DR);
}
示例#22
0
/* ----------------------------------------------------------------------------
mace_interrupt
	The interrupt handler.
---------------------------------------------------------------------------- */
static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
  struct net_device *dev = (struct net_device *) dev_id;
  mace_private *lp = netdev_priv(dev);
  unsigned int ioaddr;
  int status;
  int IntrCnt = MACE_MAX_IR_ITERATIONS;

  if (dev == NULL) {
    pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
	  irq);
    return IRQ_NONE;
  }

  ioaddr = dev->base_addr;

  if (lp->tx_irq_disabled) {
    const char *msg;
    if (lp->tx_irq_disabled)
      msg = "Interrupt with tx_irq_disabled";
    else
      msg = "Re-entering the interrupt handler";
    netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n",
		  msg,
		  inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
		  inb(ioaddr + AM2150_MACE_BASE + MACE_IMR));
    /* WARNING: MACE_IR has been read! */
    return IRQ_NONE;
  }

  if (!netif_device_present(dev)) {
    netdev_dbg(dev, "interrupt from dead card\n");
    return IRQ_NONE;
  }

  do {
    /* WARNING: MACE_IR is a READ/CLEAR port! */
    status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);

    pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);

    if (status & MACE_IR_RCVINT) {
      mace_rx(dev, MACE_MAX_RX_ITERATIONS);
    }

    if (status & MACE_IR_XMTINT) {
      unsigned char fifofc;
      unsigned char xmtrc;
      unsigned char xmtfs;

      fifofc = inb(ioaddr + AM2150_MACE_BASE + MACE_FIFOFC);
      if ((fifofc & MACE_FIFOFC_XMTFC)==0) {
	lp->linux_stats.tx_errors++;
	outb(0xFF, ioaddr + AM2150_XMT_SKIP);
      }

      /* Transmit Retry Count (XMTRC, reg 4) */
      xmtrc = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTRC);
      if (xmtrc & MACE_XMTRC_EXDEF) lp->mace_stats.exdef++;
      lp->mace_stats.xmtrc += (xmtrc & MACE_XMTRC_XMTRC);

      if (
        (xmtfs = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTFS)) &
        MACE_XMTFS_XMTSV /* Transmit Status Valid */
      ) {
	lp->mace_stats.xmtsv++;

	if (xmtfs & ~MACE_XMTFS_XMTSV) {
	  if (xmtfs & MACE_XMTFS_UFLO) {
	    /* Underflow.  Indicates that the Transmit FIFO emptied before
	       the end of frame was reached. */
	    lp->mace_stats.uflo++;
	  }
	  if (xmtfs & MACE_XMTFS_LCOL) {
	    /* Late Collision */
	    lp->mace_stats.lcol++;
	  }
	  if (xmtfs & MACE_XMTFS_MORE) {
	    /* MORE than one retry was needed */
	    lp->mace_stats.more++;
	  }
	  if (xmtfs & MACE_XMTFS_ONE) {
	    /* Exactly ONE retry occurred */
	    lp->mace_stats.one++;
	  }
	  if (xmtfs & MACE_XMTFS_DEFER) {
	    /* Transmission was defered */
	    lp->mace_stats.defer++;
	  }
	  if (xmtfs & MACE_XMTFS_LCAR) {
	    /* Loss of carrier */
	    lp->mace_stats.lcar++;
	  }
	  if (xmtfs & MACE_XMTFS_RTRY) {
	    /* Retry error: transmit aborted after 16 attempts */
	    lp->mace_stats.rtry++;
	  }
        } /* if (xmtfs & ~MACE_XMTFS_XMTSV) */

      } /* if (xmtfs & MACE_XMTFS_XMTSV) */

      lp->linux_stats.tx_packets++;
      lp->tx_free_frames++;
      netif_wake_queue(dev);
    } /* if (status & MACE_IR_XMTINT) */

    if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) {
      if (status & MACE_IR_JAB) {
        /* Jabber Error.  Excessive transmit duration (20-150ms). */
        lp->mace_stats.jab++;
      }
      if (status & MACE_IR_BABL) {
        /* Babble Error.  >1518 bytes transmitted. */
        lp->mace_stats.babl++;
      }
      if (status & MACE_IR_CERR) {
	/* Collision Error.  CERR indicates the absence of the
	   Signal Quality Error Test message after a packet
	   transmission. */
        lp->mace_stats.cerr++;
      }
      if (status & MACE_IR_RCVCCO) {
        /* Receive Collision Count Overflow; */
        lp->mace_stats.rcvcco++;
      }
      if (status & MACE_IR_RNTPCO) {
        /* Runt Packet Count Overflow */
        lp->mace_stats.rntpco++;
      }
      if (status & MACE_IR_MPCO) {
        /* Missed Packet Count Overflow */
        lp->mace_stats.mpco++;
      }
    } /* if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) */

  } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt));

  return IRQ_HANDLED;
} /* mace_interrupt */
示例#23
0
int hpprobe1(struct device *dev, int ioaddr)
{
    int i, board_id, wordmode;
    char *name;
    unsigned char *station_addr = dev->dev_addr;

    /* Check for the HP physical address, 08 00 09 xx xx xx. */
    /* This really isn't good enough: we may pick up HP LANCE boards
       also!  Avoid the lance 0x5757 signature. */
    if (inb(ioaddr) != 0x08
            || inb(ioaddr+1) != 0x00
            || inb(ioaddr+2) != 0x09
            || inb(ioaddr+14) == 0x57)
        return ENODEV;

    /* Set up the parameters based on the board ID.
       If you have additional mappings, please mail them to [email protected]. */
    if ((board_id = inb(ioaddr + HP_ID)) & 0x80) {
        name = "HP27247";
        wordmode = 1;
    } else {
        name = "HP27250";
        wordmode = 0;
    }

    /* Grab the region so we can find another board if something fails. */
    snarf_region(ioaddr, HP_IO_EXTENT);

    printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);

    for(i = 0; i < ETHER_ADDR_LEN; i++)
        printk(" %2.2x", station_addr[i] = inb(ioaddr + i));

    /* Snarf the interrupt now.  Someday this could be moved to open(). */
    if (dev->irq < 2) {
        int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
        int irq_8list[] = { 7, 5, 3, 4, 9, 0};
        int *irqp = wordmode ? irq_16list : irq_8list;
        do {
            int irq = *irqp;
            if (request_irq (irq, NULL) != -EBUSY) {
                autoirq_setup(0);
                /* Twinkle the interrupt, and check if it's seen. */
                outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
                outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
                if (irq == autoirq_report(0)		 /* It's a good IRQ line! */
                        && request_irq (irq, &ei_interrupt) == 0) {
                    printk(" selecting IRQ %d.\n", irq);
                    dev->irq = *irqp;
                    break;
                }
            }
        } while (*++irqp);
        if (*irqp == 0) {
            printk(" no free IRQ lines.\n");
            return EBUSY;
        }
    } else {
        if (dev->irq == 2)
            dev->irq = 9;
        if (irqaction(dev->irq, &ei_sigaction)) {
            printk (" unable to get IRQ %d.\n", dev->irq);
            return EBUSY;
        }
    }

    if (ei_debug > 1)
        printk(version);

    /* Set the base address to point to the NIC, not the "real" base! */
    dev->base_addr = ioaddr + NIC_OFFSET;

    ethdev_init(dev);

    ei_status.name = name;
    ei_status.word16 = wordmode;
    ei_status.tx_start_page = HP_START_PG;
    ei_status.rx_start_page = HP_START_PG + TX_PAGES;
    ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;

    ei_status.reset_8390 = &hp_reset_8390;
    ei_status.block_input = &hp_block_input;
    ei_status.block_output = &hp_block_output;
    hp_init_card(dev);

    return 0;
}
示例#24
0
static uint8_t read_memmap(uint16_t addr)
{
	write_emi_address(addr, 0);
	return inb(0x84 + (addr & 0x3));
}
示例#25
0
/*
 * Either use the shared memory (if enabled on the board) or put the packet
 * out through the ASIC FIFO.
 */
static void
el2_block_output(struct device *dev, int count,
                 const unsigned char *buf, int start_page)
{
    unsigned short int *wrd;
    int boguscount;		/* timeout counter */
    unsigned short word;	/* temporary for better machine code */

    if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
        outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
    else
        outb(EGACFR_NORM, E33G_GACFR);

    if (dev->mem_start) {	/* Shared memory transfer */
        unsigned long dest_addr = dev->mem_start +
                                  ((start_page - ei_status.tx_start_page) << 8);
        memcpy_toio(dest_addr, buf, count);
        outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
        return;
    }

    /*
     *  No shared memory, put the packet out the other way.
     *  Set up then start the internal memory transfer to Tx Start Page
     */

    word = (unsigned short)start_page;
    outb(word&0xFF, E33G_DMAAH);
    outb(word>>8, E33G_DMAAL);

    outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
           | ECNTRL_START, E33G_CNTRL);

    /*
     *  Here I am going to write data to the FIFO as quickly as possible.
     *  Note that E33G_FIFOH is defined incorrectly. It is really
     *  E33G_FIFOL, the lowest port address for both the byte and
     *  word write. Variable 'count' is NOT checked. Caller must supply a
     *  valid count. Note that I may write a harmless extra byte to the
     *  8390 if the byte-count was not even.
     */
    wrd = (unsigned short int *) buf;
    count  = (count + 1) >> 1;
    for(;;)
    {
        boguscount = 0x1000;
        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
        {
            if(!boguscount--)
            {
                printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
                el2_reset_8390(dev);
                goto blocked;
            }
        }
        if(count > WRD_COUNT)
        {
            outsw(E33G_FIFOH, wrd, WRD_COUNT);
            wrd   += WRD_COUNT;
            count -= WRD_COUNT;
        }
        else
        {
            outsw(E33G_FIFOH, wrd, count);
            break;
        }
    }
blocked:
    ;
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
    return;
}
示例#26
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;
}
示例#27
0
/*
 * Check if the keyboard controller has a keypress for us.
 * Some parts (Enter Release, LED change) are still blocking polled here,
 * but hopefully they are all short.
 */
int kdb_get_kbd_char(void)
{
	int scancode, scanstatus;
	static int shift_lock;	/* CAPS LOCK state (0-off, 1-on) */
	static int shift_key;	/* Shift next keypress */
	static int ctrl_key;
	u_short keychar;

	if (KDB_FLAG(NO_I8042) || KDB_FLAG(NO_VT_CONSOLE) ||
	    (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff)) {
		kbd_exists = 0;
		return -1;
	}
	kbd_exists = 1;

	if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
		return -1;

	/*
	 * Fetch the scancode
	 */
	scancode = inb(KBD_DATA_REG);
	scanstatus = inb(KBD_STATUS_REG);

	/*
	 * Ignore mouse events.
	 */
	if (scanstatus & KBD_STAT_MOUSE_OBF)
		return -1;

	/*
	 * Ignore release, trigger on make
	 * (except for shift keys, where we want to
	 *  keep the shift state so long as the key is
	 *  held down).
	 */

	if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
		/*
		 * Next key may use shift table
		 */
		if ((scancode & 0x80) == 0)
			shift_key = 1;
		else
			shift_key = 0;
		return -1;
	}

	if ((scancode&0x7f) == 0x1d) {
		/*
		 * Left ctrl key
		 */
		if ((scancode & 0x80) == 0)
			ctrl_key = 1;
		else
			ctrl_key = 0;
		return -1;
	}

	if ((scancode & 0x80) != 0)
		return -1;

	scancode &= 0x7f;

	/*
	 * Translate scancode
	 */

	if (scancode == 0x3a) {
		/*
		 * Toggle caps lock
		 */
		shift_lock ^= 1;

#ifdef	KDB_BLINK_LED
		kdb_toggleled(0x4);
#endif
		return -1;
	}

	if (scancode == 0x0e) {
		/*
		 * Backspace
		 */
		return 8;
	}

	/* Special Key */
	switch (scancode) {
	case 0xF: /* Tab */
		return 9;
	case 0x53: /* Del */
		return 4;
	case 0x47: /* Home */
		return 1;
	case 0x4F: /* End */
		return 5;
	case 0x4B: /* Left */
		return 2;
	case 0x48: /* Up */
		return 16;
	case 0x50: /* Down */
		return 14;
	case 0x4D: /* Right */
		return 6;
	}

	if (scancode == 0xe0)
		return -1;

	/*
	 * For Japanese 86/106 keyboards
	 * 	See comment in drivers/char/pc_keyb.c.
	 * 	- Masahiro Adegawa
	 */
	if (scancode == 0x73)
		scancode = 0x59;
	else if (scancode == 0x7d)
		scancode = 0x7c;

	if (!shift_lock && !shift_key && !ctrl_key) {
		keychar = plain_map[scancode];
	} else if ((shift_lock || shift_key) && key_maps[1]) {
		keychar = key_maps[1][scancode];
	} else if (ctrl_key && key_maps[4]) {
		keychar = key_maps[4][scancode];
	} else {
		keychar = 0x0020;
		kdb_printf("Unknown state/scancode (%d)\n", scancode);
	}
	keychar &= 0x0fff;
	if (keychar == '\t')
		keychar = ' ';
	switch (KTYP(keychar)) {
	case KT_LETTER:
	case KT_LATIN:
		if (isprint(keychar))
			break;		/* printable characters */
		/* drop through */
	case KT_SPEC:
		if (keychar == K_ENTER)
			break;
		/* drop through */
	default:
		return -1;	/* ignore unprintables */
	}

	if ((scancode & 0x7f) == 0x1c) {
		/*
		 * enter key.  All done.  Absorb the release scancode.
		 */
		while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
			;

		/*
		 * Fetch the scancode
		 */
		scancode = inb(KBD_DATA_REG);
		scanstatus = inb(KBD_STATUS_REG);

		while (scanstatus & KBD_STAT_MOUSE_OBF) {
			scancode = inb(KBD_DATA_REG);
			scanstatus = inb(KBD_STATUS_REG);
		}

		if (scancode != 0x9c) {
			/*
			 * Wasn't an enter-release,  why not?
			 */
			kdb_printf("kdb: expected enter got 0x%x status 0x%x\n",
			       scancode, scanstatus);
		}

		return 13;
	}

	return keychar & 0xff;
}
示例#28
0
static void dtl1_receive(dtl1_info_t *info)
{
    unsigned int iobase;
    nsh_t *nsh;
    int boguscount = 0;

    if (!info) {
        BT_ERR("Unknown device");
        return;
    }

    iobase = info->p_dev->resource[0]->start;

    do {
        info->hdev->stat.byte_rx++;

        /* Allocate packet */
        if (info->rx_skb == NULL)
            if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
                BT_ERR("Can't allocate mem for new packet");
                info->rx_state = RECV_WAIT_NSH;
                info->rx_count = NSHL;
                return;
            }

        *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
        nsh = (nsh_t *)info->rx_skb->data;

        info->rx_count--;

        if (info->rx_count == 0) {

            switch (info->rx_state) {
            case RECV_WAIT_NSH:
                info->rx_state = RECV_WAIT_DATA;
                info->rx_count = nsh->len + (nsh->len & 0x0001);
                break;
            case RECV_WAIT_DATA:
                bt_cb(info->rx_skb)->pkt_type = nsh->type;

                /* remove PAD byte if it exists */
                if (nsh->len & 0x0001) {
                    info->rx_skb->tail--;
                    info->rx_skb->len--;
                }

                /* remove NSH */
                skb_pull(info->rx_skb, NSHL);

                switch (bt_cb(info->rx_skb)->pkt_type) {
                case 0x80:
                    /* control data for the Nokia Card */
                    dtl1_control(info, info->rx_skb);
                    break;
                case 0x82:
                case 0x83:
                case 0x84:
                    /* send frame to the HCI layer */
                    info->rx_skb->dev = (void *) info->hdev;
                    bt_cb(info->rx_skb)->pkt_type &= 0x0f;
                    hci_recv_frame(info->rx_skb);
                    break;
                default:
                    /* unknown packet */
                    BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
                    kfree_skb(info->rx_skb);
                    break;
                }

                info->rx_state = RECV_WAIT_NSH;
                info->rx_count = NSHL;
                info->rx_skb = NULL;
                break;
            }

        }

        /* Make sure we don't stay here too long */
        if (boguscount++ > 32)
            break;

    } while (inb(iobase + UART_LSR) & UART_LSR_DR);
}
示例#29
0
/*
 * set thermal config
 */
static void set_thermal_config(void)
{
	u8 byte, byte2;
	u16 word;
	u32 dword;
	device_t sm_dev;

	/* set adt7475 */
	ADT7475_write_byte(0x40, 0x04);
	/* Config Register 6 */
	ADT7475_write_byte(0x10, 0x00);
	/* Config Register 7 */
	ADT7475_write_byte(0x11, 0x00);

	/* set Offset 64 format, enable THERM on Remote 1& Remote 2 */
	ADT7475_write_byte(0x7c, 0xa0);
	/* No offset for remote 2 */
	ADT7475_write_byte(0x72, 0x00);
	/* PWM 1 configuration register    CPU fan controlled by CPU Thermal Diode */
	ADT7475_write_byte(0x5c, 0x02);
	/* PWM 3 configuration register    Case fan controlled by 690 temp */
	ADT7475_write_byte(0x5e, 0x42);

	/* remote 1 low temp limit */
	ADT7475_write_byte(0x4e, 0x00);
	/* remote 1 High temp limit    (90C) */
	ADT7475_write_byte(0x4f, 0x9a);

	/* remote2 Low Temp Limit */
	ADT7475_write_byte(0x52, 0x00);
	/* remote2 High Limit    (90C) */
	ADT7475_write_byte(0x53, 0x9a);

	/*  remote 1 therm temp limit    (95C) */
	ADT7475_write_byte(0x6a, 0x9f);
	/* remote 2 therm temp limit    (95C) */
	ADT7475_write_byte(0x6c, 0x9f);

	/* PWM 1 minimum duty cycle     (37%) */
	ADT7475_write_byte(0x64, 0x60);
	/* PWM 1 Maximum duty cycle    (100%) */
	ADT7475_write_byte(0x38, 0xff);
	/* PWM 3 minimum duty cycle     (37%) */
	ADT7475_write_byte(0x66, 0x60);
	/* PWM 3 Maximum Duty Cycle    (100%) */
	ADT7475_write_byte(0x3a, 0xff);

	/*  Remote 1 temperature Tmin     (32C) */
	ADT7475_write_byte(0x67, 0x60);
	/* Remote 2 temperature Tmin     (32C) */
	ADT7475_write_byte(0x69, 0x60);
	/* remote 1 Trange            (53C ramp range) */
	ADT7475_write_byte(0x5f, 0xe8);
	/* remote 2 Trange            (53C ramp range) */
	ADT7475_write_byte(0x61, 0xe8);

	/* PWM2 Duty cycle */
	ADT7475_write_byte(0x65, 0x00);
	/* PWM2 Disabled */
	ADT7475_write_byte(0x5d, 0x80);
	/* PWM2 Max Duty Cycle */
	ADT7475_write_byte(0x39, 0x00);

	/* Config Register 3 - enable smbalert & therm */
	ADT7475_write_byte(0x78, 0x03);
	/* Config Register 4 - enable therm output */
	ADT7475_write_byte(0x7d, 0x09);
	/* Interrupt Mask Register 2 - Mask SMB alert for Therm Conditions, Fan 2 fault, SmbAlert Fan for Therm Timer event */
	ADT7475_write_byte(0x75, 0x2a);
	/* Config Register 1 Set Start bit */
	ADT7475_write_byte(0x40, 0x05);
	/* Read status register to clear any old errors */
	byte2 = ADT7475_read_byte(0x42);
	byte = ADT7475_read_byte(0x41);

	/* remote 1 temperature offset */
	ADT7475_write_byte(0x70, 0x00);

	printk(BIOS_INFO, "Init adt7475 end , status 0x42 %02x, status 0x41 %02x\n",
		    byte2, byte);

	/* sb600 setting for thermal config. Set SB600 GPM5 to trigger ACPI event */
	/* set GPM5 as GPM5, not DDR3_memory disable */
	byte = pm_ioread(0x8f);
	byte |= 1 << 6;		/* enable GPE */
	pm_iowrite(0x8f, byte);

	/* GPM5 as GPIO not USB OC */
	sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
	dword = pci_read_config32(sm_dev, 0x64);
	dword |= 1 << 19;
	pci_write_config32(sm_dev, 0x64, dword);

	/* Enable Client Management Index/Data registers */
	dword = pci_read_config32(sm_dev, 0x78);
	dword |= 1 << 11;	/* Cms_enable */
	pci_write_config32(sm_dev, 0x78, dword);

	/* MiscfuncEnable */
	byte = pci_read_config8(sm_dev, 0x41);
	byte |= (1 << 5);
	pci_write_config8(sm_dev, 0x41, byte);

	/* set GPM5 as input */
	/* set index register 0C50h to 13h (miscellaneous control) */
	outb(0x13, 0xC50);	/* CMIndex */
	/* set CM data register 0C51h bits [7:6] to 01b to set Input/Out control */
	byte = inb(0xC51);	/* CMData */
	byte &= 0x3f;
	byte |= 1 << 6;
	outb(byte, 0xC51);
	/* set GPM port 0C52h bit 5 to 1 to tri-state the GPM port */
	byte = inb(0xc52);	/* GpmPort */
	byte |= 1 << 5;
	outb(byte, 0xc52);
	/* set CM data register 0C51h bits [7:6] to 00b to set GPM port for read */
	byte = inb(0xc51);
	byte &= 0x3f;
	outb(byte, 0xc51);

	/* trigger SCI/SMI */
	byte = pm_ioread(0x34);
	byte &= 0xcf;
	pm_iowrite(0x34, byte);

	/* set GPM5 to not wake from s5 */
	byte = pm_ioread(0x77);
	byte &= ~(1 << 5);
	pm_iowrite(0x77, byte);

	/* trigger on falling edge */
	byte = pm_ioread(0x38);
	byte &= ~(1 << 2);
	pm_iowrite(0x38, byte);

	/* set SB600 GPIO 64 to GPIO with pull-up */
	byte = pm2_ioread(0x42);
	byte &= 0x3f;
	pm2_iowrite(0x42, byte);

	/* set GPIO 64 to input */
	word = pci_read_config16(sm_dev, 0x56);
	word |= 1 << 7;
	pci_write_config16(sm_dev, 0x56, word);

	/* set GPIO 64 internal pull-up */
	byte = pm2_ioread(0xf0);
	byte &= 0xee;
	pm2_iowrite(0xf0, byte);

	/* set Talert to be active low */
	byte = pm_ioread(0x67);
	byte &= ~(1 << 5);
	pm_iowrite(0x67, byte);

	/* set Talert to generate ACPI event */
	byte = pm_ioread(0x3c);
	byte &= 0xf3;
	pm_iowrite(0x3c, byte);

	/* THERMTRIP pin */
	/* byte = pm_ioread(0x68);
	 * byte |= 1 << 3;
	 * pm_iowrite(0x68, byte);
	 *
	 * byte = pm_ioread(0x55);
	 * byte |= 1 << 0;
	 * pm_iowrite(0x55, byte);
	 *
	 * byte = pm_ioread(0x67);
	 * byte &= ~( 1 << 6);
	 * pm_iowrite(0x67, byte);
	 */
}
示例#30
0
文件: tpm_nsc.c 项目: AK101111/linux
static u8 tpm_nsc_status(struct tpm_chip *chip)
{
	struct tpm_nsc_priv *priv = dev_get_drvdata(&chip->dev);

	return inb(priv->base + NSC_STATUS);
}