static inline void w83697hf_lock(void) { outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ }
/* 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. */ static int __init el2_probe1(struct net_device *dev, int ioaddr) { int i, iobase_reg, membase_reg, saved_406, wordlength, retval; static unsigned version_printed; unsigned long vendor_id; if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME)) return -EBUSY; if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) { retval = -EBUSY; goto out; } /* Reset and/or avoid any lurking NE2000 */ if (inb(ioaddr + 0x408) == 0xff) { mdelay(1); retval = -ENODEV; goto out1; } /* 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))) { retval = -ENODEV; goto out1; } 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); retval = -ENODEV; goto out1; } if (ei_debug && version_printed++ == 0) pr_debug("%s", version); dev->base_addr = ioaddr; pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr); /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + i); pr_cont("%pM", dev->dev_addr); /* 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) pr_cont(" 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 pr_cont(", 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"; ei_status.mem = NULL; } 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 ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE); #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. */ void __iomem *mem_base = ei_status.mem; 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) { pr_warning("3c503: memory failure or memory address conflict.\n"); dev->mem_start = 0; ei_status.name = "3c503-PIO"; iounmap(mem_base); ei_status.mem = NULL; break; } test_val += 0x55555555; writel(0, mem_base + i); } } #endif /* EL2MEMTEST */ if (dev->mem_start) dev->mem_end = dev->mem_start + EL2_MEMSIZE; if (wordlength) { /* No Tx pages to skip over to get to Rx */ ei_status.priv = 0; ei_status.name = "3c503/16"; } else { ei_status.priv = TX_PAGES * 256; 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; if (dev->irq == 2) dev->irq = 9; else if (dev->irq > 5 && dev->irq != 9) { pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n", dev->irq); dev->irq = 0; } ei_status.saved_irq = dev->irq; dev->netdev_ops = &el2_netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; retval = register_netdev(dev); if (retval) goto out1; if (dev->mem_start) pr_info("%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; pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n", dev->name, ei_status.name, (wordlength+1)<<3); } release_region(ioaddr + 0x400, 8); return 0; out1: release_region(ioaddr + 0x400, 8); out: release_region(ioaddr, EL2_IO_EXTENT); return retval; }
static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; void __iomem *base = ei_status.mem; unsigned short int *buf; unsigned short word; /* Maybe enable shared memory just be to be safe... nahh.*/ if (base) { /* Use the shared memory. */ ring_offset -= (EL2_MB1_START_PG<<8); if (ring_offset + count > EL2_MEMSIZE) { /* We must wrap the input move. */ int semi_count = EL2_MEMSIZE - ring_offset; memcpy_fromio(skb->data, base + ring_offset, semi_count); count -= semi_count; memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); } else { memcpy_fromio(skb->data, base + ring_offset, count); } 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--) { pr_notice("%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); }
static int __init dtlk_dev_probe(void) { unsigned int testval = 0; int i = 0; struct dtlk_settings *sp; if (dtlk_port_lpc | dtlk_port_tts) return -EBUSY; for (i = 0; dtlk_portlist[i]; i++) { #if 0 printk("DoubleTalk PC - Port %03x = %04x\n", dtlk_portlist[i], (testval = inw_p(dtlk_portlist[i]))); #endif if (check_region(dtlk_portlist[i], DTLK_IO_EXTENT)) continue; testval = inw_p(dtlk_portlist[i]); if ((testval &= 0xfbff) == 0x107f) { request_region(dtlk_portlist[i], DTLK_IO_EXTENT, "dtlk"); dtlk_port_lpc = dtlk_portlist[i]; dtlk_port_tts = dtlk_port_lpc + 1; sp = dtlk_interrogate(); printk("DoubleTalk PC at %03x-%03x, " "ROM version %s, serial number %u", dtlk_portlist[i], dtlk_portlist[i] + DTLK_IO_EXTENT - 1, sp->rom_version, sp->serial_number); /* put LPC port into known state, so dtlk_readable() gives valid result */ outb_p(0xff, dtlk_port_lpc); /* INIT string and index marker */ dtlk_write_bytes("\036\1@\0\0012I\r", 8); /* posting an index takes 18 msec. Here, we wait up to 100 msec to see whether it appears. */ dtlk_delay(100); dtlk_has_indexing = dtlk_readable(); #ifdef TRACING printk(", indexing %d\n", dtlk_has_indexing); #endif #ifdef INSCOPE { /* This macro records ten samples read from the LPC port, for later display */ #define LOOK \ for (i = 0; i < 10; i++) \ { \ buffer[b++] = inb_p(dtlk_port_lpc); \ __delay(loops_per_jiffy/(1000000/HZ)); \ } char buffer[1000]; int b = 0, i, j; LOOK outb_p(0xff, dtlk_port_lpc); buffer[b++] = 0; LOOK dtlk_write_bytes("\0012I\r", 4); buffer[b++] = 0; __delay(50 * loops_per_jiffy / (1000/HZ)); outb_p(0xff, dtlk_port_lpc); buffer[b++] = 0; LOOK printk("\n"); for (j = 0; j < b; j++) printk(" %02x", buffer[j]); printk("\n"); } #endif /* INSCOPE */ #ifdef OUTSCOPE { /* This macro records ten samples read from the TTS port, for later display */ #define LOOK \ for (i = 0; i < 10; i++) \ { \ buffer[b++] = inb_p(dtlk_port_tts); \ __delay(loops_per_jiffy/(1000000/HZ)); /* 1 us */ \ } char buffer[1000]; int b = 0, i, j; mdelay(10); /* 10 ms */ LOOK outb_p(0x03, dtlk_port_tts); buffer[b++] = 0; LOOK LOOK printk("\n"); for (j = 0; j < b; j++) printk(" %02x", buffer[j]); printk("\n"); } #endif /* OUTSCOPE */ dtlk_write_bytes("Double Talk found", 18); return 0; } } printk(KERN_INFO "\nDoubleTalk PC - not found\n"); return -ENODEV; }
static inline void sci_outp(struct sci_struct *sci, int offset, int value) { outb_p(value, sci->port+offset); }
int wd8003_start_xmit(struct sk_buff *skb, struct device *dev) { unsigned char cmd; int len; cli(); if (dev->tbusy) { /* put in a time out. */ if (jiffies - dev->trans_start < 30) { sti(); return (1); } printk ("wd8003 transmit timed out. \n"); } dev->tbusy = 1; if (skb == NULL) { sti(); wd_trs(dev); return (0); } /* this should check to see if it's been killed. */ if (skb->dev != dev) { sti(); return (0); } if (!skb->arp) { if ( dev->rebuild_header (skb+1, dev)) { cli(); if (skb->dev == dev) { arp_queue (skb); } cli (); /* arp_queue turns them back on. */ dev->tbusy = 0; sti(); return (0); } } memcpy ((unsigned char *)dev->mem_start, skb+1, skb->len); len = skb->len; /* now we need to set up the card info. */ dev->trans_start = jiffies; len=max(len, ETHER_MIN_LEN); /* actually we should zero out the extra memory. */ /* printk ("start_xmit len - %d\n", len);*/ cmd=inb_p(WD_COMM); cmd &= ~CPAGE; outb_p(cmd, WD_COMM); interrupt_mask |= TRANS_MASK; if (!(dev->interrupt)) outb (interrupt_mask, WD_IMR); outb_p(len&0xff,WD_TB0); outb_p(len>>8,WD_TB1); cmd |= CTRANS; outb_p(cmd,WD_COMM); sti(); if (skb->free) { kfree_skb (skb, FREE_WRITE); } return (0); }
static int wdt977_stop(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); /* unlock the SuperIO chip */ outb_p(UNLOCK_DATA, IO_INDEX_PORT); outb_p(UNLOCK_DATA, IO_INDEX_PORT); /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4 * F3 is reset to its default state * F4 can clear the TIMEOUT'ed state (bit 0) - back to default * We can not use GP17 as a PowerLed, as we use its usage as a RedLed */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(0xFF, IO_DATA_PORT); outb_p(0xF3, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); outb_p(0xF4, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x07, IO_DATA_PORT); outb_p(0xE6, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); /* lock the SuperIO chip */ outb_p(LOCK_DATA, IO_INDEX_PORT); spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "shutdown.\n"); return 0; }
/* Return -1 on error. */ static s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { int hwpec = 0; int block = 0; int ret, xact = 0; #ifdef HAVE_PEC if(isich4) hwpec = (flags & I2C_CLIENT_PEC) != 0; #endif switch (size) { case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); xact = I801_QUICK; break; case I2C_SMBUS_BYTE: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD); xact = I801_BYTE; break; case I2C_SMBUS_BYTE_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) outb_p(data->byte, SMBHSTDAT0); xact = I801_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMBHSTDAT0); outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); } xact = I801_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA: #ifdef HAVE_PEC case I2C_SMBUS_BLOCK_DATA_PEC: if(hwpec && size == I2C_SMBUS_BLOCK_DATA) size = I2C_SMBUS_BLOCK_DATA_PEC; #endif outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); block = 1; break; case I2C_SMBUS_PROC_CALL: default: dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); return -1; }
static int wdt_stop(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); /* Unlock the SuperIO chip */ outb_p(UNLOCK_DATA, IO_INDEX_PORT); outb_p(UNLOCK_DATA, IO_INDEX_PORT); /* * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. * F2 is reset to its default value (watchdog timer disabled). * F3 is reset to its default state. * F4 clears the TIMEOUT'ed state (bit 0) - back to default. */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(0xFF, IO_DATA_PORT); outb_p(0xF3, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); outb_p(0xF4, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); /* * Select device Aux1 (dev=7) to set GP16 (in reg E6) and * Gp13 (in reg E3) as inputs. */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x07, IO_DATA_PORT); if (!testmode) { outb_p(0xE6, IO_INDEX_PORT); outb_p(0x01, IO_DATA_PORT); } outb_p(0xE3, IO_INDEX_PORT); outb_p(0x01, IO_DATA_PORT); /* Lock the SuperIO chip */ outb_p(LOCK_DATA, IO_INDEX_PORT); spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "shutdown.\n"); return 0; }
static int i801_transaction(void) { int temp; int result = 0; int timeout = 0; dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x," "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* Make sure the SMBus host is ready to start transmitting */ /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n", temp); outb_p(temp, SMBHSTSTS); if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); return -1; } else { dev_dbg(&I801_dev->dev, "Successfull!\n"); } } outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); /* We will always wait for a fraction of a second! */ do { msleep(1); temp = inb_p(SMBHSTSTS); } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); result = -1; } if (temp & 0x10) { result = -1; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } if (temp & 0x08) { result = -1; dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " "until next hard reset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ } if (temp & 0x04) { result = -1; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) outb_p(inb(SMBHSTSTS), SMBHSTSTS); if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" "(%02x)\n", temp); } dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); return result; }
/* All-inclusive block transaction function */ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, int command) { int i, len; int smbcmd; int temp; int result = 0; int timeout; unsigned char hostc, errmask; if (command == I2C_SMBUS_I2C_BLOCK_DATA) { if (read_write == I2C_SMBUS_WRITE) { /* set I2C_EN bit in configuration register */ pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); pci_write_config_byte(I801_dev, SMBHSTCFG, hostc | SMBHSTCFG_I2C_EN); } else { dev_err(&I801_dev->dev, "I2C_SMBUS_I2C_BLOCK_READ not DB!\n"); return -1; } } if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; if (len < 1) len = 1; if (len > 32) len = 32; outb_p(len, SMBHSTDAT0); outb_p(data->block[1], SMBBLKDAT); } else { len = 32; /* max for reads */ } if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) { /* set 32 byte buffer */ } for (i = 1; i <= len; i++) { if (i == len && read_write == I2C_SMBUS_READ) smbcmd = I801_BLOCK_LAST; else smbcmd = I801_BLOCK_DATA; outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); /* Make sure the SMBus host is ready to start transmitting */ temp = inb_p(SMBHSTSTS); if (i == 1) { /* Erronenous conditions before transaction: * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ errmask=0x9f; } else { /* Erronenous conditions during transaction: * Failed, Bus_Err, Dev_Err, Intr */ errmask=0x1e; } if (temp & errmask) { dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " "Resetting... \n", temp); outb_p(temp, SMBHSTSTS); if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { dev_err(&I801_dev->dev, "Reset failed! (%02x)\n", temp); result = -1; goto END; } if (i != 1) { /* if die in middle of block transaction, fail */ result = -1; goto END; } } if (i == 1) outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); /* We will always wait for a fraction of a second! */ timeout = 0; do { temp = inb_p(SMBHSTSTS); msleep(1); } while ((!(temp & 0x80)) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { result = -1; dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); } if (temp & 0x10) { result = -1; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } else if (temp & 0x08) { result = -1; dev_err(&I801_dev->dev, "Bus collision!\n"); } else if (temp & 0x04) { result = -1; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } if (i == 1 && read_write == I2C_SMBUS_READ) { len = inb_p(SMBHSTDAT0); if (len < 1) len = 1; if (len > 32) len = 32; data->block[0] = len; } /* Retrieve/store value in SMBBLKDAT */ if (read_write == I2C_SMBUS_READ) data->block[i] = inb_p(SMBBLKDAT); if (read_write == I2C_SMBUS_WRITE && i+1 <= len) outb_p(data->block[i+1], SMBBLKDAT); if ((temp & 0x9e) != 0x00) outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Bad status (%02x) at end of transaction\n", temp); } dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); if (result < 0) goto END; } #ifdef HAVE_PEC if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { /* wait for INTR bit as advised by Intel */ timeout = 0; do { temp = inb_p(SMBHSTSTS); msleep(1); } while ((!(temp & 0x02)) && (timeout++ < MAX_TIMEOUT)); if (timeout >= MAX_TIMEOUT) { dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); } outb_p(temp, SMBHSTSTS); } #endif result = 0; END: if (command == I2C_SMBUS_I2C_BLOCK_DATA) { /* restore saved configuration register value */ pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); } return result; }
/* Return negative errno on error. */ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { int i, len; int temp; int timeout; s32 result = 0; /* make sure SMBus is idle */ temp = inb_p(SMBHSTSTS); for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE); timeout++) { msleep(1); temp = inb_p(SMBHSTSTS); } if (timeout >= MAX_TIMEOUT) dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp); /* clear status register (clear-on-write) */ outb_p(0xFF, SMBHSTSTS); switch (size) { case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = ALI1535_QUICK; outb_p(size, SMBHSTTYP); /* output command */ break; case I2C_SMBUS_BYTE: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = ALI1535_BYTE; outb_p(size, SMBHSTTYP); /* output command */ if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD); break; case I2C_SMBUS_BYTE_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = ALI1535_BYTE_DATA; outb_p(size, SMBHSTTYP); /* output command */ outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) outb_p(data->byte, SMBHSTDAT0); break; case I2C_SMBUS_WORD_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = ALI1535_WORD_DATA; outb_p(size, SMBHSTTYP); /* output command */ outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMBHSTDAT0); outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); } break; case I2C_SMBUS_BLOCK_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = ALI1535_BLOCK_DATA; outb_p(size, SMBHSTTYP); /* output command */ outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; if (len < 0) { len = 0; data->block[0] = len; } if (len > 32) { len = 32; data->block[0] = len; } outb_p(len, SMBHSTDAT0); /* Reset SMBBLKDAT */ outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP); for (i = 1; i <= len; i++) outb_p(data->block[i], SMBBLKDAT); } break; default: dev_warn(&adap->dev, "Unsupported transaction %d\n", size); result = -EOPNOTSUPP; goto EXIT; }
static int ali1535_transaction(struct i2c_adapter *adap) { int temp; int result = 0; int timeout = 0; dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, " "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* get status */ temp = inb_p(SMBHSTSTS); /* Make sure the SMBus host is ready to start transmitting */ /* Check the busy bit first */ if (temp & ALI1535_STS_BUSY) { /* If the host controller is still busy, it may have timed out * in the previous transaction, resulting in a "SMBus Timeout" * printk. I've tried the following to reset a stuck busy bit. * 1. Reset the controller with an KILL command. (this * doesn't seem to clear the controller if an external * device is hung) * 2. Reset the controller and the other SMBus devices with a * T_OUT command. (this clears the host busy bit if an * external device is hung, but it comes back upon a new * access to a device) * 3. Disable and reenable the controller in SMBHSTCFG. Worst * case, nothing seems to work except power reset. */ /* Try resetting entire SMB bus, including other devices - This * may not work either - it clears the BUSY bit but then the * BUSY bit may come back on when you try and use the chip * again. If that's the case you are stuck. */ dev_info(&adap->dev, "Resetting entire SMB Bus to clear busy condition (%02x)\n", temp); outb_p(ALI1535_T_OUT, SMBHSTTYP); temp = inb_p(SMBHSTSTS); } /* now check the error bits and the busy bit */ if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { /* do a clear-on-write */ outb_p(0xFF, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { /* This is probably going to be correctable only by a * power reset as one of the bits now appears to be * stuck */ /* This may be a bus or device with electrical problems. */ dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - controller or " "device on bus is probably hung\n", temp); return -EBUSY; } } else { /* check and clear done bit */ if (temp & ALI1535_STS_DONE) { outb_p(temp, SMBHSTSTS); } } /* start the transaction by writing anything to the start register */ outb_p(0xFF, SMBHSTPORT); /* We will always wait for a fraction of a second! */ timeout = 0; do { msleep(1); temp = inb_p(SMBHSTSTS); } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE)) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { result = -ETIMEDOUT; dev_err(&adap->dev, "SMBus Timeout!\n"); } if (temp & ALI1535_STS_FAIL) { result = -EIO; dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); } /* Unfortunately the ALI SMB controller maps "no response" and "bus * collision" into a single bit. No reponse is the usual case so don't * do a printk. This means that bus collisions go unreported. */ if (temp & ALI1535_STS_BUSERR) { result = -ENXIO; dev_dbg(&adap->dev, "Error: no response or bus collision ADD=%02x\n", inb_p(SMBHSTADD)); } /* haven't ever seen this */ if (temp & ALI1535_STS_DEV) { result = -EIO; dev_err(&adap->dev, "Error: device error\n"); } /* check to see if the "command complete" indication is set */ if (!(temp & ALI1535_STS_DONE)) { result = -ETIMEDOUT; dev_err(&adap->dev, "Error: command never completed\n"); } dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, " "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* take consequent actions for error conditions */ if (!(temp & ALI1535_STS_DONE)) { /* issue "kill" to reset host controller */ outb_p(ALI1535_KILL,SMBHSTTYP); outb_p(0xFF,SMBHSTSTS); } else if (temp & ALI1535_STS_ERR) { /* issue "timeout" to reset all devices on bus */ outb_p(ALI1535_T_OUT,SMBHSTTYP); outb_p(0xFF,SMBHSTSTS); } return result; }
static void dt_sendcmd(u_int cmd) { outb_p(cmd & 0xFF, speakup_info.port_tts); outb_p((cmd >> 8) & 0xFF, speakup_info.port_tts+1); }
static void bluecard_write_wakeup(bluecard_info_t *info) { if (!info) { BT_ERR("Unknown device"); return; } if (!test_bit(XMIT_SENDING_READY, &(info->tx_state))) return; if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) { set_bit(XMIT_WAKEUP, &(info->tx_state)); return; } do { register unsigned int iobase = info->p_dev->resource[0]->start; register unsigned int offset; register unsigned char command; register unsigned long ready_bit; register struct sk_buff *skb; register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); if (!pcmcia_dev_present(info->p_dev)) return; if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) { if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state))) break; offset = 0x10; command = REG_COMMAND_TX_BUF_TWO; ready_bit = XMIT_BUF_TWO_READY; } else { if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state))) break; offset = 0x00; command = REG_COMMAND_TX_BUF_ONE; ready_bit = XMIT_BUF_ONE_READY; } if (!(skb = skb_dequeue(&(info->txq)))) break; if (bt_cb(skb)->pkt_type & 0x80) { /* Disable RTS */ info->ctrl_reg |= REG_CONTROL_RTS; outb(info->ctrl_reg, iobase + REG_CONTROL); } /* Activate LED */ bluecard_enable_activity_led(info); /* Send frame */ len = bluecard_write(iobase, offset, skb->data, skb->len); /* Tell the FPGA to send the data */ outb_p(command, iobase + REG_COMMAND); /* Mark the buffer as dirty */ clear_bit(ready_bit, &(info->tx_state)); if (bt_cb(skb)->pkt_type & 0x80) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); DEFINE_WAIT(wait); unsigned char baud_reg; switch (bt_cb(skb)->pkt_type) { case PKT_BAUD_RATE_460800: baud_reg = REG_CONTROL_BAUD_RATE_460800; break; case PKT_BAUD_RATE_230400: baud_reg = REG_CONTROL_BAUD_RATE_230400; break; case PKT_BAUD_RATE_115200: baud_reg = REG_CONTROL_BAUD_RATE_115200; break; case PKT_BAUD_RATE_57600: /* Fall through... */ default: baud_reg = REG_CONTROL_BAUD_RATE_57600; break; } /* Wait until the command reaches the baseband */ prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ/10); finish_wait(&wq, &wait); /* Set baud on baseband */ info->ctrl_reg &= ~0x03; info->ctrl_reg |= baud_reg; outb(info->ctrl_reg, iobase + REG_CONTROL); /* Enable RTS */ info->ctrl_reg &= ~REG_CONTROL_RTS; outb(info->ctrl_reg, iobase + REG_CONTROL); /* Wait before the next HCI packet can be send */ prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ); finish_wait(&wq, &wait); } if (len == skb->len) { kfree_skb(skb); } else { skb_pull(skb, len); skb_queue_head(&(info->txq), skb); } info->hdev->stat.byte_tx += len; /* Change buffer */ change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state)); } while (test_bit(XMIT_WAKEUP, &(info->tx_state))); clear_bit(XMIT_SENDING, &(info->tx_state)); }
static int wdt_start(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); /* Unlock the SuperIO chip */ outb_p(UNLOCK_DATA, IO_INDEX_PORT); outb_p(UNLOCK_DATA, IO_INDEX_PORT); /* * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. * F2 has the timeout in watchdog counter units. * F3 is set to enable watchdog LED blink at timeout. * F4 is used to just clear the TIMEOUT'ed state (bit 0). */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(timeoutW, IO_DATA_PORT); outb_p(0xF3, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); outb_p(0xF4, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); /* Set device Aux2 active */ outb_p(0x30, IO_INDEX_PORT); outb_p(0x01, IO_DATA_PORT); /* * Select device Aux1 (dev=7) to set GP16 as the watchdog output * (in reg E6) and GP13 as the watchdog LED output (in reg E3). * Map GP16 at pin 119. * In test mode watch the bit 0 on F4 to indicate "triggered" or * check watchdog LED on SBC. */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x07, IO_DATA_PORT); if (!testmode) { unsigned pin_map; outb_p(0xE6, IO_INDEX_PORT); outb_p(0x0A, IO_DATA_PORT); outb_p(0x2C, IO_INDEX_PORT); pin_map = inb_p(IO_DATA_PORT); pin_map |= 0x10; pin_map &= ~(0x20); outb_p(0x2C, IO_INDEX_PORT); outb_p(pin_map, IO_DATA_PORT); } outb_p(0xE3, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); /* Set device Aux1 active */ outb_p(0x30, IO_INDEX_PORT); outb_p(0x01, IO_DATA_PORT); /* Lock the SuperIO chip */ outb_p(LOCK_DATA, IO_INDEX_PORT); spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "activated.\n"); return 0; }
int wd8003_open(struct device *dev) { unsigned char cmd; int i; /* we probably don't want to be interrupted here. */ cli(); /* This section of code is mostly copied from the bsd driver which is mostly copied from somewhere else. */ /* The somewhere else is probably the cmwymr(sp?) dos packet driver */ cmd=inb_p(WD_COMM); cmd|=CSTOP; cmd &= ~(CSTART|CPAGE); outb_p(cmd, WD_COMM); outb_p(0, WD_IMR); sti(); outb_p( dconfig,WD_DCR); /*Zero the remote byte count. */ outb_p(0, WD_RBY0); outb_p(0, WD_RBY1); outb_p(WD_MCONFIG,WD_RCC); outb_p(WD_TCONFIG,WD_TRC); outb_p(0,WD_TRPG); /* Set the transmit page start = 0 */ outb_p( max_pages,WD_PSTOP); /* (read) page stop = top of board memory */ outb_p(WD_TXBS,WD_PSTRT); /* (read) page start = cur = bnd = top of tx memory */ outb_p(WD_TXBS,WD_BNDR); /* clear interrupt status. */ outb_p(0xff,WD_ISR); /* we don't want no stinking interrupts. */ outb_p(0 ,WD_IMR); cmd|=1<<CPAGE_SHIFT; outb_p(cmd,WD_COMM); /* set the ether address. */ for (i=0; i < ETHER_ADDR_LEN; i++) { outb_p(dev->dev_addr[i],WD_PAR0+i); } /* National recommends setting the boundry < current page register */ outb_p(WD_TXBS+1,WD_CUR); /* Set the current page = page start + 1 */ /* set the multicast address. */ for (i=0; i < ETHER_ADDR_LEN; i++) { outb_p(dev->broadcast[i],WD_MAR0+i); } cmd&=~(CPAGE|CRDMA); cmd|= 4<<CRDMA_SHIFT; outb_p(cmd, WD_COMM); outb_p(WD_RCONFIG,WD_RCC); wd_start(dev); return (0); }
/* Another internally used function */ static int vt596_transaction(void) { int temp; int result = 0; int timeout = 0; dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp); return -1; } else { dev_dbg(&vt596_adapter.dev, "Successfull!\n"); } } /* start the transaction by setting bit 6 */ outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); /* We will always wait for a fraction of a second! I don't know if VIA needs this, Intel did */ do { msleep(1); temp = inb_p(SMBHSTSTS); } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { result = -1; dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n"); } if (temp & 0x10) { result = -1; dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n"); } if (temp & 0x08) { result = -1; dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be " "locked until next hard\nreset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ } if (temp & 0x04) { result = -1; dev_dbg(&vt596_adapter.dev, "Error: no response!\n"); } if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_warn(&vt596_adapter.dev, "Failed reset at end " "of transaction (%02x)\n", temp); } } dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); return result; }
static void wd_rcv( struct device *dev ) { unsigned char pkt; /* Next packet page start */ unsigned char bnd; /* Last packet page end */ unsigned char cur; /* Future packet page start */ unsigned char cmd; /* Command register save */ volatile struct wd_ring *ring; int done=0; /* Calculate next packet location */ cur = wd_get_cur( dev ); bnd = wd_get_bnd( dev ); if( (pkt = bnd + 1) == max_pages ) pkt = WD_TXBS; while( done != 1) { if (pkt != cur) { /* Position pointer to packet in card ring buffer */ ring = (volatile struct wd_ring *) (dev->mem_start + (pkt << 8)); /* Ensure a valid packet */ if( ring->status & 1 ) { /* Too small and too big packets are filtered by the board */ if( wd_debug ) printk("\nwd8013 - wdget: bnd = %d, pkt = %d, " "cur = %d, status = %d, len = %d, next = %d", bnd, pkt, cur, ring->status, ring->count, ring->next); stats.rx_packets++; /* count all receives */ done = wdget( ring, dev ); /* get the packet */ /* Calculate next packet location */ pkt = ring->next; /* Compute new boundry - tell the chip */ if( (bnd = pkt - 1) < WD_TXBS ) bnd = max_pages - 1; wd_put_bnd(bnd, dev); /* update our copy of cur. */ cur = wd_get_cur(dev); } else { /* Bad packet in ring buffer - should not happen due to hardware filtering */ printk("wd8013 - bad packet: len = %d, status = x%x, " "bnd = %d, pkt = %d, cur = %d\n" "trashing receive buffer!", ring->count, ring->status, bnd, pkt, cur); /* Reset bnd = cur-1 */ if( ( bnd = wd_get_cur( dev ) - 1 ) < WD_TXBS ) bnd = max_pages - 1; wd_put_bnd( bnd, dev ); break; /* return */ } } else { done = dev_rint(NULL, 0,0, dev); } } /* reset to page 0 */ cmd = inb_p(WD_COMM); if (cmd & 0x40) { outb_p(cmd & ~(CPAGE1), WD_COMM); /* select page 0 */ } }
/* Return -1 on error. */ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { int i, len; switch (size) { case I2C_SMBUS_PROC_CALL: dev_info(&vt596_adapter.dev, "I2C_SMBUS_PROC_CALL not supported!\n"); return -1; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); size = VT596_QUICK; break; case I2C_SMBUS_BYTE: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD); size = VT596_BYTE; break; case I2C_SMBUS_BYTE_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) outb_p(data->byte, SMBHSTDAT0); size = VT596_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMBHSTDAT0); outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); } size = VT596_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; if (len < 0) len = 0; if (len > I2C_SMBUS_BLOCK_MAX) len = I2C_SMBUS_BLOCK_MAX; outb_p(len, SMBHSTDAT0); i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= len; i++) outb_p(data->block[i], SMBBLKDAT); } size = VT596_BLOCK_DATA; break; }
static int wdt977_start(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); /* unlock the SuperIO chip */ outb_p(UNLOCK_DATA, IO_INDEX_PORT); outb_p(UNLOCK_DATA, IO_INDEX_PORT); /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4 * F2 has the timeout in minutes * F3 could be set to the POWER LED blink (with GP17 set to PowerLed) * at timeout, and to reset timer on kbd/mouse activity (not impl.) * F4 is used to just clear the TIMEOUT'ed state (bit 0) */ outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); outb_p(0xF2, IO_INDEX_PORT); outb_p(timeoutM, IO_DATA_PORT); outb_p(0xF3, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ outb_p(0xF4, IO_INDEX_PORT); outb_p(0x00, IO_DATA_PORT); /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ /* in test mode watch the bit 1 on F4 to indicate "triggered" */ if (!testmode) { outb_p(DEVICE_REGISTER, IO_INDEX_PORT); outb_p(0x07, IO_DATA_PORT); outb_p(0xE6, IO_INDEX_PORT); outb_p(0x08, IO_DATA_PORT); } /* lock the SuperIO chip */ outb_p(LOCK_DATA, IO_INDEX_PORT); spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "activated.\n"); return 0; }
static void send_1_byte(struct aztech *az) { udelay(radio_wait_time); outb_p(128 + 2 + az->curvol, az->isa.io); outb_p(128 + 64 + 2 + az->curvol, az->isa.io); }
static void WriteByteToHwPort(unsigned long addr, u8 val) { outb_p(val, addr); }
static inline void superio_outb(int addr, int val) { outb_p(addr, superio_cmd); outb_p(val, superio_cmd + 1); }
static int serial8250_startup(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned long flags; int retval; /* * Clear the FIFO buffers and disable them. * (they will be reeanbled in set_termios()) */ if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_outp(up, UART_FCR, 0); } /* * Clear the interrupt registers. */ (void) serial_inp(up, UART_LSR); (void) serial_inp(up, UART_RX); (void) serial_inp(up, UART_IIR); (void) serial_inp(up, UART_MSR); /* * At this point, there's no way the LSR could still be 0xff; * if it is, then bail out, because there's likely no UART * here. */ if (!(up->port.flags & UPF_BUGGY_UART) && (serial_inp(up, UART_LSR) == 0xff)) { printk("ttyS%d: LSR safety check engaged!\n", up->port.line); return -ENODEV; } retval = serial_link_irq_chain(up); if (retval) return retval; /* * Now, initialize the UART */ serial_outp(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { if (!is_real_interrupt(up->port.irq)) up->port.mctrl |= TIOCM_OUT1; } else /* * Most PC uarts need OUT2 raised to enable interrupts. */ if (is_real_interrupt(up->port.irq)) up->port.mctrl |= TIOCM_OUT2; serial8250_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ up->ier = UART_IER_RLSI | UART_IER_RDI; serial_outp(up, UART_IER, up->ier); if (up->port.flags & UPF_FOURPORT) { unsigned int icp; /* * Enable interrupts on the AST Fourport board */ icp = (up->port.iobase & 0xfe0) | 0x01f; outb_p(0x80, icp); (void) inb_p(icp); } /* * And clear the interrupt registers again for luck. */ (void) serial_inp(up, UART_LSR); (void) serial_inp(up, UART_RX); (void) serial_inp(up, UART_IIR); (void) serial_inp(up, UART_MSR); return 0; }
static inline int superio_inb(int addr) { outb_p(addr, superio_cmd); return inb_p(superio_cmd + 1); }
/* * 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 net_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 */ void __iomem *base = ei_status.mem; 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 (base) { /* Shared memory transfer */ memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8), 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--) { pr_notice("%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); }
static void w83697ug_unselect_wd_register(void) { outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ }
static void wdt_ctr_load(int ctr, int val) { outb_p(val&0xFF, WDT_COUNT0+ctr); outb_p(val>>8, WDT_COUNT0+ctr); }
static inline void w83697hf_unlock(void) { outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ outb_p(0x87, W83697HF_EFER); /* Again according to manual */ }