From a4e2b347848bf626b822599329933887dc90e50f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 26 Oct 2005 15:46:52 -0700 Subject: [PATCH] tg3: add 5714/5715 support Add complete support for 5714/5715. These chips are very similar to 5780 so the changes are very trivial. A TG3_FLG2_5780_CLASS flag is added to identify these chips. Signed-off-by: Michael Chan Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 71834f05504f..d6865bbd9ea4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2165,11 +2165,13 @@ #define PCI_DEVICE_ID_TIGON3_5721 0x1659 #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_TIGON3_5714 0x1668 #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 +#define PCI_DEVICE_ID_TIGON3_5715 0x1678 #define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e -- cgit v1.2.3 From 48257c4f168e5d040394aeca4d37b59f68e0d36b Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 28 Oct 2005 16:25:58 -0400 Subject: Add fs_enet ethernet network driver, for several embedded platforms. --- drivers/net/Kconfig | 1 + drivers/net/Makefile | 3 + drivers/net/fs_enet/Kconfig | 20 + drivers/net/fs_enet/Makefile | 10 + drivers/net/fs_enet/fs_enet-main.c | 1226 ++++++++++++++++++++++++++++++++++++ drivers/net/fs_enet/fs_enet-mii.c | 507 +++++++++++++++ drivers/net/fs_enet/fs_enet.h | 245 +++++++ drivers/net/fs_enet/mac-fcc.c | 578 +++++++++++++++++ drivers/net/fs_enet/mac-fec.c | 653 +++++++++++++++++++ drivers/net/fs_enet/mac-scc.c | 524 +++++++++++++++ drivers/net/fs_enet/mii-bitbang.c | 405 ++++++++++++ drivers/net/fs_enet/mii-fixed.c | 92 +++ include/linux/fs_enet_pd.h | 136 ++++ 13 files changed, 4400 insertions(+) create mode 100644 drivers/net/fs_enet/Kconfig create mode 100644 drivers/net/fs_enet/Makefile create mode 100644 drivers/net/fs_enet/fs_enet-main.c create mode 100644 drivers/net/fs_enet/fs_enet-mii.c create mode 100644 drivers/net/fs_enet/fs_enet.h create mode 100644 drivers/net/fs_enet/mac-fcc.c create mode 100644 drivers/net/fs_enet/mac-fec.c create mode 100644 drivers/net/fs_enet/mac-scc.c create mode 100644 drivers/net/fs_enet/mii-bitbang.c create mode 100644 drivers/net/fs_enet/mii-fixed.c create mode 100644 include/linux/fs_enet_pd.h (limited to 'include/linux') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 814a93b8c903..27732fdeeea4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1775,6 +1775,7 @@ config NE_H8300 controller on the Renesas H8/300 processor. source "drivers/net/fec_8xx/Kconfig" +source "drivers/net/fs_enet/Kconfig" endmenu diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1a84e0435f64..7c313cb341b8 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -203,3 +203,6 @@ obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_NETCONSOLE) += netconsole.o + +obj-$(CONFIG_FS_ENET) += fs_enet/ + diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig new file mode 100644 index 000000000000..6aaee67dd4b7 --- /dev/null +++ b/drivers/net/fs_enet/Kconfig @@ -0,0 +1,20 @@ +config FS_ENET + tristate "Freescale Ethernet Driver" + depends on NET_ETHERNET && (CPM1 || CPM2) + select MII + +config FS_ENET_HAS_SCC + bool "Chip has an SCC usable for ethernet" + depends on FS_ENET && (CPM1 || CPM2) + default y + +config FS_ENET_HAS_FCC + bool "Chip has an FCC usable for ethernet" + depends on FS_ENET && CPM2 + default y + +config FS_ENET_HAS_FEC + bool "Chip has an FEC usable for ethernet" + depends on FS_ENET && CPM1 + default y + diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile new file mode 100644 index 000000000000..d6dd3f2fb43e --- /dev/null +++ b/drivers/net/fs_enet/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the Freescale Ethernet controllers +# + +obj-$(CONFIG_FS_ENET) += fs_enet.o + +obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o +obj-$(CONFIG_8260) += mac-fcc.o + +fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c new file mode 100644 index 000000000000..44fac7373289 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -0,0 +1,1226 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * Heavily based on original FEC driver by Dan Malek + * and modifications by Joakim Tjernlund + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; + +MODULE_AUTHOR("Pantelis Antoniou "); +MODULE_DESCRIPTION("Freescale Ethernet Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +MODULE_PARM(fs_enet_debug, "i"); +MODULE_PARM_DESC(fs_enet_debug, + "Freescale bitmapped debugging message enable value"); + +int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */ + +static void fs_set_multicast_list(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + (*fep->ops->set_multicast_list)(dev); +} + +/* NAPI receive function */ +static int fs_enet_rx_napi(struct net_device *dev, int *budget) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + cbd_t *bdp; + struct sk_buff *skb, *skbn, *skbt; + int received = 0; + u16 pkt_len, sc; + int curidx; + int rx_work_limit = 0; /* pacify gcc */ + + rx_work_limit = min(dev->quota, *budget); + + if (!netif_running(dev)) + return 0; + + /* + * First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. + */ + bdp = fep->cur_rx; + + /* clear RX status bits for napi*/ + (*fep->ops->napi_clear_rx_event)(dev); + + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { + + curidx = bdp - fep->rx_bd_base; + + /* + * Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ + if ((sc & BD_ENET_RX_LAST) == 0) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s rcv is not +last\n", + dev->name); + + /* + * Check for errors. + */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { + fep->stats.rx_errors++; + /* Frame too long or too short. */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) + fep->stats.rx_length_errors++; + /* Frame alignment */ + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) + fep->stats.rx_frame_errors++; + /* CRC Error */ + if (sc & BD_ENET_RX_CR) + fep->stats.rx_crc_errors++; + /* FIFO overrun */ + if (sc & BD_ENET_RX_OV) + fep->stats.rx_crc_errors++; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + skbn = skb; + + } else { + + /* napi, got packet but no quota */ + if (--rx_work_limit < 0) + break; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + /* + * Process the incoming frame. + */ + fep->stats.rx_packets++; + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ + fep->stats.rx_bytes += pkt_len + 4; + + if (pkt_len <= fpi->rx_copybreak) { + /* +2 to make IP header L1 cache aligned */ + skbn = dev_alloc_skb(pkt_len + 2); + if (skbn != NULL) { + skb_reserve(skbn, 2); /* align IP header */ + memcpy(skbn->data, skb->data, pkt_len); + /* swap */ + skbt = skb; + skb = skbn; + skbn = skbt; + } + } else + skbn = dev_alloc_skb(ENET_RX_FRSIZE); + + if (skbn != NULL) { + skb->dev = dev; + skb_put(skb, pkt_len); /* Make room */ + skb->protocol = eth_type_trans(skb, dev); + received++; + netif_receive_skb(skb); + } else { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, dropping packet.\n", + dev->name); + fep->stats.rx_dropped++; + skbn = skb; + } + } + + fep->rx_skbuff[curidx] = skbn; + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); + + /* + * Update BD pointer to next entry. + */ + if ((sc & BD_ENET_RX_WRAP) == 0) + bdp++; + else + bdp = fep->rx_bd_base; + + (*fep->ops->rx_bd_done)(dev); + } + + fep->cur_rx = bdp; + + dev->quota -= received; + *budget -= received; + + if (rx_work_limit < 0) + return 1; /* not done */ + + /* done */ + netif_rx_complete(dev); + + (*fep->ops->napi_enable_rx)(dev); + + return 0; +} + +/* non NAPI receive function */ +static int fs_enet_rx_non_napi(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + cbd_t *bdp; + struct sk_buff *skb, *skbn, *skbt; + int received = 0; + u16 pkt_len, sc; + int curidx; + /* + * First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. + */ + bdp = fep->cur_rx; + + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { + + curidx = bdp - fep->rx_bd_base; + + /* + * Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ + if ((sc & BD_ENET_RX_LAST) == 0) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s rcv is not +last\n", + dev->name); + + /* + * Check for errors. + */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { + fep->stats.rx_errors++; + /* Frame too long or too short. */ + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) + fep->stats.rx_length_errors++; + /* Frame alignment */ + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) + fep->stats.rx_frame_errors++; + /* CRC Error */ + if (sc & BD_ENET_RX_CR) + fep->stats.rx_crc_errors++; + /* FIFO overrun */ + if (sc & BD_ENET_RX_OV) + fep->stats.rx_crc_errors++; + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + skbn = skb; + + } else { + + skb = fep->rx_skbuff[curidx]; + + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + /* + * Process the incoming frame. + */ + fep->stats.rx_packets++; + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ + fep->stats.rx_bytes += pkt_len + 4; + + if (pkt_len <= fpi->rx_copybreak) { + /* +2 to make IP header L1 cache aligned */ + skbn = dev_alloc_skb(pkt_len + 2); + if (skbn != NULL) { + skb_reserve(skbn, 2); /* align IP header */ + memcpy(skbn->data, skb->data, pkt_len); + /* swap */ + skbt = skb; + skb = skbn; + skbn = skbt; + } + } else + skbn = dev_alloc_skb(ENET_RX_FRSIZE); + + if (skbn != NULL) { + skb->dev = dev; + skb_put(skb, pkt_len); /* Make room */ + skb->protocol = eth_type_trans(skb, dev); + received++; + netif_rx(skb); + } else { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, dropping packet.\n", + dev->name); + fep->stats.rx_dropped++; + skbn = skb; + } + } + + fep->rx_skbuff[curidx] = skbn; + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); + + /* + * Update BD pointer to next entry. + */ + if ((sc & BD_ENET_RX_WRAP) == 0) + bdp++; + else + bdp = fep->rx_bd_base; + + (*fep->ops->rx_bd_done)(dev); + } + + fep->cur_rx = bdp; + + return 0; +} + +static void fs_enet_tx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + struct sk_buff *skb; + int dirtyidx, do_wake, do_restart; + u16 sc; + + spin_lock(&fep->lock); + bdp = fep->dirty_tx; + + do_wake = do_restart = 0; + while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { + + dirtyidx = bdp - fep->tx_bd_base; + + if (fep->tx_free == fep->tx_ring) + break; + + skb = fep->tx_skbuff[dirtyidx]; + + /* + * Check for errors. + */ + if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | + BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { + + if (sc & BD_ENET_TX_HB) /* No heartbeat */ + fep->stats.tx_heartbeat_errors++; + if (sc & BD_ENET_TX_LC) /* Late collision */ + fep->stats.tx_window_errors++; + if (sc & BD_ENET_TX_RL) /* Retrans limit */ + fep->stats.tx_aborted_errors++; + if (sc & BD_ENET_TX_UN) /* Underrun */ + fep->stats.tx_fifo_errors++; + if (sc & BD_ENET_TX_CSL) /* Carrier lost */ + fep->stats.tx_carrier_errors++; + + if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { + fep->stats.tx_errors++; + do_restart = 1; + } + } else + fep->stats.tx_packets++; + + if (sc & BD_ENET_TX_READY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s HEY! Enet xmit interrupt and TX_READY.\n", + dev->name); + + /* + * Deferred means some collisions occurred during transmit, + * but we eventually sent the packet OK. + */ + if (sc & BD_ENET_TX_DEF) + fep->stats.collisions++; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); + + /* + * Free the sk buffer associated with this last transmit. + */ + dev_kfree_skb_irq(skb); + fep->tx_skbuff[dirtyidx] = NULL; + + /* + * Update pointer to next buffer descriptor to be transmitted. + */ + if ((sc & BD_ENET_TX_WRAP) == 0) + bdp++; + else + bdp = fep->tx_bd_base; + + /* + * Since we have freed up a buffer, the ring is no longer + * full. + */ + if (!fep->tx_free++) + do_wake = 1; + } + + fep->dirty_tx = bdp; + + if (do_restart) + (*fep->ops->tx_restart)(dev); + + spin_unlock(&fep->lock); + + if (do_wake) + netif_wake_queue(dev); +} + +/* + * The interrupt handler. + * This is called from the MPC core interrupt. + */ +static irqreturn_t +fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + u32 int_events; + u32 int_clr_events; + int nr, napi_ok; + int handled; + + fep = netdev_priv(dev); + fpi = fep->fpi; + + nr = 0; + while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) { + + nr++; + + int_clr_events = int_events; + if (fpi->use_napi) + int_clr_events &= ~fep->ev_napi_rx; + + (*fep->ops->clear_int_events)(dev, int_clr_events); + + if (int_events & fep->ev_err) + (*fep->ops->ev_error)(dev, int_events); + + if (int_events & fep->ev_rx) { + if (!fpi->use_napi) + fs_enet_rx_non_napi(dev); + else { + napi_ok = netif_rx_schedule_prep(dev); + + (*fep->ops->napi_disable_rx)(dev); + (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx); + + /* NOTE: it is possible for FCCs in NAPI mode */ + /* to submit a spurious interrupt while in poll */ + if (napi_ok) + __netif_rx_schedule(dev); + } + } + + if (int_events & fep->ev_tx) + fs_enet_tx(dev); + } + + handled = nr > 0; + return IRQ_RETVAL(handled); +} + +void fs_init_bds(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + struct sk_buff *skb; + int i; + + fs_cleanup_bds(dev); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->tx_free = fep->tx_ring; + fep->cur_rx = fep->rx_bd_base; + + /* + * Initialize the receive buffer descriptors. + */ + for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { + skb = dev_alloc_skb(ENET_RX_FRSIZE); + if (skb == NULL) { + printk(KERN_WARNING DRV_MODULE_NAME + ": %s Memory squeeze, unable to allocate skb\n", + dev->name); + break; + } + fep->rx_skbuff[i] = skb; + skb->dev = dev; + CBDW_BUFADDR(bdp, + dma_map_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE)); + CBDW_DATLEN(bdp, 0); /* zero */ + CBDW_SC(bdp, BD_ENET_RX_EMPTY | + ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); + } + /* + * if we failed, fillup remainder + */ + for (; i < fep->rx_ring; i++, bdp++) { + fep->rx_skbuff[i] = NULL; + CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); + } + + /* + * ...and the same for transmit. + */ + for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { + fep->tx_skbuff[i] = NULL; + CBDW_BUFADDR(bdp, 0); + CBDW_DATLEN(bdp, 0); + CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); + } +} + +void fs_cleanup_bds(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct sk_buff *skb; + int i; + + /* + * Reset SKB transmit buffers. + */ + for (i = 0; i < fep->tx_ring; i++) { + if ((skb = fep->tx_skbuff[i]) == NULL) + continue; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); + + fep->tx_skbuff[i] = NULL; + dev_kfree_skb(skb); + } + + /* + * Reset SKB receive buffers + */ + for (i = 0; i < fep->rx_ring; i++) { + if ((skb = fep->rx_skbuff[i]) == NULL) + continue; + + /* unmap */ + dma_unmap_single(fep->dev, skb->data, + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), + DMA_FROM_DEVICE); + + fep->rx_skbuff[i] = NULL; + + dev_kfree_skb(skb); + } +} + +/**********************************************************************************/ + +static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + int curidx; + u16 sc; + unsigned long flags; + + spin_lock_irqsave(&fep->tx_lock, flags); + + /* + * Fill in a Tx ring entry + */ + bdp = fep->cur_tx; + + if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { + netif_stop_queue(dev); + spin_unlock_irqrestore(&fep->tx_lock, flags); + + /* + * Ooops. All transmit buffers are full. Bail out. + * This should not happen, since the tx queue should be stopped. + */ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s tx queue full!.\n", dev->name); + return NETDEV_TX_BUSY; + } + + curidx = bdp - fep->tx_bd_base; + /* + * Clear all of the status flags. + */ + CBDC_SC(bdp, BD_ENET_TX_STATS); + + /* + * Save skb pointer. + */ + fep->tx_skbuff[curidx] = skb; + + fep->stats.tx_bytes += skb->len; + + /* + * Push the data cache so the CPM does not get stale memory data. + */ + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, + skb->data, skb->len, DMA_TO_DEVICE)); + CBDW_DATLEN(bdp, skb->len); + + dev->trans_start = jiffies; + + /* + * If this was the last BD in the ring, start at the beginning again. + */ + if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) + fep->cur_tx++; + else + fep->cur_tx = fep->tx_bd_base; + + if (!--fep->tx_free) + netif_stop_queue(dev); + + /* Trigger transmission start */ + sc = BD_ENET_TX_READY | BD_ENET_TX_INTR | + BD_ENET_TX_LAST | BD_ENET_TX_TC; + + /* note that while FEC does not have this bit + * it marks it as available for software use + * yay for hw reuse :) */ + if (skb->len <= 60) + sc |= BD_ENET_TX_PAD; + CBDS_SC(bdp, sc); + + (*fep->ops->tx_kickstart)(dev); + + spin_unlock_irqrestore(&fep->tx_lock, flags); + + return NETDEV_TX_OK; +} + +static int fs_request_irq(struct net_device *dev, int irq, const char *name, + irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs)) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + (*fep->ops->pre_request_irq)(dev, irq); + return request_irq(irq, irqf, SA_SHIRQ, name, dev); +} + +static void fs_free_irq(struct net_device *dev, int irq) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + free_irq(irq, dev); + (*fep->ops->post_free_irq)(dev, irq); +} + +/**********************************************************************************/ + +/* This interrupt occurs when the PHY detects a link change. */ +static irqreturn_t +fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + + fep = netdev_priv(dev); + fpi = fep->fpi; + + /* + * Acknowledge the interrupt if possible. If we have not + * found the PHY yet we can't process or acknowledge the + * interrupt now. Instead we ignore this interrupt for now, + * which we can do since it is edge triggered. It will be + * acknowledged later by fs_enet_open(). + */ + if (!fep->phy) + return IRQ_NONE; + + fs_mii_ack_int(dev); + fs_mii_link_status_change_check(dev, 0); + + return IRQ_HANDLED; +} + +static void fs_timeout(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int wake = 0; + + fep->stats.tx_errors++; + + spin_lock_irqsave(&fep->lock, flags); + + if (dev->flags & IFF_UP) { + (*fep->ops->stop)(dev); + (*fep->ops->restart)(dev); + } + + wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY); + spin_unlock_irqrestore(&fep->lock, flags); + + if (wake) + netif_wake_queue(dev); +} + +static int fs_enet_open(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + int r; + + /* Install our interrupt handler. */ + r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s Could not allocate FEC IRQ!", dev->name); + return -EINVAL; + } + + /* Install our phy interrupt handler */ + if (fpi->phy_irq != -1) { + + r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s Could not allocate PHY IRQ!", dev->name); + fs_free_irq(dev, fep->interrupt); + return -EINVAL; + } + } + + fs_mii_startup(dev); + netif_carrier_off(dev); + fs_mii_link_status_change_check(dev, 1); + + return 0; +} + +static int fs_enet_close(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + unsigned long flags; + + netif_stop_queue(dev); + netif_carrier_off(dev); + fs_mii_shutdown(dev); + + spin_lock_irqsave(&fep->lock, flags); + (*fep->ops->stop)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + + /* release any irqs */ + if (fpi->phy_irq != -1) + fs_free_irq(dev, fpi->phy_irq); + fs_free_irq(dev, fep->interrupt); + + return 0; +} + +static struct net_device_stats *fs_enet_get_stats(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return &fep->stats; +} + +/*************************************************************************/ + +static void fs_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); +} + +static int fs_get_regs_len(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + return (*fep->ops->get_regs_len)(dev); +} + +static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int r, len; + + len = regs->len; + + spin_lock_irqsave(&fep->lock, flags); + r = (*fep->ops->get_regs)(dev, p, &len); + spin_unlock_irqrestore(&fep->lock, flags); + + if (r == 0) + regs->version = 0; +} + +static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_gset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; +} + +static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_sset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; +} + +static int fs_nway_reset(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return mii_nway_restart(&fep->mii_if); +} + +static u32 fs_get_msglevel(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + return fep->msg_enable; +} + +static void fs_set_msglevel(struct net_device *dev, u32 value) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fep->msg_enable = value; +} + +static struct ethtool_ops fs_ethtool_ops = { + .get_drvinfo = fs_get_drvinfo, + .get_regs_len = fs_get_regs_len, + .get_settings = fs_get_settings, + .set_settings = fs_set_settings, + .nway_reset = fs_nway_reset, + .get_link = ethtool_op_get_link, + .get_msglevel = fs_get_msglevel, + .set_msglevel = fs_set_msglevel, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_regs = fs_get_regs, +}; + +static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; + unsigned long flags; + int rc; + + if (!netif_running(dev)) + return -EINVAL; + + spin_lock_irqsave(&fep->lock, flags); + rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); + spin_unlock_irqrestore(&fep->lock, flags); + return rc; +} + +extern int fs_mii_connect(struct net_device *dev); +extern void fs_mii_disconnect(struct net_device *dev); + +static struct net_device *fs_init_instance(struct device *dev, + const struct fs_platform_info *fpi) +{ + struct net_device *ndev = NULL; + struct fs_enet_private *fep = NULL; + int privsize, i, r, err = 0, registered = 0; + + /* guard */ + if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) + return ERR_PTR(-EINVAL); + + privsize = sizeof(*fep) + (sizeof(struct sk_buff **) * + (fpi->rx_ring + fpi->tx_ring)); + + ndev = alloc_etherdev(privsize); + if (!ndev) { + err = -ENOMEM; + goto err; + } + SET_MODULE_OWNER(ndev); + + fep = netdev_priv(ndev); + memset(fep, 0, privsize); /* clear everything */ + + fep->dev = dev; + dev_set_drvdata(dev, ndev); + fep->fpi = fpi; + if (fpi->init_ioports) + fpi->init_ioports(); + +#ifdef CONFIG_FS_ENET_HAS_FEC + if (fs_get_fec_index(fpi->fs_no) >= 0) + fep->ops = &fs_fec_ops; +#endif + +#ifdef CONFIG_FS_ENET_HAS_SCC + if (fs_get_scc_index(fpi->fs_no) >=0 ) + fep->ops = &fs_scc_ops; +#endif + +#ifdef CONFIG_FS_ENET_HAS_FCC + if (fs_get_fcc_index(fpi->fs_no) >= 0) + fep->ops = &fs_fcc_ops; +#endif + + if (fep->ops == NULL) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s No matching ops found (%d).\n", + ndev->name, fpi->fs_no); + err = -EINVAL; + goto err; + } + + r = (*fep->ops->setup_data)(ndev); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s setup_data failed\n", + ndev->name); + err = r; + goto err; + } + + /* point rx_skbuff, tx_skbuff */ + fep->rx_skbuff = (struct sk_buff **)&fep[1]; + fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; + + /* init locks */ + spin_lock_init(&fep->lock); + spin_lock_init(&fep->tx_lock); + + /* + * Set the Ethernet address. + */ + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = fpi->macaddr[i]; + + r = (*fep->ops->allocate_bd)(ndev); + + if (fep->ring_base == NULL) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r); + err = r; + goto err; + } + + /* + * Set receive and transmit descriptor base. + */ + fep->rx_bd_base = fep->ring_base; + fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; + + /* initialize ring size variables */ + fep->tx_ring = fpi->tx_ring; + fep->rx_ring = fpi->rx_ring; + + /* + * The FEC Ethernet specific entries in the device structure. + */ + ndev->open = fs_enet_open; + ndev->hard_start_xmit = fs_enet_start_xmit; + ndev->tx_timeout = fs_timeout; + ndev->watchdog_timeo = 2 * HZ; + ndev->stop = fs_enet_close; + ndev->get_stats = fs_enet_get_stats; + ndev->set_multicast_list = fs_set_multicast_list; + if (fpi->use_napi) { + ndev->poll = fs_enet_rx_napi; + ndev->weight = fpi->napi_weight; + } + ndev->ethtool_ops = &fs_ethtool_ops; + ndev->do_ioctl = fs_ioctl; + + init_timer(&fep->phy_timer_list); + + netif_carrier_off(ndev); + + err = register_netdev(ndev); + if (err != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s register_netdev failed.\n", ndev->name); + goto err; + } + registered = 1; + + err = fs_mii_connect(ndev); + if (err != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s fs_mii_connect failed.\n", ndev->name); + goto err; + } + + return ndev; + + err: + if (ndev != NULL) { + + if (registered) + unregister_netdev(ndev); + + if (fep != NULL) { + (*fep->ops->free_bd)(ndev); + (*fep->ops->cleanup_data)(ndev); + } + + free_netdev(ndev); + } + + dev_set_drvdata(dev, NULL); + + return ERR_PTR(err); +} + +static int fs_cleanup_instance(struct net_device *ndev) +{ + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + struct device *dev; + + if (ndev == NULL) + return -EINVAL; + + fep = netdev_priv(ndev); + if (fep == NULL) + return -EINVAL; + + fpi = fep->fpi; + + fs_mii_disconnect(ndev); + + unregister_netdev(ndev); + + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), + fep->ring_base, fep->ring_mem_addr); + + /* reset it */ + (*fep->ops->cleanup_data)(ndev); + + dev = fep->dev; + if (dev != NULL) { + dev_set_drvdata(dev, NULL); + fep->dev = NULL; + } + + free_netdev(ndev); + + return 0; +} + +/**************************************************************************************/ + +/* handy pointer to the immap */ +void *fs_enet_immap = NULL; + +static int setup_immap(void) +{ + phys_addr_t paddr = 0; + unsigned long size = 0; + +#ifdef CONFIG_CPM1 + paddr = IMAP_ADDR; + size = 0x10000; /* map 64K */ +#endif + +#ifdef CONFIG_CPM2 + paddr = CPM_MAP_ADDR; + size = 0x40000; /* map 256 K */ +#endif + fs_enet_immap = ioremap(paddr, size); + if (fs_enet_immap == NULL) + return -EBADF; /* XXX ahem; maybe just BUG_ON? */ + + return 0; +} + +static void cleanup_immap(void) +{ + if (fs_enet_immap != NULL) { + iounmap(fs_enet_immap); + fs_enet_immap = NULL; + } +} + +/**************************************************************************************/ + +static int __devinit fs_enet_probe(struct device *dev) +{ + struct net_device *ndev; + + /* no fixup - no device */ + if (dev->platform_data == NULL) { + printk(KERN_INFO "fs_enet: " + "probe called with no platform data; " + "remove unused devices\n"); + return -ENODEV; + } + + ndev = fs_init_instance(dev, dev->platform_data); + if (IS_ERR(ndev)) + return PTR_ERR(ndev); + return 0; +} + +static int fs_enet_remove(struct device *dev) +{ + return fs_cleanup_instance(dev_get_drvdata(dev)); +} + +static struct device_driver fs_enet_fec_driver = { + .name = "fsl-cpm-fec", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static struct device_driver fs_enet_scc_driver = { + .name = "fsl-cpm-scc", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static struct device_driver fs_enet_fcc_driver = { + .name = "fsl-cpm-fcc", + .bus = &platform_bus_type, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +#ifdef CONFIG_PM +/* .suspend = fs_enet_suspend, TODO */ +/* .resume = fs_enet_resume, TODO */ +#endif +}; + +static int __init fs_init(void) +{ + int r; + + printk(KERN_INFO + "%s", version); + + r = setup_immap(); + if (r != 0) + return r; + r = driver_register(&fs_enet_fec_driver); + if (r != 0) + goto err; + + r = driver_register(&fs_enet_fcc_driver); + if (r != 0) + goto err; + + r = driver_register(&fs_enet_scc_driver); + if (r != 0) + goto err; + + return 0; +err: + cleanup_immap(); + return r; + +} + +static void __exit fs_cleanup(void) +{ + driver_unregister(&fs_enet_fec_driver); + driver_unregister(&fs_enet_fcc_driver); + driver_unregister(&fs_enet_scc_driver); + cleanup_immap(); +} + +/**************************************************************************************/ + +module_init(fs_init); +module_exit(fs_cleanup); diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c new file mode 100644 index 000000000000..c6770377ef87 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet-mii.c @@ -0,0 +1,507 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * Heavily based on original FEC driver by Dan Malek + * and modifications by Joakim Tjernlund + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +/* + * Generic PHY support. + * Should work for all PHYs, but link change is detected by polling + */ + +static void generic_timer_callback(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; + + add_timer(&fep->phy_timer_list); + + fs_mii_link_status_change_check(dev, 0); +} + +static void generic_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ + fep->phy_timer_list.data = (unsigned long)dev; + fep->phy_timer_list.function = generic_timer_callback; + add_timer(&fep->phy_timer_list); +} + +static void generic_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + del_timer_sync(&fep->phy_timer_list); +} + +/* ------------------------------------------------------------------------- */ +/* The Davicom DM9161 is used on the NETTA board */ + +/* register definitions */ + +#define MII_DM9161_ANAR 4 /* Aux. Config Register */ +#define MII_DM9161_ACR 16 /* Aux. Config Register */ +#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ +#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ +#define MII_DM9161_INTR 21 /* Interrupt Register */ +#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ +#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ + +static void dm9161_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); + /* Start autonegotiation */ + fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ*8); +} + +static void dm9161_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); +} + +static void dm9161_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); +} + +/**********************************************************************************/ + +static const struct phy_info phy_info[] = { + { + .id = 0x00181b88, + .name = "DM9161", + .startup = dm9161_startup, + .ack_int = dm9161_ack_int, + .shutdown = dm9161_shutdown, + }, { + .id = 0, + .name = "GENERIC", + .startup = generic_startup, + .shutdown = generic_shutdown, + }, +}; + +/**********************************************************************************/ + +static int phy_id_detect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = fep->mii_bus; + int i, r, start, end, phytype, physubtype; + const struct phy_info *phy; + int phy_hwid, phy_id; + + phy_hwid = -1; + fep->phy = NULL; + + /* auto-detect? */ + if (fpi->phy_addr == -1) { + start = 1; + end = 32; + } else { /* direct */ + start = fpi->phy_addr; + end = start + 1; + } + + for (phy_id = start; phy_id < end; phy_id++) { + /* skip already used phy addresses on this bus */ + if (bus->usage_map & (1 << phy_id)) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID1); + if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID2); + if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) + continue; + phy_hwid = (phytype << 16) | physubtype; + if (phy_hwid != -1) + break; + } + + if (phy_hwid == -1) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s No PHY detected! range=0x%02x-0x%02x\n", + dev->name, start, end); + return -1; + } + + for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) + if (phy->id == (phy_hwid >> 4) || phy->id == 0) + break; + + if (i >= ARRAY_SIZE(phy_info)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s PHY id 0x%08x is not supported!\n", + dev->name, phy_hwid); + return -1; + } + + fep->phy = phy; + + /* mark this address as used */ + bus->usage_map |= (1 << phy_id); + + printk(KERN_INFO DRV_MODULE_NAME + ": %s Phy @ 0x%x, type %s (0x%08x)%s\n", + dev->name, phy_id, fep->phy->name, phy_hwid, + fpi->phy_addr == -1 ? " (auto-detected)" : ""); + + return phy_id; +} + +void fs_mii_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->startup) + (*fep->phy->startup) (dev); +} + +void fs_mii_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->shutdown) + (*fep->phy->shutdown) (dev); +} + +void fs_mii_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->ack_int) + (*fep->phy->ack_int) (dev); +} + +#define MII_LINK 0x0001 +#define MII_HALF 0x0002 +#define MII_FULL 0x0004 +#define MII_BASE4 0x0008 +#define MII_10M 0x0010 +#define MII_100M 0x0020 +#define MII_1G 0x0040 +#define MII_10G 0x0080 + +/* return full mii info at one gulp, with a usable form */ +static unsigned int mii_full_status(struct mii_if_info *mii) +{ + unsigned int status; + int bmsr, adv, lpa, neg; + struct fs_enet_private* fep = netdev_priv(mii->dev); + + /* first, a dummy read, needed to latch some MII phys */ + (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + + /* no link */ + if ((bmsr & BMSR_LSTATUS) == 0) + return 0; + + status = MII_LINK; + + /* Lets look what ANEG says if it's supported - otherwize we shall + take the right values from the platform info*/ + if(!mii->force_media) { + /* autoneg not completed; don't bother */ + if ((bmsr & BMSR_ANEGCOMPLETE) == 0) + return 0; + + adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE); + lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA); + + neg = lpa & adv; + } else { + neg = fep->fpi->bus_info->lpa; + } + + if (neg & LPA_100FULL) + status |= MII_FULL | MII_100M; + else if (neg & LPA_100BASE4) + status |= MII_FULL | MII_BASE4 | MII_100M; + else if (neg & LPA_100HALF) + status |= MII_HALF | MII_100M; + else if (neg & LPA_10FULL) + status |= MII_FULL | MII_10M; + else + status |= MII_HALF | MII_10M; + + return status; +} + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct mii_if_info *mii = &fep->mii_if; + unsigned int mii_status; + int ok_to_print, link, duplex, speed; + unsigned long flags; + + ok_to_print = netif_msg_link(fep); + + mii_status = mii_full_status(mii); + + if (!init_media && mii_status == fep->last_mii_status) + return; + + fep->last_mii_status = mii_status; + + link = !!(mii_status & MII_LINK); + duplex = !!(mii_status & MII_FULL); + speed = (mii_status & MII_100M) ? 100 : 10; + + if (link == 0) { + netif_carrier_off(mii->dev); + netif_stop_queue(dev); + if (!init_media) { + spin_lock_irqsave(&fep->lock, flags); + (*fep->ops->stop)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + } + + if (ok_to_print) + printk(KERN_INFO "%s: link down\n", mii->dev->name); + + } else { + + mii->full_duplex = duplex; + + netif_carrier_on(mii->dev); + + spin_lock_irqsave(&fep->lock, flags); + fep->duplex = duplex; + fep->speed = speed; + (*fep->ops->restart)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + + netif_start_queue(dev); + + if (ok_to_print) + printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n", + dev->name, speed, duplex ? "full" : "half"); + } +} + +/**********************************************************************************/ + +int fs_mii_read(struct net_device *dev, int phy_id, int location) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + + unsigned long flags; + int ret; + + spin_lock_irqsave(&bus->mii_lock, flags); + ret = (*bus->mii_read)(bus, phy_id, location); + spin_unlock_irqrestore(&bus->mii_lock, flags); + + return ret; +} + +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + unsigned long flags; + + spin_lock_irqsave(&bus->mii_lock, flags); + (*bus->mii_write)(bus, phy_id, location, value); + spin_unlock_irqrestore(&bus->mii_lock, flags); +} + +/*****************************************************************************/ + +/* list of all registered mii buses */ +static LIST_HEAD(fs_mii_bus_list); + +static struct fs_enet_mii_bus *lookup_bus(int method, int id) +{ + struct list_head *ptr; + struct fs_enet_mii_bus *bus; + + list_for_each(ptr, &fs_mii_bus_list) { + bus = list_entry(ptr, struct fs_enet_mii_bus, list); + if (bus->bus_info->method == method && + bus->bus_info->id == id) + return bus; + } + return NULL; +} + +static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) +{ + struct fs_enet_mii_bus *bus; + int ret = 0; + + bus = kmalloc(sizeof(*bus), GFP_KERNEL); + if (bus == NULL) { + ret = -ENOMEM; + goto err; + } + memset(bus, 0, sizeof(*bus)); + spin_lock_init(&bus->mii_lock); + bus->bus_info = bi; + bus->refs = 0; + bus->usage_map = 0; + + /* perform initialization */ + switch (bi->method) { + + case fsmii_fixed: + ret = fs_mii_fixed_init(bus); + if (ret != 0) + goto err; + break; + + case fsmii_bitbang: + ret = fs_mii_bitbang_init(bus); + if (ret != 0) + goto err; + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + ret = fs_mii_fec_init(bus); + if (ret != 0) + goto err; + break; +#endif + default: + ret = -EINVAL; + goto err; + } + + list_add(&bus->list, &fs_mii_bus_list); + + return bus; + +err: + if (bus) + kfree(bus); + return ERR_PTR(ret); +} + +static void destroy_bus(struct fs_enet_mii_bus *bus) +{ + /* remove from bus list */ + list_del(&bus->list); + + /* nothing more needed */ + kfree(bus); +} + +int fs_mii_connect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = NULL; + + /* check method validity */ + switch (fpi->bus_info->method) { + case fsmii_fixed: + case fsmii_bitbang: + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + break; +#endif + default: + printk(KERN_ERR DRV_MODULE_NAME + ": %s Unknown MII bus method (%d)!\n", + dev->name, fpi->bus_info->method); + return -EINVAL; + } + + bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id); + + /* if not found create new bus */ + if (bus == NULL) { + bus = create_bus(fpi->bus_info); + if (IS_ERR(bus)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s MII bus creation failure!\n", dev->name); + return PTR_ERR(bus); + } + } + + bus->refs++; + + fep->mii_bus = bus; + + fep->mii_if.dev = dev; + fep->mii_if.phy_id_mask = 0x1f; + fep->mii_if.reg_num_mask = 0x1f; + fep->mii_if.mdio_read = fs_mii_read; + fep->mii_if.mdio_write = fs_mii_write; + fep->mii_if.force_media = fpi->bus_info->disable_aneg; + fep->mii_if.phy_id = phy_id_detect(dev); + + return 0; +} + +void fs_mii_disconnect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = NULL; + + bus = fep->mii_bus; + fep->mii_bus = NULL; + + if (--bus->refs <= 0) + destroy_bus(bus); +} diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h new file mode 100644 index 000000000000..1105543b9d88 --- /dev/null +++ b/drivers/net/fs_enet/fs_enet.h @@ -0,0 +1,245 @@ +#ifndef FS_ENET_H +#define FS_ENET_H + +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef CONFIG_CPM1 +#include +#endif + +#ifdef CONFIG_CPM2 +#include +#endif + +/* hw driver ops */ +struct fs_ops { + int (*setup_data)(struct net_device *dev); + int (*allocate_bd)(struct net_device *dev); + void (*free_bd)(struct net_device *dev); + void (*cleanup_data)(struct net_device *dev); + void (*set_multicast_list)(struct net_device *dev); + void (*restart)(struct net_device *dev); + void (*stop)(struct net_device *dev); + void (*pre_request_irq)(struct net_device *dev, int irq); + void (*post_free_irq)(struct net_device *dev, int irq); + void (*napi_clear_rx_event)(struct net_device *dev); + void (*napi_enable_rx)(struct net_device *dev); + void (*napi_disable_rx)(struct net_device *dev); + void (*rx_bd_done)(struct net_device *dev); + void (*tx_kickstart)(struct net_device *dev); + u32 (*get_int_events)(struct net_device *dev); + void (*clear_int_events)(struct net_device *dev, u32 int_events); + void (*ev_error)(struct net_device *dev, u32 int_events); + int (*get_regs)(struct net_device *dev, void *p, int *sizep); + int (*get_regs_len)(struct net_device *dev); + void (*tx_restart)(struct net_device *dev); +}; + +struct phy_info { + unsigned int id; + const char *name; + void (*startup) (struct net_device * dev); + void (*shutdown) (struct net_device * dev); + void (*ack_int) (struct net_device * dev); +}; + +/* The FEC stores dest/src/type, data, and checksum for receive packets. + */ +#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ +#define MIN_MTU 46 /* this is data size */ +#define CRC_LEN 4 + +#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) +#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) + +/* Must be a multiple of 32 (to cover both FEC & FCC) */ +#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31) +/* This is needed so that invalidate_xxx wont invalidate too much */ +#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) + +struct fs_enet_mii_bus { + struct list_head list; + spinlock_t mii_lock; + const struct fs_mii_bus_info *bus_info; + int refs; + u32 usage_map; + + int (*mii_read)(struct fs_enet_mii_bus *bus, + int phy_id, int location); + + void (*mii_write)(struct fs_enet_mii_bus *bus, + int phy_id, int location, int value); + + union { + struct { + unsigned int mii_speed; + void *fecp; + } fec; + + struct { + /* note that the actual port size may */ + /* be different; cpm(s) handle it OK */ + u8 mdio_msk; + u8 *mdio_dir; + u8 *mdio_dat; + u8 mdc_msk; + u8 *mdc_dir; + u8 *mdc_dat; + } bitbang; + + struct { + u16 lpa; + } fixed; + }; +}; + +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus); +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); +int fs_mii_fec_init(struct fs_enet_mii_bus *bus); + +struct fs_enet_private { + struct device *dev; /* pointer back to the device (must be initialized first) */ + spinlock_t lock; /* during all ops except TX pckt processing */ + spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ + const struct fs_platform_info *fpi; + const struct fs_ops *ops; + int rx_ring, tx_ring; + dma_addr_t ring_mem_addr; + void *ring_base; + struct sk_buff **rx_skbuff; + struct sk_buff **tx_skbuff; + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ + cbd_t *tx_bd_base; + cbd_t *dirty_tx; /* ring entries to be free()ed. */ + cbd_t *cur_rx; + cbd_t *cur_tx; + int tx_free; + struct net_device_stats stats; + struct timer_list phy_timer_list; + const struct phy_info *phy; + u32 msg_enable; + struct mii_if_info mii_if; + unsigned int last_mii_status; + struct fs_enet_mii_bus *mii_bus; + int interrupt; + + int duplex, speed; /* current settings */ + + /* event masks */ + u32 ev_napi_rx; /* mask of NAPI rx events */ + u32 ev_rx; /* rx event mask */ + u32 ev_tx; /* tx event mask */ + u32 ev_err; /* error event mask */ + + u16 bd_rx_empty; /* mask of BD rx empty */ + u16 bd_rx_err; /* mask of BD rx errors */ + + union { + struct { + int idx; /* FEC1 = 0, FEC2 = 1 */ + void *fecp; /* hw registers */ + u32 hthi, htlo; /* state for multicast */ + } fec; + + struct { + int idx; /* FCC1-3 = 0-2 */ + void *fccp; /* hw registers */ + void *ep; /* parameter ram */ + void *fcccp; /* hw registers cont. */ + void *mem; /* FCC DPRAM */ + u32 gaddrh, gaddrl; /* group address */ + } fcc; + + struct { + int idx; /* FEC1 = 0, FEC2 = 1 */ + void *sccp; /* hw registers */ + void *ep; /* parameter ram */ + u32 hthi, htlo; /* state for multicast */ + } scc; + + }; +}; + +/***************************************************************************/ + +int fs_mii_read(struct net_device *dev, int phy_id, int location); +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value); + +void fs_mii_startup(struct net_device *dev); +void fs_mii_shutdown(struct net_device *dev); +void fs_mii_ack_int(struct net_device *dev); + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media); + +void fs_init_bds(struct net_device *dev); +void fs_cleanup_bds(struct net_device *dev); + +/***************************************************************************/ + +#define DRV_MODULE_NAME "fs_enet" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Aug 8, 2005" + +/***************************************************************************/ + +int fs_enet_platform_init(void); +void fs_enet_platform_cleanup(void); + +/***************************************************************************/ + +/* buffer descriptor access macros */ + +/* access macros */ +#if defined(CONFIG_CPM1) +/* for a a CPM1 __raw_xxx's are sufficient */ +#define __cbd_out32(addr, x) __raw_writel(x, addr) +#define __cbd_out16(addr, x) __raw_writew(x, addr) +#define __cbd_in32(addr) __raw_readl(addr) +#define __cbd_in16(addr) __raw_readw(addr) +#else +/* for others play it safe */ +#define __cbd_out32(addr, x) out_be32(addr, x) +#define __cbd_out16(addr, x) out_be16(addr, x) +#define __cbd_in32(addr) in_be32(addr) +#define __cbd_in16(addr) in_be16(addr) +#endif + +/* write */ +#define CBDW_SC(_cbd, _sc) __cbd_out16(&(_cbd)->cbd_sc, (_sc)) +#define CBDW_DATLEN(_cbd, _datlen) __cbd_out16(&(_cbd)->cbd_datlen, (_datlen)) +#define CBDW_BUFADDR(_cbd, _bufaddr) __cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) + +/* read */ +#define CBDR_SC(_cbd) __cbd_in16(&(_cbd)->cbd_sc) +#define CBDR_DATLEN(_cbd) __cbd_in16(&(_cbd)->cbd_datlen) +#define CBDR_BUFADDR(_cbd) __cbd_in32(&(_cbd)->cbd_bufaddr) + +/* set bits */ +#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) + +/* clear bits */ +#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) + +/*******************************************************************/ + +extern const struct fs_ops fs_fec_ops; +extern const struct fs_ops fs_fcc_ops; +extern const struct fs_ops fs_scc_ops; + +/*******************************************************************/ + +/* handy pointer to the immap */ +extern void *fs_enet_immap; + +/*******************************************************************/ + +#endif diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c new file mode 100644 index 000000000000..a940b96433c7 --- /dev/null +++ b/drivers/net/fs_enet/mac-fcc.c @@ -0,0 +1,578 @@ +/* + * FCC driver for Motorola MPC82xx (PQ2). + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +/* FCC access macros */ + +#define __fcc_out32(addr, x) out_be32((unsigned *)addr, x) +#define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x) +#define __fcc_out8(addr, x) out_8((unsigned char *)addr, x) +#define __fcc_in32(addr) in_be32((unsigned *)addr) +#define __fcc_in16(addr) in_be16((unsigned short *)addr) +#define __fcc_in8(addr) in_8((unsigned char *)addr) + +/* parameter space */ + +/* write, read, set bits, clear bits */ +#define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v)) +#define R32(_p, _m) __fcc_in32(&(_p)->_m) +#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) +#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) + +#define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v)) +#define R16(_p, _m) __fcc_in16(&(_p)->_m) +#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) +#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) + +#define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v)) +#define R8(_p, _m) __fcc_in8(&(_p)->_m) +#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) +#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) + +/*************************************************/ + +#define FCC_MAX_MULTICAST_ADDRS 64 + +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) +#define mk_mii_end 0 + +#define MAX_CR_CMD_LOOPS 10000 + +static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) +{ + const struct fs_platform_info *fpi = fep->fpi; + + cpm2_map_t *immap = fs_enet_immap; + cpm_cpm2_t *cpmp = &immap->im_cpm; + u32 v; + int i; + + /* Currently I don't know what feature call will look like. But + I guess there'd be something like do_cpm_cmd() which will require page & sblock */ + v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); + W32(cpmp, cp_cpcr, v | CPM_CR_FLG); + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) + if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) + break; + + if (i >= MAX_CR_CMD_LOOPS) { + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; + } + + return 0; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq(pdev, 0); + + /* Attach the memory for the FCC Parameter RAM */ + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); + fep->fcc.ep = (void *)r->start; + + if (fep->fcc.ep == NULL) + return -EINVAL; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); + fep->fcc.fccp = (void *)r->start; + + if (fep->fcc.fccp == NULL) + return -EINVAL; + + fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; + + if (fep->fcc.fcccp == NULL) + return -EINVAL; + + return 0; +} + +#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) +#define FCC_RX_EVENT (FCC_ENET_RXF) +#define FCC_TX_EVENT (FCC_ENET_TXB) +#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); + if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ + return -EINVAL; + + fep->fcc.mem = (void *)fpi->mem_offset; + + if (do_pd_setup(fep) != 0) + return -EINVAL; + + fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK; + fep->ev_rx = FCC_RX_EVENT; + fep->ev_tx = FCC_TX_EVENT; + fep->ev_err = FCC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_base = dma_alloc_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), &fep->ring_mem_addr, + GFP_KERNEL); + if (fep->ring_base == NULL) + return -ENOMEM; + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + if (fep->ring_base) + dma_free_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), + fep->ring_base, fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + S32(fccp, fcc_fpsmr, FCC_PSMR_PRO); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_enet_t *ep = fep->fcc.ep; + + W32(ep, fen_gaddrh, 0); + W32(ep, fen_gaddrl, 0); +} + +static void set_multicast_one(struct net_device *dev, const u8 *mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_enet_t *ep = fep->fcc.ep; + u16 taddrh, taddrm, taddrl; + + taddrh = ((u16)mac[5] << 8) | mac[4]; + taddrm = ((u16)mac[3] << 8) | mac[2]; + taddrl = ((u16)mac[1] << 8) | mac[0]; + + W16(ep, fen_taddrh, taddrh); + W16(ep, fen_taddrm, taddrm); + W16(ep, fen_taddrl, taddrl); + fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + fcc_enet_t *ep = fep->fcc.ep; + + /* clear promiscuous always */ + C32(fccp, fcc_fpsmr, FCC_PSMR_PRO); + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > FCC_MAX_MULTICAST_ADDRS) { + + W32(ep, fen_gaddrh, 0xffffffff); + W32(ep, fen_gaddrl, 0xffffffff); + } + + /* read back */ + fep->fcc.gaddrh = R32(ep, fen_gaddrh); + fep->fcc.gaddrl = R32(ep, fen_gaddrl); +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +static void restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + fcc_t *fccp = fep->fcc.fccp; + fcc_c_t *fcccp = fep->fcc.fcccp; + fcc_enet_t *ep = fep->fcc.ep; + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; + u16 paddrh, paddrm, paddrl; + u16 mem_addr; + const unsigned char *mac; + int i; + + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); + + /* clear everything (slow & steady does it) */ + for (i = 0; i < sizeof(*ep); i++) + __fcc_out8((char *)ep + i, 0); + + /* get physical address */ + rx_bd_base_phys = fep->ring_mem_addr; + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; + + /* point to bds */ + W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys); + W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys); + + /* Set maximum bytes per receive buffer. + * It must be a multiple of 32. + */ + W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE); + + W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24); + W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24); + + /* Allocate space in the reserved FCC area of DPRAM for the + * internal buffers. No one uses this space (yet), so we + * can do this. Later, we will add resource management for + * this area. + */ + + mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */ + + W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff)); + W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff)); + W16(ep, fen_padptr, mem_addr + 64); + + /* fill with special symbol... */ + memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32); + + W32(ep, fen_genfcc.fcc_rbptr, 0); + W32(ep, fen_genfcc.fcc_tbptr, 0); + W32(ep, fen_genfcc.fcc_rcrc, 0); + W32(ep, fen_genfcc.fcc_tcrc, 0); + W16(ep, fen_genfcc.fcc_res1, 0); + W32(ep, fen_genfcc.fcc_res2, 0); + + /* no CAM */ + W32(ep, fen_camptr, 0); + + /* Set CRC preset and mask */ + W32(ep, fen_cmask, 0xdebb20e3); + W32(ep, fen_cpres, 0xffffffff); + + W32(ep, fen_crcec, 0); /* CRC Error counter */ + W32(ep, fen_alec, 0); /* alignment error counter */ + W32(ep, fen_disfc, 0); /* discard frame counter */ + W16(ep, fen_retlim, 15); /* Retry limit threshold */ + W16(ep, fen_pper, 0); /* Normal persistence */ + + /* set group address */ + W32(ep, fen_gaddrh, fep->fcc.gaddrh); + W32(ep, fen_gaddrl, fep->fcc.gaddrh); + + /* Clear hash filter tables */ + W32(ep, fen_iaddrh, 0); + W32(ep, fen_iaddrl, 0); + + /* Clear the Out-of-sequence TxBD */ + W16(ep, fen_tfcstat, 0); + W16(ep, fen_tfclen, 0); + W32(ep, fen_tfcptr, 0); + + W16(ep, fen_mflr, PKT_MAXBUF_SIZE); /* maximum frame length register */ + W16(ep, fen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ + + /* set address */ + mac = dev->dev_addr; + paddrh = ((u16)mac[5] << 8) | mac[4]; + paddrm = ((u16)mac[3] << 8) | mac[2]; + paddrl = ((u16)mac[1] << 8) | mac[0]; + + W16(ep, fen_paddrh, paddrh); + W16(ep, fen_paddrm, paddrm); + W16(ep, fen_paddrl, paddrl); + + W16(ep, fen_taddrh, 0); + W16(ep, fen_taddrm, 0); + W16(ep, fen_taddrl, 0); + + W16(ep, fen_maxd1, 1520); /* maximum DMA1 length */ + W16(ep, fen_maxd2, 1520); /* maximum DMA2 length */ + + /* Clear stat counters, in case we ever enable RMON */ + W32(ep, fen_octc, 0); + W32(ep, fen_colc, 0); + W32(ep, fen_broc, 0); + W32(ep, fen_mulc, 0); + W32(ep, fen_uspc, 0); + W32(ep, fen_frgc, 0); + W32(ep, fen_ospc, 0); + W32(ep, fen_jbrc, 0); + W32(ep, fen_p64c, 0); + W32(ep, fen_p65c, 0); + W32(ep, fen_p128c, 0); + W32(ep, fen_p256c, 0); + W32(ep, fen_p512c, 0); + W32(ep, fen_p1024c, 0); + + W16(ep, fen_rfthr, 0); /* Suggested by manual */ + W16(ep, fen_rfcnt, 0); + W16(ep, fen_cftype, 0); + + fs_init_bds(dev); + + /* adjust to speed (for RMII mode) */ + if (fpi->use_rmii) { + if (fep->speed == 100) + C8(fcccp, fcc_gfemr, 0x20); + else + S8(fcccp, fcc_gfemr, 0x20); + } + + fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); + + /* clear events */ + W16(fccp, fcc_fcce, 0xffff); + + /* Enable interrupts we wish to service */ + W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB); + + /* Set GFMR to enable Ethernet operating mode */ + W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); + + /* set sync/delimiters */ + W16(fccp, fcc_fdsr, 0xd555); + + W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC); + + if (fpi->use_rmii) + S32(fccp, fcc_fpsmr, FCC_PSMR_RMII); + + /* adjust to duplex mode */ + if (fep->duplex) + S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); + else + C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); + + S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + /* stop ethernet */ + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); + + /* clear events */ + W16(fccp, fcc_fcce, 0xffff); + + /* clear interrupt mask */ + W16(fccp, fcc_fccm, 0); + + fs_cleanup_bds(dev); +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + /* nothing */ +} + +static void tx_kickstart(struct net_device *dev) +{ + /* nothing */ +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + return (u32)R16(fccp, fcc_fcce); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + W16(fccp, fcc_fcce, int_events & 0xffff); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events); +} + +int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) + return -EINVAL; + + memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); + p = (char *)p + sizeof(fcc_t); + + memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); + p = (char *)p + sizeof(fcc_c_t); + + memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); + + return 0; +} + +int get_regs_len(struct net_device *dev) +{ + return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); +} + +/* Some transmit errors cause the transmitter to shut + * down. We now issue a restart transmit. Since the + * errors close the BD and update the pointers, the restart + * _should_ pick up without having to reset any of our + * pointers either. Also, To workaround 8260 device erratum + * CPM37, we must disable and then re-enable the transmitter + * following a Late Collision, Underrun, or Retry Limit error. + */ +void tx_restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fcc_t *fccp = fep->fcc.fccp; + + C32(fccp, fcc_gfmr, FCC_GFMR_ENT); + udelay(10); + S32(fccp, fcc_gfmr, FCC_GFMR_ENT); + + fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); +} + +/*************************************************************************/ + +const struct fs_ops fs_fcc_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c new file mode 100644 index 000000000000..5ef4e845a387 --- /dev/null +++ b/drivers/net/fs_enet/mac-fec.c @@ -0,0 +1,653 @@ +/* + * Freescale Ethernet controllers + * + * Copyright (c) 2005 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_8xx +#include +#include +#include +#include +#endif + +#include "fs_enet.h" + +/*************************************************/ + +#if defined(CONFIG_CPM1) +/* for a CPM1 __raw_xxx's are sufficient */ +#define __fs_out32(addr, x) __raw_writel(x, addr) +#define __fs_out16(addr, x) __raw_writew(x, addr) +#define __fs_in32(addr) __raw_readl(addr) +#define __fs_in16(addr) __raw_readw(addr) +#else +/* for others play it safe */ +#define __fs_out32(addr, x) out_be32(addr, x) +#define __fs_out16(addr, x) out_be16(addr, x) +#define __fs_in32(addr) in_be32(addr) +#define __fs_in16(addr) in_be16(addr) +#endif + +/* write */ +#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v)) + +/* read */ +#define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg) + +/* set bits */ +#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) + +/* clear bits */ +#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) + + +/* CRC polynomium used by the FEC for the multicast group filtering */ +#define FEC_CRC_POLY 0x04C11DB7 + +#define FEC_MAX_MULTICAST_ADDRS 64 + +/* Interrupt events/masks. +*/ +#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ +#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ +#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ +#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ +#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ +#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ +#define FEC_ENET_RXF 0x02000000U /* Full frame received */ +#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ +#define FEC_ENET_MII 0x00800000U /* MII interrupt */ +#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ + +#define FEC_ECNTRL_PINMUX 0x00000004 +#define FEC_ECNTRL_ETHER_EN 0x00000002 +#define FEC_ECNTRL_RESET 0x00000001 + +#define FEC_RCNTRL_BC_REJ 0x00000010 +#define FEC_RCNTRL_PROM 0x00000008 +#define FEC_RCNTRL_MII_MODE 0x00000004 +#define FEC_RCNTRL_DRT 0x00000002 +#define FEC_RCNTRL_LOOP 0x00000001 + +#define FEC_TCNTRL_FDEN 0x00000004 +#define FEC_TCNTRL_HBC 0x00000002 +#define FEC_TCNTRL_GTS 0x00000001 + + +/* Make MII read/write commands for the FEC. +*/ +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) +#define mk_mii_end 0 + +#define FEC_MII_LOOPS 10000 + +/* + * Delay to wait for FEC reset command to complete (in us) + */ +#define FEC_RESET_DELAY 50 + +static int whack_reset(fec_t * fecp) +{ + int i; + + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); + for (i = 0; i < FEC_RESET_DELAY; i++) { + if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0) + return 0; /* OK */ + udelay(1); + } + + return -1; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + fep->fec.fecp =(void*)r->start; + + if(fep->fec.fecp == NULL) + return -EINVAL; + + return 0; + +} + +#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) +#define FEC_RX_EVENT (FEC_ENET_RXF) +#define FEC_TX_EVENT (FEC_ENET_TXF) +#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \ + FEC_ENET_BABT | FEC_ENET_EBERR) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (do_pd_setup(fep) != 0) + return -EINVAL; + + fep->fec.hthi = 0; + fep->fec.htlo = 0; + + fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK; + fep->ev_rx = FEC_RX_EVENT; + fep->ev_tx = FEC_TX_EVENT; + fep->ev_err = FEC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_base = dma_alloc_coherent(fep->dev, + (fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), &fep->ring_mem_addr, + GFP_KERNEL); + if (fep->ring_base == NULL) + return -ENOMEM; + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + if(fep->ring_base) + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) + * sizeof(cbd_t), + fep->ring_base, + fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FS(fecp, r_cntrl, FEC_RCNTRL_PROM); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fep->fec.hthi = 0; + fep->fec.htlo = 0; +} + +static void set_multicast_one(struct net_device *dev, const u8 *mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + int temp, hash_index, i, j; + u32 crc, csrVal; + u8 byte, msb; + + crc = 0xffffffff; + for (i = 0; i < 6; i++) { + byte = mac[i]; + for (j = 0; j < 8; j++) { + msb = crc >> 31; + crc <<= 1; + if (msb ^ (byte & 0x1)) + crc ^= FEC_CRC_POLY; + byte >>= 1; + } + } + + temp = (crc & 0x3f) >> 1; + hash_index = ((temp & 0x01) << 4) | + ((temp & 0x02) << 2) | + ((temp & 0x04)) | + ((temp & 0x08) >> 2) | + ((temp & 0x10) >> 4); + csrVal = 1 << hash_index; + if (crc & 1) + fep->fec.hthi |= csrVal; + else + fep->fec.htlo |= csrVal; +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { + fep->fec.hthi = 0xffffffffU; + fep->fec.htlo = 0xffffffffU; + } + + FC(fecp, r_cntrl, FEC_RCNTRL_PROM); + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +static void restart(struct net_device *dev) +{ +#ifdef CONFIG_DUET + immap_t *immap = fs_enet_immap; + u32 cptr; +#endif + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + const struct fs_platform_info *fpi = fep->fpi; + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; + int r; + u32 addrhi, addrlo; + + r = whack_reset(fep->fec.fecp); + if (r != 0) + printk(KERN_ERR DRV_MODULE_NAME + ": %s FEC Reset FAILED!\n", dev->name); + + /* + * Set station address. + */ + addrhi = ((u32) dev->dev_addr[0] << 24) | + ((u32) dev->dev_addr[1] << 16) | + ((u32) dev->dev_addr[2] << 8) | + (u32) dev->dev_addr[3]; + addrlo = ((u32) dev->dev_addr[4] << 24) | + ((u32) dev->dev_addr[5] << 16); + FW(fecp, addr_low, addrhi); + FW(fecp, addr_high, addrlo); + + /* + * Reset all multicast. + */ + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); + + /* + * Set maximum receive buffer size. + */ + FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); + FW(fecp, r_hash, PKT_MAXBUF_SIZE); + + /* get physical address */ + rx_bd_base_phys = fep->ring_mem_addr; + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; + + /* + * Set receive and transmit descriptor base. + */ + FW(fecp, r_des_start, rx_bd_base_phys); + FW(fecp, x_des_start, tx_bd_base_phys); + + fs_init_bds(dev); + + /* + * Enable big endian and don't care about SDMA FC. + */ + FW(fecp, fun_code, 0x78000000); + + /* + * Set MII speed. + */ + FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed); + + /* + * Clear any outstanding interrupt. + */ + FW(fecp, ievent, 0xffc0); + FW(fecp, ivec, (fep->interrupt / 2) << 29); + + + /* + * adjust to speed (only for DUET & RMII) + */ +#ifdef CONFIG_DUET + if (fpi->use_rmii) { + cptr = in_be32(&immap->im_cpm.cp_cptr); + switch (fs_get_fec_index(fpi->fs_no)) { + case 0: + cptr |= 0x100; + if (fep->speed == 10) + cptr |= 0x0000010; + else if (fep->speed == 100) + cptr &= ~0x0000010; + break; + case 1: + cptr |= 0x80; + if (fep->speed == 10) + cptr |= 0x0000008; + else if (fep->speed == 100) + cptr &= ~0x0000008; + break; + default: + BUG(); /* should never happen */ + break; + } + out_be32(&immap->im_cpm.cp_cptr, cptr); + } +#endif + + FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + /* + * adjust to duplex mode + */ + if (fep->duplex) { + FC(fecp, r_cntrl, FEC_RCNTRL_DRT); + FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ + } else { + FS(fecp, r_cntrl, FEC_RCNTRL_DRT); + FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ + } + + /* + * Enable interrupts we wish to service. + */ + FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB); + + /* + * And last, enable the transmit and receive processing. + */ + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, r_des_active, 0x01000000); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + struct fs_enet_mii_bus *bus = fep->mii_bus; + const struct fs_mii_bus_info *bi = bus->bus_info; + int i; + + if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) + return; /* already down */ + + FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ + for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && + i < FEC_RESET_DELAY; i++) + udelay(1); + + if (i == FEC_RESET_DELAY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FEC timeout on graceful transmit stop\n", + dev->name); + /* + * Disable FEC. Let only MII interrupts. + */ + FW(fecp, imask, 0); + FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN); + + fs_cleanup_bds(dev); + + /* shut down FEC1? that's where the mii bus is */ + if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) { + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, ievent, FEC_ENET_MII); + FW(fecp, mii_speed, bus->fec.mii_speed); + } +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + immap_t *immap = fs_enet_immap; + u32 siel; + + /* SIU interrupt */ + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { + + siel = in_be32(&immap->im_siu_conf.sc_siel); + if ((irq & 1) == 0) + siel |= (0x80000000 >> irq); + else + siel &= ~(0x80000000 >> (irq & ~1)); + out_be32(&immap->im_siu_conf.sc_siel, siel); + } +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, r_des_active, 0x01000000); +} + +static void tx_kickstart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, x_des_active, 0x01000000); +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + return FR(fecp, ievent) & FR(fecp, imask); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + fec_t *fecp = fep->fec.fecp; + + FW(fecp, ievent, int_events); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events); +} + +int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(fec_t)) + return -EINVAL; + + memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t)); + + return 0; +} + +int get_regs_len(struct net_device *dev) +{ + return sizeof(fec_t); +} + +void tx_restart(struct net_device *dev) +{ + /* nothing */ +} + +/*************************************************************************/ + +const struct fs_ops fs_fec_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; + +/***********************************************************************/ + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + fec_t *fecp = bus->fec.fecp; + int i, ret = -1; + + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) { + FW(fecp, ievent, FEC_ENET_MII); + ret = FR(fecp, mii_data) & 0xffff; + } + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value) +{ + fec_t *fecp = bus->fec.fecp; + int i; + + /* this must never happen */ + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) + FW(fecp, ievent, FEC_ENET_MII); +} + +int fs_mii_fec_init(struct fs_enet_mii_bus *bus) +{ + bd_t *bd = (bd_t *)__res; + const struct fs_mii_bus_info *bi = bus->bus_info; + fec_t *fecp; + + if (bi->id != 0) + return -1; + + bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec; + bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) + & 0x3F) << 1; + + fecp = bus->fec.fecp; + + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, ievent, FEC_ENET_MII); + FW(fecp, mii_speed, bus->fec.mii_speed); + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c new file mode 100644 index 000000000000..d8c6e9cadcf5 --- /dev/null +++ b/drivers/net/fs_enet/mac-scc.c @@ -0,0 +1,524 @@ +/* + * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_8xx +#include +#include +#include +#include +#endif + +#include "fs_enet.h" + +/*************************************************/ + +#if defined(CONFIG_CPM1) +/* for a 8xx __raw_xxx's are sufficient */ +#define __fs_out32(addr, x) __raw_writel(x, addr) +#define __fs_out16(addr, x) __raw_writew(x, addr) +#define __fs_out8(addr, x) __raw_writeb(x, addr) +#define __fs_in32(addr) __raw_readl(addr) +#define __fs_in16(addr) __raw_readw(addr) +#define __fs_in8(addr) __raw_readb(addr) +#else +/* for others play it safe */ +#define __fs_out32(addr, x) out_be32(addr, x) +#define __fs_out16(addr, x) out_be16(addr, x) +#define __fs_in32(addr) in_be32(addr) +#define __fs_in16(addr) in_be16(addr) +#endif + +/* write, read, set bits, clear bits */ +#define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v)) +#define R32(_p, _m) __fs_in32(&(_p)->_m) +#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) +#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) + +#define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v)) +#define R16(_p, _m) __fs_in16(&(_p)->_m) +#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) +#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) + +#define W8(_p, _m, _v) __fs_out8(&(_p)->_m, (_v)) +#define R8(_p, _m) __fs_in8(&(_p)->_m) +#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) +#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) + +#define SCC_MAX_MULTICAST_ADDRS 64 + +/* + * Delay to wait for SCC reset command to complete (in us) + */ +#define SCC_RESET_DELAY 50 +#define MAX_CR_CMD_LOOPS 10000 + +static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) +{ + cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; + u32 v, ch; + int i = 0; + + ch = fep->scc.idx << 2; + v = mk_cr_cmd(ch, op); + W16(cpmp, cp_cpcr, v | CPM_CR_FLG); + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) + if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) + break; + + if (i >= MAX_CR_CMD_LOOPS) { + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; + } + return 0; +} + +static int do_pd_setup(struct fs_enet_private *fep) +{ + struct platform_device *pdev = to_platform_device(fep->dev); + struct resource *r; + + /* Fill out IRQ field */ + fep->interrupt = platform_get_irq_byname(pdev, "interrupt"); + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + fep->scc.sccp = (void *)r->start; + + if (fep->scc.sccp == NULL) + return -EINVAL; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"); + fep->scc.ep = (void *)r->start; + + if (fep->scc.ep == NULL) + return -EINVAL; + + return 0; +} + +#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB) +#define SCC_RX_EVENT (SCCE_ENET_RXF) +#define SCC_TX_EVENT (SCCE_ENET_TXB) +#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY) + +static int setup_data(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->scc.idx = fs_get_scc_index(fpi->fs_no); + if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ + return -EINVAL; + + do_pd_setup(fep); + + fep->scc.hthi = 0; + fep->scc.htlo = 0; + + fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; + fep->ev_rx = SCC_RX_EVENT; + fep->ev_tx = SCC_TX_EVENT; + fep->ev_err = SCC_ERR_EVENT_MSK; + + return 0; +} + +static int allocate_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + + fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) * + sizeof(cbd_t), 8); + if (IS_DPERR(fep->ring_mem_addr)) + return -ENOMEM; + + fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr); + + return 0; +} + +static void free_bd(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->ring_base) + cpm_dpfree(fep->ring_mem_addr); +} + +static void cleanup_data(struct net_device *dev) +{ + /* nothing */ +} + +static void set_promiscuous_mode(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + S16(sccp, scc_psmr, SCC_PSMR_PRO); +} + +static void set_multicast_start(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_enet_t *ep = fep->scc.ep; + + W16(ep, sen_gaddr1, 0); + W16(ep, sen_gaddr2, 0); + W16(ep, sen_gaddr3, 0); + W16(ep, sen_gaddr4, 0); +} + +static void set_multicast_one(struct net_device *dev, const u8 * mac) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_enet_t *ep = fep->scc.ep; + u16 taddrh, taddrm, taddrl; + + taddrh = ((u16) mac[5] << 8) | mac[4]; + taddrm = ((u16) mac[3] << 8) | mac[2]; + taddrl = ((u16) mac[1] << 8) | mac[0]; + + W16(ep, sen_taddrh, taddrh); + W16(ep, sen_taddrm, taddrm); + W16(ep, sen_taddrl, taddrl); + scc_cr_cmd(fep, CPM_CR_SET_GADDR); +} + +static void set_multicast_finish(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + scc_enet_t *ep = fep->scc.ep; + + /* clear promiscuous always */ + C16(sccp, scc_psmr, SCC_PSMR_PRO); + + /* if all multi or too many multicasts; just enable all */ + if ((dev->flags & IFF_ALLMULTI) != 0 || + dev->mc_count > SCC_MAX_MULTICAST_ADDRS) { + + W16(ep, sen_gaddr1, 0xffff); + W16(ep, sen_gaddr2, 0xffff); + W16(ep, sen_gaddr3, 0xffff); + W16(ep, sen_gaddr4, 0xffff); + } +} + +static void set_multicast_list(struct net_device *dev) +{ + struct dev_mc_list *pmc; + + if ((dev->flags & IFF_PROMISC) == 0) { + set_multicast_start(dev); + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + set_multicast_one(dev, pmc->dmi_addr); + set_multicast_finish(dev); + } else + set_promiscuous_mode(dev); +} + +/* + * This function is called to start or restart the FEC during a link + * change. This only happens when switching between half and full + * duplex. + */ +static void restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + scc_enet_t *ep = fep->scc.ep; + const struct fs_platform_info *fpi = fep->fpi; + u16 paddrh, paddrm, paddrl; + const unsigned char *mac; + int i; + + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* clear everything (slow & steady does it) */ + for (i = 0; i < sizeof(*ep); i++) + __fs_out8((char *)ep + i, 0); + + /* point to bds */ + W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr); + W16(ep, sen_genscc.scc_tbase, + fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring); + + /* Initialize function code registers for big-endian. + */ + W8(ep, sen_genscc.scc_rfcr, SCC_EB); + W8(ep, sen_genscc.scc_tfcr, SCC_EB); + + /* Set maximum bytes per receive buffer. + * This appears to be an Ethernet frame size, not the buffer + * fragment size. It must be a multiple of four. + */ + W16(ep, sen_genscc.scc_mrblr, 0x5f0); + + /* Set CRC preset and mask. + */ + W32(ep, sen_cpres, 0xffffffff); + W32(ep, sen_cmask, 0xdebb20e3); + + W32(ep, sen_crcec, 0); /* CRC Error counter */ + W32(ep, sen_alec, 0); /* alignment error counter */ + W32(ep, sen_disfc, 0); /* discard frame counter */ + + W16(ep, sen_pads, 0x8888); /* Tx short frame pad character */ + W16(ep, sen_retlim, 15); /* Retry limit threshold */ + + W16(ep, sen_maxflr, 0x5ee); /* maximum frame length register */ + + W16(ep, sen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ + + W16(ep, sen_maxd1, 0x000005f0); /* maximum DMA1 length */ + W16(ep, sen_maxd2, 0x000005f0); /* maximum DMA2 length */ + + /* Clear hash tables. + */ + W16(ep, sen_gaddr1, 0); + W16(ep, sen_gaddr2, 0); + W16(ep, sen_gaddr3, 0); + W16(ep, sen_gaddr4, 0); + W16(ep, sen_iaddr1, 0); + W16(ep, sen_iaddr2, 0); + W16(ep, sen_iaddr3, 0); + W16(ep, sen_iaddr4, 0); + + /* set address + */ + mac = dev->dev_addr; + paddrh = ((u16) mac[5] << 8) | mac[4]; + paddrm = ((u16) mac[3] << 8) | mac[2]; + paddrl = ((u16) mac[1] << 8) | mac[0]; + + W16(ep, sen_paddrh, paddrh); + W16(ep, sen_paddrm, paddrm); + W16(ep, sen_paddrl, paddrl); + + W16(ep, sen_pper, 0); + W16(ep, sen_taddrl, 0); + W16(ep, sen_taddrm, 0); + W16(ep, sen_taddrh, 0); + + fs_init_bds(dev); + + scc_cr_cmd(fep, CPM_CR_INIT_TRX); + + W16(sccp, scc_scce, 0xffff); + + /* Enable interrupts we wish to service. + */ + W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); + + /* Set GSMR_H to enable all normal operating modes. + * Set GSMR_L to enable Ethernet to MC68160. + */ + W32(sccp, scc_gsmrh, 0); + W32(sccp, scc_gsmrl, + SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | + SCC_GSMRL_MODE_ENET); + + /* Set sync/delimiters. + */ + W16(sccp, scc_dsr, 0xd555); + + /* Set processing mode. Use Ethernet CRC, catch broadcast, and + * start frame search 22 bit times after RENA. + */ + W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22); + + /* Set full duplex mode if needed */ + if (fep->duplex) + S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); + + S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); +} + +static void stop(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + int i; + + for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++) + udelay(1); + + if (i == SCC_RESET_DELAY) + printk(KERN_WARNING DRV_MODULE_NAME + ": %s SCC timeout on graceful transmit stop\n", + dev->name); + + W16(sccp, scc_sccm, 0); + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + fs_cleanup_bds(dev); +} + +static void pre_request_irq(struct net_device *dev, int irq) +{ + immap_t *immap = fs_enet_immap; + u32 siel; + + /* SIU interrupt */ + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { + + siel = in_be32(&immap->im_siu_conf.sc_siel); + if ((irq & 1) == 0) + siel |= (0x80000000 >> irq); + else + siel &= ~(0x80000000 >> (irq & ~1)); + out_be32(&immap->im_siu_conf.sc_siel, siel); + } +} + +static void post_free_irq(struct net_device *dev, int irq) +{ + /* nothing */ +} + +static void napi_clear_rx_event(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK); +} + +static void napi_enable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); +} + +static void napi_disable_rx(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); +} + +static void rx_bd_done(struct net_device *dev) +{ + /* nothing */ +} + +static void tx_kickstart(struct net_device *dev) +{ + /* nothing */ +} + +static u32 get_int_events(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + return (u32) R16(sccp, scc_scce); +} + +static void clear_int_events(struct net_device *dev, u32 int_events) +{ + struct fs_enet_private *fep = netdev_priv(dev); + scc_t *sccp = fep->scc.sccp; + + W16(sccp, scc_scce, int_events & 0xffff); +} + +static void ev_error(struct net_device *dev, u32 int_events) +{ + printk(KERN_WARNING DRV_MODULE_NAME + ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events); +} + +static int get_regs(struct net_device *dev, void *p, int *sizep) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t)) + return -EINVAL; + + memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t)); + p = (char *)p + sizeof(scc_t); + + memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t)); + + return 0; +} + +static int get_regs_len(struct net_device *dev) +{ + return sizeof(scc_t) + sizeof(scc_enet_t); +} + +static void tx_restart(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + scc_cr_cmd(fep, CPM_CR_RESTART_TX); +} + +/*************************************************************************/ + +const struct fs_ops fs_scc_ops = { + .setup_data = setup_data, + .cleanup_data = cleanup_data, + .set_multicast_list = set_multicast_list, + .restart = restart, + .stop = stop, + .pre_request_irq = pre_request_irq, + .post_free_irq = post_free_irq, + .napi_clear_rx_event = napi_clear_rx_event, + .napi_enable_rx = napi_enable_rx, + .napi_disable_rx = napi_disable_rx, + .rx_bd_done = rx_bd_done, + .tx_kickstart = tx_kickstart, + .get_int_events = get_int_events, + .clear_int_events = clear_int_events, + .ev_error = ev_error, + .get_regs = get_regs, + .get_regs_len = get_regs_len, + .tx_restart = tx_restart, + .allocate_bd = allocate_bd, + .free_bd = free_bd, +}; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c new file mode 100644 index 000000000000..24a5e2e23d18 --- /dev/null +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -0,0 +1,405 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +#ifdef CONFIG_8xx +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) +{ + immap_t *im = (immap_t *)fs_enet_immap; + void *dir, *dat, *ppar; + int adv; + u8 msk; + + switch (port) { + case fsiop_porta: + dir = &im->im_ioport.iop_padir; + dat = &im->im_ioport.iop_padat; + ppar = &im->im_ioport.iop_papar; + break; + + case fsiop_portb: + dir = &im->im_cpm.cp_pbdir; + dat = &im->im_cpm.cp_pbdat; + ppar = &im->im_cpm.cp_pbpar; + break; + + case fsiop_portc: + dir = &im->im_ioport.iop_pcdir; + dat = &im->im_ioport.iop_pcdat; + ppar = &im->im_ioport.iop_pcpar; + break; + + case fsiop_portd: + dir = &im->im_ioport.iop_pddir; + dat = &im->im_ioport.iop_pddat; + ppar = &im->im_ioport.iop_pdpar; + break; + + case fsiop_porte: + dir = &im->im_cpm.cp_pedir; + dat = &im->im_cpm.cp_pedat; + ppar = &im->im_cpm.cp_pepar; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } + + adv = bit >> 3; + dir = (char *)dir + adv; + dat = (char *)dat + adv; + ppar = (char *)ppar + adv; + + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + + *dirp = dir; + *datp = dat; + *mskp = msk; + + return 0; +} +#endif + +#ifdef CONFIG_8260 +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) +{ + iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport; + void *dir, *dat, *ppar; + int adv; + u8 msk; + + switch (port) { + case fsiop_porta: + dir = &io->iop_pdira; + dat = &io->iop_pdata; + ppar = &io->iop_ppara; + break; + + case fsiop_portb: + dir = &io->iop_pdirb; + dat = &io->iop_pdatb; + ppar = &io->iop_pparb; + break; + + case fsiop_portc: + dir = &io->iop_pdirc; + dat = &io->iop_pdatc; + ppar = &io->iop_pparc; + break; + + case fsiop_portd: + dir = &io->iop_pdird; + dat = &io->iop_pdatd; + ppar = &io->iop_ppard; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } + + adv = bit >> 3; + dir = (char *)dir + adv; + dat = (char *)dat + adv; + ppar = (char *)ppar + adv; + + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + + *dirp = dir; + *datp = dat; + *mskp = msk; + + return 0; +} +#endif + +static inline void bb_set(u8 *p, u8 m) +{ + out_8(p, in_8(p) | m); +} + +static inline void bb_clr(u8 *p, u8 m) +{ + out_8(p, in_8(p) & ~m); +} + +static inline int bb_read(u8 *p, u8 m) +{ + return (in_8(p) & m) != 0; +} + +static inline void mdio_active(struct fs_enet_mii_bus *bus) +{ + bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); +} + +static inline void mdio_tristate(struct fs_enet_mii_bus *bus) +{ + bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); +} + +static inline int mdio_read(struct fs_enet_mii_bus *bus) +{ + return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); +} + +static inline void mdio(struct fs_enet_mii_bus *bus, int what) +{ + if (what) + bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); + else + bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); +} + +static inline void mdc(struct fs_enet_mii_bus *bus, int what) +{ + if (what) + bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); + else + bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); +} + +static inline void mii_delay(struct fs_enet_mii_bus *bus) +{ + udelay(bus->bus_info->i.bitbang.delay); +} + +/* Utility to send the preamble, address, and register (common to read and write). */ +static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg) +{ + int j; + + /* + * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. + * The IEEE spec says this is a PHY optional requirement. The AMD + * 79C874 requires one after power up and one after a MII communications + * error. This means that we are doing more preambles than we need, + * but it is safer and will be much more robust. + */ + + mdio_active(bus); + mdio(bus, 1); + for (j = 0; j < 32; j++) { + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + } + + /* send the start bit (01) and the read opcode (10) or write (10) */ + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, !read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* send the PHY address */ + for (j = 0; j < 5; j++) { + mdc(bus, 0); + mdio(bus, (addr & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + addr <<= 1; + } + + /* send the register address */ + for (j = 0; j < 5; j++) { + mdc(bus, 0); + mdio(bus, (reg & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + reg <<= 1; + } +} + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + u16 rdreg; + int ret, j; + u8 addr = phy_id & 0xff; + u8 reg = location & 0xff; + + bitbang_pre(bus, 1, addr, reg); + + /* tri-state our MDIO I/O pin so we can read */ + mdc(bus, 0); + mdio_tristate(bus); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* check the turnaround bit: the PHY should be driving it to zero */ + if (mdio_read(bus) != 0) { + /* PHY didn't drive TA low */ + for (j = 0; j < 32; j++) { + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + } + ret = -1; + goto out; + } + + mdc(bus, 0); + mii_delay(bus); + + /* read 16 bits of register data, MSB first */ + rdreg = 0; + for (j = 0; j < 16; j++) { + mdc(bus, 1); + mii_delay(bus); + rdreg <<= 1; + rdreg |= mdio_read(bus); + mdc(bus, 0); + mii_delay(bus); + } + + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + ret = rdreg; +out: + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) +{ + int j; + u8 addr = phy_id & 0xff; + u8 reg = location & 0xff; + u16 value = val & 0xffff; + + bitbang_pre(bus, 0, addr, reg); + + /* send the turnaround (10) */ + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + + /* write 16 bits of register data, MSB first */ + for (j = 0; j < 16; j++) { + mdc(bus, 0); + mdio(bus, (value & 0x8000) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + value <<= 1; + } + + /* + * Tri-state the MDIO line. + */ + mdio_tristate(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); +} + +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus) +{ + const struct fs_mii_bus_info *bi = bus->bus_info; + int r; + + r = bitbang_prep_bit(&bus->bitbang.mdio_dir, + &bus->bitbang.mdio_dat, + &bus->bitbang.mdio_msk, + bi->i.bitbang.mdio_port, + bi->i.bitbang.mdio_bit); + if (r != 0) + return r; + + r = bitbang_prep_bit(&bus->bitbang.mdc_dir, + &bus->bitbang.mdc_dat, + &bus->bitbang.mdc_msk, + bi->i.bitbang.mdc_port, + bi->i.bitbang.mdc_bit); + if (r != 0) + return r; + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c new file mode 100644 index 000000000000..b3e192d612e5 --- /dev/null +++ b/drivers/net/fs_enet/mii-fixed.c @@ -0,0 +1,92 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +static const u16 mii_regs[7] = { + 0x3100, + 0x786d, + 0x0fff, + 0x0fff, + 0x01e1, + 0x45e1, + 0x0003, +}; + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + int ret = 0; + + if ((unsigned int)location >= ARRAY_SIZE(mii_regs)) + return -1; + + if (location != 5) + ret = mii_regs[location]; + else + ret = bus->fixed.lpa; + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) +{ + /* do nothing */ +} + +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus) +{ + const struct fs_mii_bus_info *bi = bus->bus_info; + + bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */ + + /* if speed is fixed at 10Mb, remove 100Mb modes */ + if (bi->i.fixed.speed == 10) + bus->fixed.lpa &= ~LPA_100; + + /* if duplex is half, remove full duplex modes */ + if (bi->i.fixed.duplex == 0) + bus->fixed.lpa &= ~LPA_DUPLEX; + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h new file mode 100644 index 000000000000..bef23bbf8690 --- /dev/null +++ b/include/linux/fs_enet_pd.h @@ -0,0 +1,136 @@ +/* + * Platform information definitions for the + * universal Freescale Ethernet driver. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef FS_ENET_PD_H +#define FS_ENET_PD_H + +#include +#include + +#define FS_ENET_NAME "fs_enet" + +enum fs_id { + fsid_fec1, + fsid_fec2, + fsid_fcc1, + fsid_fcc2, + fsid_fcc3, + fsid_scc1, + fsid_scc2, + fsid_scc3, + fsid_scc4, +}; + +#define FS_MAX_INDEX 9 + +static inline int fs_get_fec_index(enum fs_id id) +{ + if (id >= fsid_fec1 && id <= fsid_fec2) + return id - fsid_fec1; + return -1; +} + +static inline int fs_get_fcc_index(enum fs_id id) +{ + if (id >= fsid_fcc1 && id <= fsid_fcc3) + return id - fsid_fcc1; + return -1; +} + +static inline int fs_get_scc_index(enum fs_id id) +{ + if (id >= fsid_scc1 && id <= fsid_scc4) + return id - fsid_scc1; + return -1; +} + +enum fs_mii_method { + fsmii_fixed, + fsmii_fec, + fsmii_bitbang, +}; + +enum fs_ioport { + fsiop_porta, + fsiop_portb, + fsiop_portc, + fsiop_portd, + fsiop_porte, +}; + +struct fs_mii_bus_info { + int method; /* mii method */ + int id; /* the id of the mii_bus */ + int disable_aneg; /* if the controller needs to negothiate speed & duplex */ + int lpa; /* the default board-specific vallues will be applied otherwise */ + + union { + struct { + int duplex; + int speed; + } fixed; + + struct { + /* nothing */ + } fec; + + struct { + /* nothing */ + } scc; + + struct { + int mdio_port; /* port & bit for MDIO */ + int mdio_bit; + int mdc_port; /* port & bit for MDC */ + int mdc_bit; + int delay; /* delay in us */ + } bitbang; + } i; +}; + +struct fs_platform_info { + + void(*init_ioports)(void); + /* device specific information */ + int fs_no; /* controller index */ + + u32 cp_page; /* CPM page */ + u32 cp_block; /* CPM sblock */ + + u32 clk_trx; /* some stuff for pins & mux configuration*/ + u32 clk_route; + u32 clk_mask; + + u32 mem_offset; + u32 dpram_offset; + u32 fcc_regs_c; + + u32 device_flags; + + int phy_addr; /* the phy address (-1 no phy) */ + int phy_irq; /* the phy irq (if it exists) */ + + const struct fs_mii_bus_info *bus_info; + + int rx_ring, tx_ring; /* number of buffers on rx */ + __u8 macaddr[6]; /* mac address */ + int rx_copybreak; /* limit we copy small frames */ + int use_napi; /* use NAPI */ + int napi_weight; /* NAPI weight */ + + int use_rmii; /* use RMII mode */ +}; + +#endif -- cgit v1.2.3 From e04b0ea2e0f9c1bb0d874db4493fc7f7a623116b Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 27 Sep 2005 01:21:55 -0700 Subject: [PATCH] PCI: Block config access during BIST Some PCI adapters (eg. ipr scsi adapters) have an exposure today in that they issue BIST to the adapter to reset the card. If, during the time it takes to complete BIST, userspace attempts to access PCI config space, the host bus bridge will master abort the access since the ipr adapter does not respond on the PCI bus for a brief period of time when running BIST. On PPC64 hardware, this master abort results in the host PCI bridge isolating that PCI device from the rest of the system, making the device unusable until Linux is rebooted. This patch is an attempt to close that exposure by introducing some blocking code in the PCI code. When blocked, writes will be humored and reads will return the cached value. Ben Herrenschmidt has also mentioned that he plans to use this in PPC power management. Signed-off-by: Brian King Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman drivers/pci/access.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 20 +++++----- drivers/pci/pci.h | 7 +++ drivers/pci/proc.c | 28 +++++++-------- drivers/pci/syscall.c | 14 +++---- include/linux/pci.h | 7 +++ 6 files changed, 134 insertions(+), 31 deletions(-) --- drivers/pci/access.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 20 +++++------ drivers/pci/pci.h | 7 ++++ drivers/pci/proc.c | 28 ++++++++-------- drivers/pci/syscall.c | 14 ++++---- include/linux/pci.h | 7 ++++ 6 files changed, 134 insertions(+), 31 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 24a76de49f41..2a42add7f563 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -60,3 +60,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword); EXPORT_SYMBOL(pci_bus_write_config_byte); EXPORT_SYMBOL(pci_bus_write_config_word); EXPORT_SYMBOL(pci_bus_write_config_dword); + +static u32 pci_user_cached_config(struct pci_dev *dev, int pos) +{ + u32 data; + + data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])]; + data >>= (pos % sizeof(dev->saved_config_space[0])) * 8; + return data; +} + +#define PCI_USER_READ_CONFIG(size,type) \ +int pci_user_read_config_##size \ + (struct pci_dev *dev, int pos, type *val) \ +{ \ + unsigned long flags; \ + int ret = 0; \ + u32 data = -1; \ + if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->read(dev->bus, dev->devfn, \ + pos, sizeof(type), &data); \ + else if (pos < sizeof(dev->saved_config_space)) \ + data = pci_user_cached_config(dev, pos); \ + spin_unlock_irqrestore(&pci_lock, flags); \ + *val = (type)data; \ + return ret; \ +} + +#define PCI_USER_WRITE_CONFIG(size,type) \ +int pci_user_write_config_##size \ + (struct pci_dev *dev, int pos, type val) \ +{ \ + unsigned long flags; \ + int ret = -EIO; \ + if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->write(dev->bus, dev->devfn, \ + pos, sizeof(type), val); \ + spin_unlock_irqrestore(&pci_lock, flags); \ + return ret; \ +} + +PCI_USER_READ_CONFIG(byte, u8) +PCI_USER_READ_CONFIG(word, u16) +PCI_USER_READ_CONFIG(dword, u32) +PCI_USER_WRITE_CONFIG(byte, u8) +PCI_USER_WRITE_CONFIG(word, u16) +PCI_USER_WRITE_CONFIG(dword, u32) + +/** + * pci_block_user_cfg_access - Block userspace PCI config reads/writes + * @dev: pci device struct + * + * This function blocks any userspace PCI config accesses from occurring. + * When blocked, any writes will be bit bucketed and reads will return the + * data saved using pci_save_state for the first 64 bytes of config + * space and return 0xff for all other config reads. + **/ +void pci_block_user_cfg_access(struct pci_dev *dev) +{ + unsigned long flags; + + pci_save_state(dev); + + /* spinlock to synchronize with anyone reading config space now */ + spin_lock_irqsave(&pci_lock, flags); + dev->block_ucfg_access = 1; + spin_unlock_irqrestore(&pci_lock, flags); +} +EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); + +/** + * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes + * @dev: pci device struct + * + * This function allows userspace PCI config accesses to resume. + **/ +void pci_unblock_user_cfg_access(struct pci_dev *dev) +{ + unsigned long flags; + + /* spinlock to synchronize with anyone reading saved config space */ + spin_lock_irqsave(&pci_lock, flags); + dev->block_ucfg_access = 0; + spin_unlock_irqrestore(&pci_lock, flags); +} +EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 2898830c496f..965a5934623a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 1) && size) { u8 val; - pci_read_config_byte(dev, off, &val); + pci_user_read_config_byte(dev, off, &val); data[off - init_off] = val; off++; size--; @@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 3) && size > 2) { u16 val; - pci_read_config_word(dev, off, &val); + pci_user_read_config_word(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; off += 2; @@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) while (size > 3) { u32 val; - pci_read_config_dword(dev, off, &val); + pci_user_read_config_dword(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; data[off - init_off + 2] = (val >> 16) & 0xff; @@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size >= 2) { u16 val; - pci_read_config_word(dev, off, &val); + pci_user_read_config_word(dev, off, &val); data[off - init_off] = val & 0xff; data[off - init_off + 1] = (val >> 8) & 0xff; off += 2; @@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size > 0) { u8 val; - pci_read_config_byte(dev, off, &val); + pci_user_read_config_byte(dev, off, &val); data[off - init_off] = val; off++; --size; @@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) } if ((off & 1) && size) { - pci_write_config_byte(dev, off, data[off - init_off]); + pci_user_write_config_byte(dev, off, data[off - init_off]); off++; size--; } @@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if ((off & 3) && size > 2) { u16 val = data[off - init_off]; val |= (u16) data[off - init_off + 1] << 8; - pci_write_config_word(dev, off, val); + pci_user_write_config_word(dev, off, val); off += 2; size -= 2; } @@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) val |= (u32) data[off - init_off + 1] << 8; val |= (u32) data[off - init_off + 2] << 16; val |= (u32) data[off - init_off + 3] << 24; - pci_write_config_dword(dev, off, val); + pci_user_write_config_dword(dev, off, val); off += 4; size -= 4; } @@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count) if (size >= 2) { u16 val = data[off - init_off]; val |= (u16) data[off - init_off + 1] << 8; - pci_write_config_word(dev, off, val); + pci_user_write_config_word(dev, off, val); off += 2; size -= 2; } if (size) { - pci_write_config_byte(dev, off, data[off - init_off]); + pci_user_write_config_byte(dev, off, data[off - init_off]); off++; --size; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d3f3dd42240d..6527b36c9a61 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -15,6 +15,13 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); +extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); +extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); +extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); +extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); +extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); +extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); + /* PCI /proc functions */ #ifdef CONFIG_PROC_FS extern int pci_proc_attach_device(struct pci_dev *dev); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 9613f666c110..9eb465727fce 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -80,7 +80,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if ((pos & 1) && cnt) { unsigned char val; - pci_read_config_byte(dev, pos, &val); + pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; @@ -89,7 +89,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if ((pos & 3) && cnt > 2) { unsigned short val; - pci_read_config_word(dev, pos, &val); + pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (unsigned short __user *) buf); buf += 2; pos += 2; @@ -98,7 +98,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp while (cnt >= 4) { unsigned int val; - pci_read_config_dword(dev, pos, &val); + pci_user_read_config_dword(dev, pos, &val); __put_user(cpu_to_le32(val), (unsigned int __user *) buf); buf += 4; pos += 4; @@ -107,7 +107,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (cnt >= 2) { unsigned short val; - pci_read_config_word(dev, pos, &val); + pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (unsigned short __user *) buf); buf += 2; pos += 2; @@ -116,7 +116,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (cnt) { unsigned char val; - pci_read_config_byte(dev, pos, &val); + pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; @@ -151,7 +151,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if ((pos & 1) && cnt) { unsigned char val; __get_user(val, buf); - pci_write_config_byte(dev, pos, val); + pci_user_write_config_byte(dev, pos, val); buf++; pos++; cnt--; @@ -160,7 +160,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if ((pos & 3) && cnt > 2) { unsigned short val; __get_user(val, (unsigned short __user *) buf); - pci_write_config_word(dev, pos, le16_to_cpu(val)); + pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; cnt -= 2; @@ -169,7 +169,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof while (cnt >= 4) { unsigned int val; __get_user(val, (unsigned int __user *) buf); - pci_write_config_dword(dev, pos, le32_to_cpu(val)); + pci_user_write_config_dword(dev, pos, le32_to_cpu(val)); buf += 4; pos += 4; cnt -= 4; @@ -178,7 +178,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (cnt >= 2) { unsigned short val; __get_user(val, (unsigned short __user *) buf); - pci_write_config_word(dev, pos, le16_to_cpu(val)); + pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; cnt -= 2; @@ -187,7 +187,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (cnt) { unsigned char val; __get_user(val, buf); - pci_write_config_byte(dev, pos, val); + pci_user_write_config_byte(dev, pos, val); buf++; pos++; cnt--; @@ -484,10 +484,10 @@ static int show_dev_config(struct seq_file *m, void *v) drv = pci_dev_driver(dev); - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); - pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); - pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat); + pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); + pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); + pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat); seq_printf(m, " Bus %2d, device %3d, function %2d:\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); seq_printf(m, " Class %04x", class_rev >> 16); diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index c071790cc983..87fafc08cb9d 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -13,7 +13,7 @@ #include #include #include - +#include "pci.h" asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, @@ -38,13 +38,13 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, lock_kernel(); switch (len) { case 1: - cfg_ret = pci_read_config_byte(dev, off, &byte); + cfg_ret = pci_user_read_config_byte(dev, off, &byte); break; case 2: - cfg_ret = pci_read_config_word(dev, off, &word); + cfg_ret = pci_user_read_config_word(dev, off, &word); break; case 4: - cfg_ret = pci_read_config_dword(dev, off, &dword); + cfg_ret = pci_user_read_config_dword(dev, off, &dword); break; default: err = -EINVAL; @@ -112,7 +112,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(byte, (u8 __user *)buf); if (err) break; - err = pci_write_config_byte(dev, off, byte); + err = pci_user_write_config_byte(dev, off, byte); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; @@ -121,7 +121,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(word, (u16 __user *)buf); if (err) break; - err = pci_write_config_word(dev, off, word); + err = pci_user_write_config_word(dev, off, word); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; @@ -130,7 +130,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, err = get_user(dword, (u32 __user *)buf); if (err) break; - err = pci_write_config_dword(dev, off, dword); + err = pci_user_write_config_dword(dev, off, dword); if (err != PCIBIOS_SUCCESSFUL) err = -EIO; break; diff --git a/include/linux/pci.h b/include/linux/pci.h index 7349058ed778..3596ac94ecff 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -132,6 +132,7 @@ struct pci_dev { unsigned int is_enabled:1; /* pci_enable_device has been called */ unsigned int is_busmaster:1; /* device is busmaster */ unsigned int no_msi:1; /* device may not use msi */ + unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ u32 saved_config_space[16]; /* config space saved at suspend time */ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ @@ -490,6 +491,9 @@ extern void pci_disable_msix(struct pci_dev *dev); extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); #endif +extern void pci_block_user_cfg_access(struct pci_dev *dev); +extern void pci_unblock_user_cfg_access(struct pci_dev *dev); + /* * PCI domain support. Sometimes called PCI segment (eg by ACPI), * a PCI domain is defined to be a set of PCI busses which share @@ -560,6 +564,9 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) +static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } +static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } + #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ -- cgit v1.2.3 From b135c4815051bad6b2472e4ad0152f205918d2c5 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 29 Sep 2005 10:39:46 +1000 Subject: [PATCH] pci_ids: remove duplicates from pci_ids.h pci_ids.h cleanup: remove duplicated entries and change some defines to explicit value rather than in terms of another constant, preparation for removing unused symbols Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman include/linux/pci_ids.h | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) --- include/linux/pci_ids.h | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 71834f05504f..0631074954f7 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -274,7 +274,6 @@ #define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050 #define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051 #define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052 -#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452 #define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053 #define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054 #define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055 @@ -517,16 +516,16 @@ #define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 #define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414 #define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440 -# define PCI_DEVICE_ID_AMD_VIPER_7440 PCI_DEVICE_ID_AMD_OPUS_7440 +#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 #define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 -# define PCI_DEVICE_ID_AMD_VIPER_7441 PCI_DEVICE_ID_AMD_OPUS_7441 +#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441 #define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 -# define PCI_DEVICE_ID_AMD_VIPER_7443 PCI_DEVICE_ID_AMD_OPUS_7443 +#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 #define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 #define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448 -# define PCI_DEVICE_ID_AMD_VIPER_7448 PCI_DEVICE_ID_AMD_OPUS_7448 +#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448 #define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449 -# define PCI_DEVICE_ID_AMD_VIPER_7449 PCI_DEVICE_ID_AMD_OPUS_7449 +#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449 #define PCI_DEVICE_ID_AMD_8111_LAN 0x7462 #define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 @@ -585,7 +584,6 @@ #define PCI_DEVICE_ID_CT_65550 0x00e0 #define PCI_DEVICE_ID_CT_65554 0x00e4 #define PCI_DEVICE_ID_CT_65555 0x00e5 -#define PCI_DEVICE_ID_CT_69000 0x00c0 #define PCI_VENDOR_ID_MIRO 0x1031 #define PCI_DEVICE_ID_MIRO_36050 0x5601 @@ -1197,7 +1195,6 @@ #define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc #define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 -#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 #define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 @@ -1623,7 +1620,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB +#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB 0x0220 #define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 #define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 @@ -1792,10 +1789,6 @@ #define PCI_DEVICE_ID_PC300_TE_M_2 0x0320 #define PCI_DEVICE_ID_PC300_TE_M_1 0x0321 -/* Allied Telesyn */ -#define PCI_VENDOR_ID_AT 0x1259 -#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 - #define PCI_VENDOR_ID_ESSENTIAL 0x120f #define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 @@ -2340,16 +2333,13 @@ #define PCI_VENDOR_ID_DUNORD 0x5544 #define PCI_DEVICE_ID_DUNORD_I3000 0x0001 +#define PCI_VENDOR_ID_GENROCO 0x5555 +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 + #define PCI_VENDOR_ID_DCI 0x6666 #define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 #define PCI_DEVICE_ID_DCI_PCCOM8 0x0002 -#define PCI_VENDOR_ID_DUNORD 0x5544 -#define PCI_DEVICE_ID_DUNORD_I3000 0x0001 - -#define PCI_VENDOR_ID_GENROCO 0x5555 -#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 - #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 #define PCI_DEVICE_ID_INTEL_21145 0x0039 -- cgit v1.2.3 From b7924c38c9a9c6151213bc0d91776eace614e761 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 29 Sep 2005 11:06:40 +1000 Subject: [PATCH] pci_ids: remove non-referenced symbols from pci_ids.h pci_ids.h cleanup: removed non-referenced symbols, compile tested with 'make allmodconfig' Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman include/linux/pci_ids.h | 540 ------------------------------------------------ 1 file changed, 540 deletions(-) --- include/linux/pci_ids.h | 540 ------------------------------------------------ 1 file changed, 540 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0631074954f7..11fed60a928d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -132,9 +132,6 @@ #define PCI_VENDOR_ID_COMPAQ 0x0e11 #define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 -#define PCI_DEVICE_ID_COMPAQ_1280 0x3033 -#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000 -#define PCI_DEVICE_ID_COMPAQ_6010 0x6010 #define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 #define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 @@ -281,8 +278,6 @@ #define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057 #define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058 /* Rage128 M4 */ -#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45 -#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46 /* Radeon R100 */ #define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 #define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 @@ -303,32 +298,22 @@ #define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 #define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 /* Radeon NV-100 */ -#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159 -#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a /* Radeon RV250 (9000) */ #define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 #define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 #define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 #define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 /* Radeon RV280 (9200) */ -#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960 #define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961 #define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964 /* Radeon R300 (9500) */ -#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144 /* Radeon R300 (9700) */ #define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 #define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 #define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 #define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 -#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145 -#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146 /* Radeon R350 (9800) */ -#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48 -#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49 /* Radeon RV350 (9600) */ -#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150 -#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152 /* Radeon M6 */ #define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 #define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a @@ -341,10 +326,6 @@ #define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66 #define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67 /* Radeon */ -#define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144 -#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145 -#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146 -#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147 /* RadeonIGP */ #define PCI_DEVICE_ID_ATI_RS100 0xcab0 #define PCI_DEVICE_ID_ATI_RS200 0xcab2 @@ -445,34 +426,18 @@ #define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 #define PCI_DEVICE_ID_CIRRUS_6729 0x1100 #define PCI_DEVICE_ID_CIRRUS_6832 0x1110 -#define PCI_DEVICE_ID_CIRRUS_7542 0x1200 #define PCI_DEVICE_ID_CIRRUS_7543 0x1202 -#define PCI_DEVICE_ID_CIRRUS_7541 0x1204 #define PCI_DEVICE_ID_CIRRUS_4610 0x6001 #define PCI_DEVICE_ID_CIRRUS_4612 0x6003 #define PCI_DEVICE_ID_CIRRUS_4615 0x6004 -#define PCI_DEVICE_ID_CIRRUS_4281 0x6005 #define PCI_VENDOR_ID_IBM 0x1014 -#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a #define PCI_DEVICE_ID_IBM_TR 0x0018 -#define PCI_DEVICE_ID_IBM_82G2675 0x001d -#define PCI_DEVICE_ID_IBM_MCA 0x0020 -#define PCI_DEVICE_ID_IBM_82351 0x0022 -#define PCI_DEVICE_ID_IBM_PYTHON 0x002d -#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e #define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e -#define PCI_DEVICE_ID_IBM_MPIC 0x0046 -#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d -#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096 #define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc -#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105 -#define PCI_DEVICE_ID_IBM_405GP 0x0156 #define PCI_DEVICE_ID_IBM_SNIPE 0x0180 -#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd #define PCI_DEVICE_ID_IBM_CITRINE 0x028C #define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166 -#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031 #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219 #define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A @@ -483,7 +448,6 @@ #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 #define PCI_VENDOR_ID_WD 0x101c -#define PCI_DEVICE_ID_WD_7197 0x3296 #define PCI_DEVICE_ID_WD_90C 0xc24a #define PCI_VENDOR_ID_AMI 0x101e @@ -500,33 +464,18 @@ #define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006 #define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007 #define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C -#define PCI_DEVICE_ID_AMD_FE_GATE_700D 0x700D #define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E -#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F -#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400 #define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401 -#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403 -#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404 -#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408 #define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409 #define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B -#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C #define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410 #define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411 #define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 -#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414 -#define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440 #define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 #define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 -#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441 #define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 #define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 #define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 -#define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448 -#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448 -#define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449 -#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449 -#define PCI_DEVICE_ID_AMD_8111_LAN 0x7462 #define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 #define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a @@ -637,7 +586,6 @@ #define PCI_DEVICE_ID_SI_550 0x0550 #define PCI_DEVICE_ID_SI_540_VGA 0x5300 #define PCI_DEVICE_ID_SI_550_VGA 0x5315 -#define PCI_DEVICE_ID_SI_601 0x0601 #define PCI_DEVICE_ID_SI_620 0x0620 #define PCI_DEVICE_ID_SI_630 0x0630 #define PCI_DEVICE_ID_SI_633 0x0633 @@ -648,30 +596,22 @@ #define PCI_DEVICE_ID_SI_648 0x0648 #define PCI_DEVICE_ID_SI_650 0x0650 #define PCI_DEVICE_ID_SI_651 0x0651 -#define PCI_DEVICE_ID_SI_652 0x0652 #define PCI_DEVICE_ID_SI_655 0x0655 #define PCI_DEVICE_ID_SI_661 0x0661 #define PCI_DEVICE_ID_SI_730 0x0730 #define PCI_DEVICE_ID_SI_733 0x0733 #define PCI_DEVICE_ID_SI_630_VGA 0x6300 -#define PCI_DEVICE_ID_SI_730_VGA 0x7300 #define PCI_DEVICE_ID_SI_735 0x0735 #define PCI_DEVICE_ID_SI_740 0x0740 #define PCI_DEVICE_ID_SI_741 0x0741 #define PCI_DEVICE_ID_SI_745 0x0745 #define PCI_DEVICE_ID_SI_746 0x0746 -#define PCI_DEVICE_ID_SI_748 0x0748 -#define PCI_DEVICE_ID_SI_750 0x0750 -#define PCI_DEVICE_ID_SI_751 0x0751 -#define PCI_DEVICE_ID_SI_752 0x0752 #define PCI_DEVICE_ID_SI_755 0x0755 #define PCI_DEVICE_ID_SI_760 0x0760 #define PCI_DEVICE_ID_SI_900 0x0900 #define PCI_DEVICE_ID_SI_961 0x0961 #define PCI_DEVICE_ID_SI_962 0x0962 #define PCI_DEVICE_ID_SI_963 0x0963 -#define PCI_DEVICE_ID_SI_5107 0x5107 -#define PCI_DEVICE_ID_SI_5300 0x5300 #define PCI_DEVICE_ID_SI_5511 0x5511 #define PCI_DEVICE_ID_SI_5513 0x5513 #define PCI_DEVICE_ID_SI_5518 0x5518 @@ -683,10 +623,6 @@ #define PCI_DEVICE_ID_SI_5597 0x5597 #define PCI_DEVICE_ID_SI_5598 0x5598 #define PCI_DEVICE_ID_SI_5600 0x5600 -#define PCI_DEVICE_ID_SI_6300 0x6300 -#define PCI_DEVICE_ID_SI_6306 0x6306 -#define PCI_DEVICE_ID_SI_6326 0x6326 -#define PCI_DEVICE_ID_SI_7001 0x7001 #define PCI_DEVICE_ID_SI_7012 0x7012 #define PCI_DEVICE_ID_SI_7013 0x7013 #define PCI_DEVICE_ID_SI_7016 0x7016 @@ -707,14 +643,11 @@ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A #define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B -#define PCI_DEVICE_ID_HP_PCI_LBA 0x1054 -#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0 #define PCI_DEVICE_ID_HP_REO_IOC 0x10f1 #define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b #define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 #define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 -#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229 #define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a #define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e #define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c @@ -722,9 +655,7 @@ #define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290 #define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301 #define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a -#define PCI_DEVICE_ID_HP_CISS 0x3210 #define PCI_DEVICE_ID_HP_CISSA 0x3220 -#define PCI_DEVICE_ID_HP_CISSB 0x3222 #define PCI_DEVICE_ID_HP_CISSC 0x3230 #define PCI_DEVICE_ID_HP_CISSD 0x3238 #define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 @@ -732,8 +663,6 @@ #define PCI_VENDOR_ID_PCTECH 0x1042 #define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 #define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 -#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000 -#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010 #define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 #define PCI_VENDOR_ID_ASUSTEK 0x1043 @@ -743,24 +672,15 @@ #define PCI_DEVICE_ID_DPT 0xa400 #define PCI_VENDOR_ID_OPTI 0x1045 -#define PCI_DEVICE_ID_OPTI_92C178 0xc178 -#define PCI_DEVICE_ID_OPTI_82C557 0xc557 #define PCI_DEVICE_ID_OPTI_82C558 0xc558 #define PCI_DEVICE_ID_OPTI_82C621 0xc621 #define PCI_DEVICE_ID_OPTI_82C700 0xc700 -#define PCI_DEVICE_ID_OPTI_82C701 0xc701 -#define PCI_DEVICE_ID_OPTI_82C814 0xc814 -#define PCI_DEVICE_ID_OPTI_82C822 0xc822 -#define PCI_DEVICE_ID_OPTI_82C861 0xc861 #define PCI_DEVICE_ID_OPTI_82C825 0xd568 #define PCI_VENDOR_ID_ELSA 0x1048 #define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 #define PCI_DEVICE_ID_ELSA_QS3000 0x3000 -#define PCI_VENDOR_ID_SGS 0x104a -#define PCI_DEVICE_ID_SGS_2000 0x0008 -#define PCI_DEVICE_ID_SGS_1764 0x0009 #define PCI_VENDOR_ID_BUSLOGIC 0x104B #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 @@ -768,7 +688,6 @@ #define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 #define PCI_VENDOR_ID_TI 0x104c -#define PCI_DEVICE_ID_TI_TVP4010 0x3d04 #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 #define PCI_DEVICE_ID_TI_4450 0x8011 #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 @@ -802,14 +721,10 @@ #define PCI_DEVICE_ID_TI_X420 0xac8e #define PCI_VENDOR_ID_SONY 0x104d -#define PCI_DEVICE_ID_SONY_CXD3222 0x8039 -#define PCI_VENDOR_ID_OAK 0x104e -#define PCI_DEVICE_ID_OAK_OTI107 0x0107 /* Winbond have two vendor IDs! See 0x10ad as well */ #define PCI_VENDOR_ID_WINBOND2 0x1050 -#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 #define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a #define PCI_DEVICE_ID_WINBOND2_6692 0x6692 @@ -818,19 +733,15 @@ #define PCI_VENDOR_ID_EFAR 0x1055 #define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 -#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 -#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462 #define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 #define PCI_VENDOR_ID_MOTOROLA 0x1057 -#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507 #define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 #define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 #define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004 #define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 #define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 #define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 -#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806 #define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b #define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 @@ -841,33 +752,19 @@ #define PCI_DEVICE_ID_PROMISE_20262 0x4d38 #define PCI_DEVICE_ID_PROMISE_20263 0x0D38 #define PCI_DEVICE_ID_PROMISE_20268 0x4d68 -#define PCI_DEVICE_ID_PROMISE_20268R 0x6268 #define PCI_DEVICE_ID_PROMISE_20269 0x4d69 #define PCI_DEVICE_ID_PROMISE_20270 0x6268 #define PCI_DEVICE_ID_PROMISE_20271 0x6269 #define PCI_DEVICE_ID_PROMISE_20275 0x1275 #define PCI_DEVICE_ID_PROMISE_20276 0x5275 #define PCI_DEVICE_ID_PROMISE_20277 0x7275 -#define PCI_DEVICE_ID_PROMISE_5300 0x5300 -#define PCI_VENDOR_ID_N9 0x105d -#define PCI_DEVICE_ID_N9_I128 0x2309 -#define PCI_DEVICE_ID_N9_I128_2 0x2339 -#define PCI_DEVICE_ID_N9_I128_T2R 0x493d #define PCI_VENDOR_ID_UMC 0x1060 #define PCI_DEVICE_ID_UMC_UM8673F 0x0101 -#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 #define PCI_DEVICE_ID_UMC_UM8886BF 0x673a #define PCI_DEVICE_ID_UMC_UM8886A 0x886a -#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 -#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 -#define PCI_DEVICE_ID_UMC_UM9017F 0x9017 -#define PCI_DEVICE_ID_UMC_UM8886N 0xe886 -#define PCI_DEVICE_ID_UMC_UM8891N 0xe891 -#define PCI_VENDOR_ID_X 0x1061 -#define PCI_DEVICE_ID_X_AGX016 0x0001 #define PCI_VENDOR_ID_MYLEX 0x1069 #define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001 @@ -878,37 +775,26 @@ #define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 #define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166 -#define PCI_VENDOR_ID_PICOP 0x1066 -#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 -#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002 #define PCI_VENDOR_ID_APPLE 0x106b #define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 -#define PCI_DEVICE_ID_APPLE_GC 0x0002 #define PCI_DEVICE_ID_APPLE_HYDRA 0x000e #define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 -#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 -#define PCI_DEVICE_ID_APPLE_KEYLARGO 0x0022 #define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024 -#define PCI_DEVICE_ID_APPLE_KEYLARGO_P 0x0025 -#define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e -#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 #define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 #define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b -#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e #define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043 #define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b #define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c #define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050 #define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 -#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052 #define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058 #define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059 #define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 @@ -921,12 +807,9 @@ #define PCI_DEVICE_ID_YAMAHA_744 0x0010 #define PCI_DEVICE_ID_YAMAHA_754 0x0012 -#define PCI_VENDOR_ID_NEXGEN 0x1074 -#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 #define PCI_VENDOR_ID_QLOGIC 0x1077 #define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 -#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 #define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 #define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 #define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 @@ -944,32 +827,20 @@ #define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 #define PCI_DEVICE_ID_CYRIX_5520 0x0002 #define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 -#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101 #define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 #define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 #define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 -#define PCI_VENDOR_ID_LEADTEK 0x107d -#define PCI_DEVICE_ID_LEADTEK_805 0x0000 -#define PCI_VENDOR_ID_INTERPHASE 0x107e -#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004 -#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005 -#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008 #define PCI_VENDOR_ID_CONTAQ 0x1080 -#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 #define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 -#define PCI_VENDOR_ID_FOREX 0x1083 #define PCI_VENDOR_ID_OLICOM 0x108d -#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001 -#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011 #define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 #define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 #define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 -#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021 #define PCI_VENDOR_ID_SUN 0x108e #define PCI_DEVICE_ID_SUN_EBUS 0x1000 @@ -988,49 +859,31 @@ #define PCI_DEVICE_ID_SUN_CASSINI 0xabba #define PCI_VENDOR_ID_CMD 0x1095 -#define PCI_DEVICE_ID_CMD_640 0x0640 #define PCI_DEVICE_ID_CMD_643 0x0643 #define PCI_DEVICE_ID_CMD_646 0x0646 -#define PCI_DEVICE_ID_CMD_647 0x0647 #define PCI_DEVICE_ID_CMD_648 0x0648 #define PCI_DEVICE_ID_CMD_649 0x0649 -#define PCI_DEVICE_ID_CMD_670 0x0670 -#define PCI_DEVICE_ID_CMD_680 0x0680 #define PCI_DEVICE_ID_SII_680 0x0680 #define PCI_DEVICE_ID_SII_3112 0x3112 #define PCI_DEVICE_ID_SII_1210SA 0x0240 -#define PCI_VENDOR_ID_VISION 0x1098 -#define PCI_DEVICE_ID_VISION_QD8500 0x0001 -#define PCI_DEVICE_ID_VISION_QD8580 0x0002 #define PCI_VENDOR_ID_BROOKTREE 0x109e -#define PCI_DEVICE_ID_BROOKTREE_848 0x0350 -#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351 -#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e #define PCI_DEVICE_ID_BROOKTREE_878 0x0878 #define PCI_DEVICE_ID_BROOKTREE_879 0x0879 -#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474 -#define PCI_VENDOR_ID_SIERRA 0x10a8 -#define PCI_DEVICE_ID_SIERRA_STB 0x0000 #define PCI_VENDOR_ID_SGI 0x10a9 #define PCI_DEVICE_ID_SGI_IOC3 0x0003 #define PCI_DEVICE_ID_SGI_IOC4 0x100a #define PCI_VENDOR_ID_SGI_LITHIUM 0x1002 -#define PCI_VENDOR_ID_ACC 0x10aa -#define PCI_DEVICE_ID_ACC_2056 0x0000 #define PCI_VENDOR_ID_WINBOND 0x10ad -#define PCI_DEVICE_ID_WINBOND_83769 0x0001 #define PCI_DEVICE_ID_WINBOND_82C105 0x0105 #define PCI_DEVICE_ID_WINBOND_83C553 0x0565 -#define PCI_VENDOR_ID_DATABOOK 0x10b3 -#define PCI_DEVICE_ID_DATABOOK_87144 0xb106 #define PCI_VENDOR_ID_PLX 0x10b5 #define PCI_DEVICE_ID_PLX_R685 0x1030 @@ -1041,33 +894,19 @@ #define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 #define PCI_DEVICE_ID_PLX_R753 0x1152 #define PCI_DEVICE_ID_PLX_OLITEC 0x1187 -#define PCI_DEVICE_ID_PLX_9030 0x9030 #define PCI_DEVICE_ID_PLX_9050 0x9050 -#define PCI_DEVICE_ID_PLX_9060 0x9060 -#define PCI_DEVICE_ID_PLX_9060ES 0x906E -#define PCI_DEVICE_ID_PLX_9060SD 0x906D #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 #define PCI_VENDOR_ID_MADGE 0x10b6 #define PCI_DEVICE_ID_MADGE_MK2 0x0002 -#define PCI_DEVICE_ID_MADGE_C155S 0x1001 #define PCI_VENDOR_ID_3COM 0x10b7 #define PCI_DEVICE_ID_3COM_3C985 0x0001 #define PCI_DEVICE_ID_3COM_3C940 0x1700 #define PCI_DEVICE_ID_3COM_3C339 0x3390 #define PCI_DEVICE_ID_3COM_3C359 0x3590 -#define PCI_DEVICE_ID_3COM_3C590 0x5900 -#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 -#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 -#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 #define PCI_DEVICE_ID_3COM_3C940B 0x80eb -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 #define PCI_DEVICE_ID_3COM_3CR990 0x9900 #define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902 #define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903 @@ -1077,24 +916,11 @@ #define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909 #define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a -#define PCI_VENDOR_ID_SMC 0x10b8 -#define PCI_DEVICE_ID_SMC_EPIC100 0x0005 #define PCI_VENDOR_ID_AL 0x10b9 -#define PCI_DEVICE_ID_AL_M1445 0x1445 -#define PCI_DEVICE_ID_AL_M1449 0x1449 -#define PCI_DEVICE_ID_AL_M1451 0x1451 -#define PCI_DEVICE_ID_AL_M1461 0x1461 -#define PCI_DEVICE_ID_AL_M1489 0x1489 -#define PCI_DEVICE_ID_AL_M1511 0x1511 -#define PCI_DEVICE_ID_AL_M1513 0x1513 -#define PCI_DEVICE_ID_AL_M1521 0x1521 -#define PCI_DEVICE_ID_AL_M1523 0x1523 -#define PCI_DEVICE_ID_AL_M1531 0x1531 #define PCI_DEVICE_ID_AL_M1533 0x1533 #define PCI_DEVICE_ID_AL_M1535 0x1535 #define PCI_DEVICE_ID_AL_M1541 0x1541 -#define PCI_DEVICE_ID_AL_M1543 0x1543 #define PCI_DEVICE_ID_AL_M1563 0x1563 #define PCI_DEVICE_ID_AL_M1621 0x1621 #define PCI_DEVICE_ID_AL_M1631 0x1631 @@ -1107,49 +933,23 @@ #define PCI_DEVICE_ID_AL_M1681 0x1681 #define PCI_DEVICE_ID_AL_M1683 0x1683 #define PCI_DEVICE_ID_AL_M1689 0x1689 -#define PCI_DEVICE_ID_AL_M3307 0x3307 -#define PCI_DEVICE_ID_AL_M4803 0x5215 #define PCI_DEVICE_ID_AL_M5219 0x5219 #define PCI_DEVICE_ID_AL_M5228 0x5228 #define PCI_DEVICE_ID_AL_M5229 0x5229 -#define PCI_DEVICE_ID_AL_M5237 0x5237 -#define PCI_DEVICE_ID_AL_M5243 0x5243 #define PCI_DEVICE_ID_AL_M5451 0x5451 #define PCI_DEVICE_ID_AL_M7101 0x7101 -#define PCI_VENDOR_ID_MITSUBISHI 0x10ba -#define PCI_VENDOR_ID_SURECOM 0x10bd -#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34 #define PCI_VENDOR_ID_NEOMAGIC 0x10c8 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005 -#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083 #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 #define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 -#define PCI_VENDOR_ID_ASP 0x10cd -#define PCI_DEVICE_ID_ASP_ABP940 0x1200 -#define PCI_DEVICE_ID_ASP_ABP940U 0x1300 -#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300 - -#define PCI_VENDOR_ID_MACRONIX 0x10d9 -#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512 -#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531 #define PCI_VENDOR_ID_TCONRAD 0x10da #define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 -#define PCI_VENDOR_ID_CERN 0x10dc -#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001 -#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002 -#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021 -#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022 #define PCI_VENDOR_ID_NVIDIA 0x10de #define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 @@ -1281,7 +1081,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 -#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 @@ -1332,24 +1131,13 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 #define PCI_VENDOR_ID_IMS 0x10e0 -#define PCI_DEVICE_ID_IMS_8849 0x8849 #define PCI_DEVICE_ID_IMS_TT128 0x9128 #define PCI_DEVICE_ID_IMS_TT3D 0x9135 -#define PCI_VENDOR_ID_TEKRAM2 0x10e1 -#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000 -#define PCI_VENDOR_ID_AMCC 0x10e8 -#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 -#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062 -#define PCI_DEVICE_ID_AMCC_S5933 0x807d -#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c #define PCI_VENDOR_ID_INTERG 0x10ea -#define PCI_DEVICE_ID_INTERG_1680 0x1680 #define PCI_DEVICE_ID_INTERG_1682 0x1682 #define PCI_DEVICE_ID_INTERG_2000 0x2000 #define PCI_DEVICE_ID_INTERG_2010 0x2010 @@ -1357,27 +1145,18 @@ #define PCI_DEVICE_ID_INTERG_5050 0x5050 #define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_DEVICE_ID_REALTEK_8029 0x8029 -#define PCI_DEVICE_ID_REALTEK_8129 0x8129 #define PCI_DEVICE_ID_REALTEK_8139 0x8139 -#define PCI_DEVICE_ID_REALTEK_8169 0x8169 #define PCI_VENDOR_ID_XILINX 0x10ee #define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 #define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1 #define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2 #define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3 -#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 -#define PCI_DEVICE_ID_TURBOPAM 0x4020 -#define PCI_VENDOR_ID_TRUEVISION 0x10fa -#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c #define PCI_VENDOR_ID_INIT 0x1101 -#define PCI_DEVICE_ID_INIT_320P 0x9100 -#define PCI_DEVICE_ID_INIT_360P 0x9500 #define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 @@ -1405,36 +1184,25 @@ #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 -#define PCI_DEVICE_ID_VIA_82C505 0x0505 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 #define PCI_DEVICE_ID_VIA_82C576 0x0576 -#define PCI_DEVICE_ID_VIA_82C585 0x0585 #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 -#define PCI_DEVICE_ID_VIA_82C595 0x0595 #define PCI_DEVICE_ID_VIA_82C596 0x0596 #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 #define PCI_DEVICE_ID_VIA_82C598_0 0x0598 #define PCI_DEVICE_ID_VIA_8601_0 0x0601 #define PCI_DEVICE_ID_VIA_8605_0 0x0605 -#define PCI_DEVICE_ID_VIA_82C680 0x0680 #define PCI_DEVICE_ID_VIA_82C686 0x0686 #define PCI_DEVICE_ID_VIA_82C691_0 0x0691 -#define PCI_DEVICE_ID_VIA_82C693 0x0693 -#define PCI_DEVICE_ID_VIA_82C693_1 0x0698 -#define PCI_DEVICE_ID_VIA_82C926 0x0926 #define PCI_DEVICE_ID_VIA_82C576_1 0x1571 -#define PCI_DEVICE_ID_VIA_82C595_97 0x1595 #define PCI_DEVICE_ID_VIA_82C586_2 0x3038 #define PCI_DEVICE_ID_VIA_82C586_3 0x3040 -#define PCI_DEVICE_ID_VIA_6305 0x3044 #define PCI_DEVICE_ID_VIA_82C596_3 0x3050 #define PCI_DEVICE_ID_VIA_82C596B_3 0x3051 #define PCI_DEVICE_ID_VIA_82C686_4 0x3057 #define PCI_DEVICE_ID_VIA_82C686_5 0x3058 #define PCI_DEVICE_ID_VIA_8233_5 0x3059 -#define PCI_DEVICE_ID_VIA_8233_7 0x3065 -#define PCI_DEVICE_ID_VIA_82C686_6 0x3068 #define PCI_DEVICE_ID_VIA_8233_0 0x3074 #define PCI_DEVICE_ID_VIA_8633_0 0x3091 #define PCI_DEVICE_ID_VIA_8367_0 0x3099 @@ -1452,38 +1220,23 @@ #define PCI_DEVICE_ID_VIA_XN266 0x3156 #define PCI_DEVICE_ID_VIA_8754C_0 0x3168 #define PCI_DEVICE_ID_VIA_8235 0x3177 -#define PCI_DEVICE_ID_VIA_P4N333 0x3178 #define PCI_DEVICE_ID_VIA_8385_0 0x3188 #define PCI_DEVICE_ID_VIA_8377_0 0x3189 #define PCI_DEVICE_ID_VIA_8378_0 0x3205 #define PCI_DEVICE_ID_VIA_8783_0 0x3208 -#define PCI_DEVICE_ID_VIA_P4M400 0x3209 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_3296_0 0x0296 -#define PCI_DEVICE_ID_VIA_86C100A 0x6100 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 -#define PCI_DEVICE_ID_VIA_8501_1 0x8501 -#define PCI_DEVICE_ID_VIA_82C597_1 0x8597 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 -#define PCI_DEVICE_ID_VIA_8601_1 0x8601 -#define PCI_DEVICE_ID_VIA_8505_1 0x8605 -#define PCI_DEVICE_ID_VIA_8633_1 0xB091 -#define PCI_DEVICE_ID_VIA_8367_1 0xB099 -#define PCI_DEVICE_ID_VIA_P4X266_1 0xB101 -#define PCI_DEVICE_ID_VIA_8615_1 0xB103 -#define PCI_DEVICE_ID_VIA_8361_1 0xB112 -#define PCI_DEVICE_ID_VIA_8235_1 0xB168 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 #define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 -#define PCI_VENDOR_ID_SMC2 0x1113 -#define PCI_DEVICE_ID_SMC2_1211TX 0x1211 #define PCI_VENDOR_ID_VORTEX 0x1119 #define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 @@ -1506,18 +1259,6 @@ #define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 #define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 #define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110 -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111 -#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112 -#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113 -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114 -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115 -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120 -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121 -#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122 -#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123 -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124 -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125 #define PCI_VENDOR_ID_EF 0x111a #define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 @@ -1529,21 +1270,15 @@ #define PCI_DEVICE_ID_IDT_IDT77201 0x0001 #define PCI_VENDOR_ID_FORE 0x1127 -#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 #define PCI_DEVICE_ID_FORE_PCA200E 0x0300 -#define PCI_VENDOR_ID_IMAGINGTECH 0x112f -#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 #define PCI_VENDOR_ID_PHILIPS 0x1131 -#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145 #define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 #define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730 #define PCI_VENDOR_ID_EICON 0x1133 -#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001 #define PCI_DEVICE_ID_EICON_DIVA20 0xe002 -#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003 #define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004 #define PCI_DEVICE_ID_EICON_DIVA201 0xe005 #define PCI_DEVICE_ID_EICON_DIVA202 0xe00b @@ -1555,35 +1290,17 @@ #define PCI_VENDOR_ID_ZIATECH 0x1138 #define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 -#define PCI_VENDOR_ID_CYCLONE 0x113c -#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001 -#define PCI_VENDOR_ID_ALLIANCE 0x1142 -#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210 -#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422 -#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424 -#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d #define PCI_VENDOR_ID_SYSKONNECT 0x1148 -#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000 #define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 #define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 #define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 #define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400 #define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500 -#define PCI_VENDOR_ID_VMIC 0x114a -#define PCI_DEVICE_ID_VMIC_VME 0x7587 #define PCI_VENDOR_ID_DIGI 0x114f -#define PCI_DEVICE_ID_DIGI_EPC 0x0002 -#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003 -#define PCI_DEVICE_ID_DIGI_XEM 0x0004 -#define PCI_DEVICE_ID_DIGI_XR 0x0005 -#define PCI_DEVICE_ID_DIGI_CX 0x0006 -#define PCI_DEVICE_ID_DIGI_XRJ 0x0009 -#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a -#define PCI_DEVICE_ID_DIGI_XR_920 0x0027 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070 #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 @@ -1593,23 +1310,15 @@ #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA #define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB -#define PCI_VENDOR_ID_MUTECH 0x1159 -#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 #define PCI_VENDOR_ID_XIRCOM 0x115d -#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003 #define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101 #define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103 -#define PCI_VENDOR_ID_RENDITION 0x1163 -#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 -#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 #define PCI_VENDOR_ID_SERVERWORKS 0x1166 #define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 -#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010 -#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 @@ -1619,13 +1328,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 -#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB 0x0220 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 -#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 -#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230 #define PCI_VENDOR_ID_SBE 0x1176 #define PCI_DEVICE_ID_SBE_WANXL100 0x0301 @@ -1636,17 +1339,12 @@ #define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102 #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103 #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105 -#define PCI_DEVICE_ID_TOSHIBA_601 0x0601 #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603 -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a #define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f #define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617 #define PCI_VENDOR_ID_TOSHIBA_2 0x102f -#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a #define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 -#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180 #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 @@ -1661,7 +1359,6 @@ #define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 #define PCI_VENDOR_ID_ARTOP 0x1191 -#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 #define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 #define PCI_DEVICE_ID_ARTOP_ATP860 0x0006 #define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 @@ -1674,16 +1371,11 @@ #define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040 #define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050 #define PCI_DEVICE_ID_ARTOP_8060 0x8060 -#define PCI_DEVICE_ID_ARTOP_AEC67160 0x8080 -#define PCI_DEVICE_ID_ARTOP_AEC67160_2 0x8081 -#define PCI_DEVICE_ID_ARTOP_AEC67162 0x808a #define PCI_VENDOR_ID_ZEITNET 0x1193 #define PCI_DEVICE_ID_ZEITNET_1221 0x0001 #define PCI_DEVICE_ID_ZEITNET_1225 0x0002 -#define PCI_VENDOR_ID_OMEGA 0x119b -#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221 #define PCI_VENDOR_ID_FUJITSU_ME 0x119e #define PCI_DEVICE_ID_FUJITSU_FS155 0x0001 @@ -1693,61 +1385,41 @@ #define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 #define PCI_VENDOR_ID_MARVELL 0x11ab -#define PCI_DEVICE_ID_MARVELL_GT64011 0x4146 -#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 #define PCI_DEVICE_ID_MARVELL_GT96100 0x9652 #define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653 -#define PCI_VENDOR_ID_LITEON 0x11ad -#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002 #define PCI_VENDOR_ID_V3 0x11b0 #define PCI_DEVICE_ID_V3_V960 0x0001 -#define PCI_DEVICE_ID_V3_V350 0x0001 -#define PCI_DEVICE_ID_V3_V961 0x0002 #define PCI_DEVICE_ID_V3_V351 0x0002 -#define PCI_VENDOR_ID_NP 0x11bc -#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001 #define PCI_VENDOR_ID_ATT 0x11c1 -#define PCI_DEVICE_ID_ATT_L56XMF 0x0440 #define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 -#define PCI_VENDOR_ID_NEC2 0x11c3 /* NEC (2nd) */ #define PCI_VENDOR_ID_SPECIALIX 0x11cb #define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 -#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000 #define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 #define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 -#define PCI_VENDOR_ID_AURAVISION 0x11d1 -#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7 #define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 #define PCI_DEVICE_ID_AD1889JS 0x1889 -#define PCI_VENDOR_ID_IKON 0x11d5 -#define PCI_DEVICE_ID_IKON_10115 0x0115 -#define PCI_DEVICE_ID_IKON_10117 0x0117 -#define PCI_VENDOR_ID_SEGA 0x11db #define PCI_DEVICE_ID_SEGA_BBA 0x1234 #define PCI_VENDOR_ID_ZORAN 0x11de #define PCI_DEVICE_ID_ZORAN_36057 0x6057 #define PCI_DEVICE_ID_ZORAN_36120 0x6120 -#define PCI_VENDOR_ID_KINETIC 0x11f4 -#define PCI_DEVICE_ID_KINETIC_2915 0x2915 #define PCI_VENDOR_ID_COMPEX 0x11f6 #define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 -#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 #define PCI_VENDOR_ID_RP 0x11fe #define PCI_DEVICE_ID_RP32INTF 0x0001 @@ -1761,7 +1433,6 @@ #define PCI_DEVICE_ID_RP16SNI 0x0009 #define PCI_DEVICE_ID_RPP4 0x000A #define PCI_DEVICE_ID_RPP8 0x000B -#define PCI_DEVICE_ID_RP8M 0x000C #define PCI_DEVICE_ID_RP4M 0x000D #define PCI_DEVICE_ID_RP2_232 0x000E #define PCI_DEVICE_ID_RP2_422 0x000F @@ -1805,10 +1476,7 @@ #define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005 #define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 -#define PCI_VENDOR_ID_SIGMADES 0x1236 -#define PCI_DEVICE_ID_SIGMADES_6425 0x6401 -#define PCI_VENDOR_ID_CCUBE 0x123f #define PCI_VENDOR_ID_AVM 0x1244 #define PCI_DEVICE_ID_AVM_B1 0x0700 @@ -1818,19 +1486,8 @@ #define PCI_DEVICE_ID_AVM_C2 0x1100 #define PCI_DEVICE_ID_AVM_T1 0x1200 -#define PCI_VENDOR_ID_DIPIX 0x1246 #define PCI_VENDOR_ID_STALLION 0x124d -#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000 -#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002 -#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003 - -#define PCI_VENDOR_ID_OPTIBASE 0x1255 -#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110 -#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210 -#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110 -#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120 -#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130 /* Allied Telesyn */ #define PCI_VENDOR_ID_AT 0x1259 @@ -1839,7 +1496,6 @@ #define PCI_VENDOR_ID_ESS 0x125d #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 -#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969 #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 #define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988 #define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989 @@ -1852,11 +1508,7 @@ #define PCI_VENDOR_ID_SATSAGEM 0x1267 #define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 -#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352 -#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b -#define PCI_VENDOR_ID_HUGHES 0x1273 -#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002 #define PCI_VENDOR_ID_ENSONIQ 0x1274 #define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 @@ -1877,13 +1529,10 @@ #define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 /* formerly Platform Tech */ -#define PCI_VENDOR_ID_ESS_OLD 0x1285 #define PCI_DEVICE_ID_ESS_ESS0100 0x0100 #define PCI_VENDOR_ID_ALTEON 0x12ae -#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001 -#define PCI_VENDOR_ID_USR 0x12B9 #define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001 @@ -1898,8 +1547,6 @@ #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B -#define PCI_VENDOR_ID_PICTUREL 0x12c5 -#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081 #define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 #define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 @@ -1921,8 +1568,6 @@ #define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8 #define PCI_DEVICE_ID_LML_33R10 0x8a02 -#define PCI_VENDOR_ID_CBOARDS 0x1307 -#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001 #define PCI_VENDOR_ID_SIIG 0x131f #define PCI_SUBVENDOR_ID_SIIG 0x131f @@ -1965,8 +1610,6 @@ #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 -#define PCI_VENDOR_ID_RADISYS 0x1331 -#define PCI_DEVICE_ID_RADISYS_ENP2611 0x0030 #define PCI_VENDOR_ID_DOMEX 0x134a #define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 @@ -1974,8 +1617,6 @@ #define PCI_VENDOR_ID_QUATECH 0x135C #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 -#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030 -#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040 #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 @@ -1994,7 +1635,6 @@ #define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106 #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 -#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109 #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 @@ -2008,12 +1648,9 @@ #define PCI_DEVICE_ID_LMC_SSI 0x0005 #define PCI_DEVICE_ID_LMC_T1 0x0006 -#define PCI_VENDOR_ID_MARIAN 0x1382 -#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048 #define PCI_VENDOR_ID_NETGEAR 0x1385 #define PCI_DEVICE_ID_NETGEAR_GA620 0x620a -#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a #define PCI_VENDOR_ID_APPLICOM 0x1389 #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 @@ -2036,9 +1673,6 @@ #define PCI_DEVICE_ID_MOXA_CP134U 0x1340 #define PCI_DEVICE_ID_MOXA_C168 0x1680 #define PCI_DEVICE_ID_MOXA_CP168U 0x1681 -#define PCI_DEVICE_ID_MOXA_CP204J 0x2040 -#define PCI_DEVICE_ID_MOXA_C218 0x2180 -#define PCI_DEVICE_ID_MOXA_C320 0x3200 #define PCI_VENDOR_ID_CCD 0x1397 #define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 @@ -2059,9 +1693,7 @@ #define PCI_VENDOR_ID_MICROGATE 0x13c0 #define PCI_DEVICE_ID_MICROGATE_USC 0x0010 -#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 -#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 #define PCI_VENDOR_ID_3WARE 0x13C1 #define PCI_DEVICE_ID_3WARE_1000 0x1000 @@ -2112,10 +1744,6 @@ #define PCI_VENDOR_ID_SAMSUNG 0x144d -#define PCI_VENDOR_ID_AIRONET 0x14b9 -#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001 -#define PCI_DEVICE_ID_AIRONET_4800 0x4500 // values switched? see -#define PCI_DEVICE_ID_AIRONET_4500 0x4800 // drivers/net/aironet4500_card.c #define PCI_VENDOR_ID_TITAN 0x14D2 #define PCI_DEVICE_ID_TITAN_010L 0x8001 @@ -2134,8 +1762,6 @@ #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 #define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 -#define PCI_VENDOR_ID_SIPACKETS 0x14d9 -#define PCI_DEVICE_ID_SP_HT 0x0010 #define PCI_VENDOR_ID_AFAVLAB 0x14db #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 @@ -2200,8 +1826,6 @@ #define PCI_VENDOR_ID_CHELSIO 0x1425 -#define PCI_VENDOR_ID_MIPS 0x153f -#define PCI_DEVICE_ID_SOC_IT 0x0001 #define PCI_VENDOR_ID_SYBA 0x1592 #define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 @@ -2221,15 +1845,7 @@ #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 #define PCI_VENDOR_ID_PDC 0x15e9 -#define PCI_DEVICE_ID_PDC_1841 0x1841 -#define PCI_VENDOR_ID_MACROLINK 0x15ed -#define PCI_DEVICE_ID_MACROLINK_MCCS8 0x1000 -#define PCI_DEVICE_ID_MACROLINK_MCCS 0x1001 -#define PCI_DEVICE_ID_MACROLINK_MCCS8H 0x1002 -#define PCI_DEVICE_ID_MACROLINK_MCCSH 0x1003 -#define PCI_DEVICE_ID_MACROLINK_MCCR8 0x2000 -#define PCI_DEVICE_ID_MACROLINK_MCCR 0x2001 #define PCI_VENDOR_ID_FARSITE 0x1619 #define PCI_DEVICE_ID_FARSITE_T2P 0x0400 @@ -2247,7 +1863,6 @@ #define PCI_DEVICE_ID_REVOLUTION 0x0044 #define PCI_VENDOR_ID_LINKSYS 0x1737 -#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 #define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 #define PCI_VENDOR_ID_ALTIMA 0x173b @@ -2262,7 +1877,6 @@ #define PCI_DEVICE_ID_HERC_WIN 0x5732 #define PCI_DEVICE_ID_HERC_UNI 0x5832 -#define PCI_VENDOR_ID_INFINICON 0x1820 #define PCI_VENDOR_ID_SITECOM 0x182d #define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069 @@ -2272,8 +1886,6 @@ #define PCI_VENDOR_ID_TDI 0x192E #define PCI_DEVICE_ID_TDI_EHCI 0x0101 -#define PCI_VENDOR_ID_SYMPHONY 0x1c1c -#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 @@ -2282,59 +1894,26 @@ #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 #define PCI_VENDOR_ID_3DLABS 0x3d3d -#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 -#define PCI_DEVICE_ID_3DLABS_500TX 0x0002 -#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003 -#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004 -#define PCI_DEVICE_ID_3DLABS_MX 0x0006 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 -#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 -#define PCI_VENDOR_ID_AVANCE 0x4005 -#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064 -#define PCI_DEVICE_ID_AVANCE_2302 0x2302 #define PCI_VENDOR_ID_AKS 0x416c #define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100 -#define PCI_DEVICE_ID_AKS_CPC 0x0200 -#define PCI_VENDOR_ID_REDCREEK 0x4916 -#define PCI_DEVICE_ID_RC45 0x1960 -#define PCI_VENDOR_ID_NETVIN 0x4a14 -#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 #define PCI_VENDOR_ID_S3 0x5333 -#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551 -#define PCI_DEVICE_ID_S3_ViRGE 0x5631 #define PCI_DEVICE_ID_S3_TRIO 0x8811 -#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812 -#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814 -#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d #define PCI_DEVICE_ID_S3_868 0x8880 -#define PCI_DEVICE_ID_S3_928 0x88b0 -#define PCI_DEVICE_ID_S3_864_1 0x88c0 -#define PCI_DEVICE_ID_S3_864_2 0x88c1 -#define PCI_DEVICE_ID_S3_964_1 0x88d0 -#define PCI_DEVICE_ID_S3_964_2 0x88d1 #define PCI_DEVICE_ID_S3_968 0x88f0 -#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901 -#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902 -#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01 -#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10 #define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25 -#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01 -#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02 -#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 #define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04 #define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 #define PCI_VENDOR_ID_DUNORD 0x5544 #define PCI_DEVICE_ID_DUNORD_I3000 0x0001 -#define PCI_VENDOR_ID_GENROCO 0x5555 -#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 #define PCI_VENDOR_ID_DCI 0x6666 #define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 @@ -2342,7 +1921,6 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_EESSC 0x0008 -#define PCI_DEVICE_ID_INTEL_21145 0x0039 #define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 #define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 #define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 @@ -2351,30 +1929,17 @@ #define PCI_DEVICE_ID_INTEL_82375 0x0482 #define PCI_DEVICE_ID_INTEL_82424 0x0483 #define PCI_DEVICE_ID_INTEL_82378 0x0484 -#define PCI_DEVICE_ID_INTEL_82430 0x0486 -#define PCI_DEVICE_ID_INTEL_82434 0x04a3 #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 -#define PCI_DEVICE_ID_INTEL_82562ET 0x1031 -#define PCI_DEVICE_ID_INTEL_82801CAM 0x1038 #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 -#define PCI_DEVICE_ID_INTEL_82815_AB 0x1131 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 -#define PCI_DEVICE_ID_INTEL_82559ER 0x1209 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 -#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222 -#define PCI_DEVICE_ID_INTEL_7116 0x1223 #define PCI_DEVICE_ID_INTEL_7505_0 0x2550 -#define PCI_DEVICE_ID_INTEL_7505_1 0x2552 #define PCI_DEVICE_ID_INTEL_7205_0 0x255d -#define PCI_DEVICE_ID_INTEL_82596 0x1226 -#define PCI_DEVICE_ID_INTEL_82865 0x1227 -#define PCI_DEVICE_ID_INTEL_82557 0x1229 #define PCI_DEVICE_ID_INTEL_82437 0x122d #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e #define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 #define PCI_DEVICE_ID_INTEL_82371MX 0x1234 -#define PCI_DEVICE_ID_INTEL_82437MX 0x1235 #define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82380FB 0x124b #define PCI_DEVICE_ID_INTEL_82439 0x1250 @@ -2383,83 +1948,53 @@ #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 -#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 #define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 #define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416 #define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418 #define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 #define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421 -#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422 #define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423 #define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425 #define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426 #define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428 #define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440 -#define PCI_DEVICE_ID_INTEL_82801BA_1 0x2442 #define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443 -#define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444 #define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445 -#define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446 #define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448 -#define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449 #define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a #define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b #define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c #define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e #define PCI_DEVICE_ID_INTEL_82801E_0 0x2450 -#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452 -#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453 -#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459 #define PCI_DEVICE_ID_INTEL_82801E_11 0x245b -#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d -#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e #define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 -#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482 #define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 -#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484 #define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485 #define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486 -#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487 #define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a #define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b #define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c #define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 #define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1 -#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2 #define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 -#define PCI_DEVICE_ID_INTEL_82801DB_4 0x24c4 #define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 #define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 -#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7 #define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9 #define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca #define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb #define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc -#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd #define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0 #define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1 -#define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2 #define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3 -#define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4 #define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 #define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 -#define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7 #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db -#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd #define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 #define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 -#define PCI_DEVICE_ID_INTEL_ESB_3 0x25a3 -#define PCI_DEVICE_ID_INTEL_ESB_31 0x25b0 #define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 #define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6 -#define PCI_DEVICE_ID_INTEL_ESB_6 0x25a7 -#define PCI_DEVICE_ID_INTEL_ESB_7 0x25a9 -#define PCI_DEVICE_ID_INTEL_ESB_8 0x25aa #define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab -#define PCI_DEVICE_ID_INTEL_ESB_11 0x25ac -#define PCI_DEVICE_ID_INTEL_ESB_12 0x25ad -#define PCI_DEVICE_ID_INTEL_ESB_13 0x25ae #define PCI_DEVICE_ID_INTEL_82820_HB 0x2500 #define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501 #define PCI_DEVICE_ID_INTEL_82850_HB 0x2530 @@ -2469,7 +2004,6 @@ #define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 #define PCI_DEVICE_ID_INTEL_82865_IG 0x2572 #define PCI_DEVICE_ID_INTEL_82875_HB 0x2578 -#define PCI_DEVICE_ID_INTEL_82875_IG 0x257b #define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580 #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 @@ -2479,80 +2013,23 @@ #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 -#define PCI_DEVICE_ID_INTEL_ICH6_3 0x2651 -#define PCI_DEVICE_ID_INTEL_ICH6_4 0x2652 -#define PCI_DEVICE_ID_INTEL_ICH6_5 0x2653 -#define PCI_DEVICE_ID_INTEL_ICH6_6 0x2658 -#define PCI_DEVICE_ID_INTEL_ICH6_7 0x2659 -#define PCI_DEVICE_ID_INTEL_ICH6_8 0x265a -#define PCI_DEVICE_ID_INTEL_ICH6_9 0x265b -#define PCI_DEVICE_ID_INTEL_ICH6_10 0x265c -#define PCI_DEVICE_ID_INTEL_ICH6_11 0x2660 -#define PCI_DEVICE_ID_INTEL_ICH6_12 0x2662 -#define PCI_DEVICE_ID_INTEL_ICH6_13 0x2664 -#define PCI_DEVICE_ID_INTEL_ICH6_14 0x2666 -#define PCI_DEVICE_ID_INTEL_ICH6_15 0x2668 #define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a #define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d #define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e #define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f #define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670 -#define PCI_DEVICE_ID_INTEL_ESB2_1 0x2680 -#define PCI_DEVICE_ID_INTEL_ESB2_2 0x2681 -#define PCI_DEVICE_ID_INTEL_ESB2_3 0x2682 -#define PCI_DEVICE_ID_INTEL_ESB2_4 0x2683 -#define PCI_DEVICE_ID_INTEL_ESB2_5 0x2688 -#define PCI_DEVICE_ID_INTEL_ESB2_6 0x2689 -#define PCI_DEVICE_ID_INTEL_ESB2_7 0x268a -#define PCI_DEVICE_ID_INTEL_ESB2_8 0x268b -#define PCI_DEVICE_ID_INTEL_ESB2_9 0x268c -#define PCI_DEVICE_ID_INTEL_ESB2_10 0x2690 -#define PCI_DEVICE_ID_INTEL_ESB2_11 0x2692 -#define PCI_DEVICE_ID_INTEL_ESB2_12 0x2694 -#define PCI_DEVICE_ID_INTEL_ESB2_13 0x2696 #define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 -#define PCI_DEVICE_ID_INTEL_ESB2_15 0x2699 -#define PCI_DEVICE_ID_INTEL_ESB2_16 0x269a #define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b #define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e #define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 -#define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0 -#define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1 #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd -#define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4 -#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5 -#define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8 -#define PCI_DEVICE_ID_INTEL_ICH7_8 0x27c9 -#define PCI_DEVICE_ID_INTEL_ICH7_9 0x27ca -#define PCI_DEVICE_ID_INTEL_ICH7_10 0x27cb -#define PCI_DEVICE_ID_INTEL_ICH7_11 0x27cc -#define PCI_DEVICE_ID_INTEL_ICH7_12 0x27d0 -#define PCI_DEVICE_ID_INTEL_ICH7_13 0x27d2 -#define PCI_DEVICE_ID_INTEL_ICH7_14 0x27d4 -#define PCI_DEVICE_ID_INTEL_ICH7_15 0x27d6 -#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8 #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da -#define PCI_DEVICE_ID_INTEL_ICH7_18 0x27dc #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de #define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df -#define PCI_DEVICE_ID_INTEL_ICH7_22 0x27e0 -#define PCI_DEVICE_ID_INTEL_ICH7_23 0x27e2 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 -#define PCI_DEVICE_ID_INTEL_ESB2_19 0x3500 -#define PCI_DEVICE_ID_INTEL_ESB2_20 0x3501 -#define PCI_DEVICE_ID_INTEL_ESB2_21 0x3504 -#define PCI_DEVICE_ID_INTEL_ESB2_22 0x3505 -#define PCI_DEVICE_ID_INTEL_ESB2_23 0x350c -#define PCI_DEVICE_ID_INTEL_ESB2_24 0x350d -#define PCI_DEVICE_ID_INTEL_ESB2_25 0x3510 -#define PCI_DEVICE_ID_INTEL_ESB2_26 0x3511 -#define PCI_DEVICE_ID_INTEL_ESB2_27 0x3514 -#define PCI_DEVICE_ID_INTEL_ESB2_28 0x3515 -#define PCI_DEVICE_ID_INTEL_ESB2_29 0x3518 -#define PCI_DEVICE_ID_INTEL_ESB2_30 0x3519 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 @@ -2566,7 +2043,6 @@ #define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 #define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e -#define PCI_DEVICE_ID_INTEL_80310 0x530d #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 @@ -2591,22 +2067,15 @@ #define PCI_DEVICE_ID_INTEL_440MX_6 0x7196 #define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198 #define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199 -#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a #define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 -#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1 #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 -#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 -#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602 -#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 -#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca #define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_DEVICE_ID_INTEL_84460GX 0x84ea #define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500 -#define PCI_DEVICE_ID_INTEL_IXP2400 0x9001 #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 @@ -2619,7 +2088,6 @@ #define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003 #define PCI_VENDOR_ID_KTI 0x8e2e -#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 #define PCI_VENDOR_ID_ADAPTEC 0x9004 #define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 @@ -2627,7 +2095,6 @@ #define PCI_DEVICE_ID_ADAPTEC_38602 0x3860 #define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 #define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 -#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800 #define PCI_DEVICE_ID_ADAPTEC_3860 0x6038 #define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 #define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 @@ -2647,7 +2114,6 @@ #define PCI_DEVICE_ID_ADAPTEC_7886 0x8678 #define PCI_DEVICE_ID_ADAPTEC_7887 0x8778 #define PCI_DEVICE_ID_ADAPTEC_7888 0x8878 -#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78 #define PCI_VENDOR_ID_ADAPTEC2 0x9005 #define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 @@ -2667,8 +2133,6 @@ #define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf #define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503 -#define PCI_VENDOR_ID_ATRONICS 0x907f -#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 #define PCI_VENDOR_ID_HOLTEK 0x9412 #define PCI_DEVICE_ID_HOLTEK_6565 0x6565 @@ -2701,7 +2165,3 @@ #define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897 #define PCI_DEVICE_ID_RME_DIGI32_8 0x9898 -#define PCI_VENDOR_ID_ARK 0xedd8 -#define PCI_DEVICE_ID_ARK_STING 0xa091 -#define PCI_DEVICE_ID_ARK_STINGARK 0xa099 -#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 -- cgit v1.2.3 From d10211b278c70fbebb83fb9e4ee717ca13f69b2d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 15 Oct 2005 22:02:19 -0700 Subject: [PATCH] PCI: fix edac drivers for radisys 82600 borkage I told you that the pci_ids.h cleanup was a bad idea ;) Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 11fed60a928d..611e48a4e679 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1610,6 +1610,7 @@ #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 +#define PCI_VENDOR_ID_RADISYS 0x1331 #define PCI_VENDOR_ID_DOMEX 0x134a #define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 -- cgit v1.2.3 From 2f028234f2c7f31dc0ff0784e20f14be11f7035c Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 20 Oct 2005 09:55:32 +1000 Subject: [PATCH] pci_ids: cleanup comments pci_ids.h cleanup: convert // comment to /* comment */ Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 611e48a4e679..7d300f7469e3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -444,7 +444,7 @@ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251 #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 -#define PCI_VENDOR_ID_COMPEX2 0x101a // pci.ids says "AT&T GIS (NCR)" +#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */ #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 #define PCI_VENDOR_ID_WD 0x101c @@ -1158,10 +1158,10 @@ #define PCI_VENDOR_ID_INIT 0x1101 -#define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA +#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 -#define PCI_VENDOR_ID_ECTIVA 0x1102 // duplicate: CREATIVE +#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ #define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 #define PCI_VENDOR_ID_TTI 0x1103 @@ -1171,7 +1171,7 @@ #define PCI_DEVICE_ID_TTI_HPT302 0x0006 #define PCI_DEVICE_ID_TTI_HPT371 0x0007 #define PCI_DEVICE_ID_TTI_HPT374 0x0008 -#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 // apparently a 372N variant? +#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */ #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_8763_0 0x0198 -- cgit v1.2.3 From 094f1649577dfc7f2c7407a8380e05a506b31f7f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH] USB: add endpoint information to sysfs This patch adds endpoint information for both devices and interfaces to sysfs. Previously it was only possible to get the endpoint information from usbfs, and never possible to get any information on endpoint 0. Signed-off-by: Greg Kroah-Hartman drivers/usb/core/sysfs.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/usb.h | 4 2 files changed, 197 insertions(+), 2 deletions(-) --- drivers/usb/core/sysfs.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/usb.h | 4 + 2 files changed, 197 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 00297f113849..eae413bf8c2a 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -22,6 +22,174 @@ #include "usb.h" +/* endpoint stuff */ +struct endpoint_attribute { + struct device_attribute dev_attr; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev; +}; +#define to_endpoint_attr(_dev_attr) \ + container_of(_dev_attr, struct endpoint_attribute, dev_attr) + +#define usb_ep_attr(field, format_string) \ +static ssize_t show_ep_##field(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); \ + \ + return sprintf(buf, format_string, endpoint_attr->endpoint->field); \ +} +usb_ep_attr(bLength, "%02x\n") +usb_ep_attr(bDescriptorType, "%02x\n") +usb_ep_attr(bEndpointAddress, "%02x\n") +usb_ep_attr(bmAttributes, "%02x\n") +usb_ep_attr(bInterval, "%02x\n") + +static ssize_t show_ep_wMaxPacketSize(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + + return sprintf(buf, "%04x\n", + le16_to_cpu(endpoint_attr->endpoint->wMaxPacketSize) & 0x07ff); +} + +static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + char *type = "unknown"; + + switch (endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + type = "Control"; + break; + case USB_ENDPOINT_XFER_ISOC: + type = "Isoc"; + break; + case USB_ENDPOINT_XFER_BULK: + type = "Bulk"; + break; + case USB_ENDPOINT_XFER_INT: + type = "Interrupt"; + break; + } + return sprintf(buf, "%s\n", type); +} + +static ssize_t show_ep_interval(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + struct usb_device *udev = endpoint_attr->udev; + struct usb_endpoint_descriptor *endpoint = endpoint_attr->endpoint; + char unit; + unsigned interval = 0; + unsigned in; + + in = (endpoint->bEndpointAddress & USB_DIR_IN); + + switch (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ + interval = endpoint->bInterval; + break; + case USB_ENDPOINT_XFER_ISOC: + interval = 1 << (endpoint->bInterval - 1); + break; + case USB_ENDPOINT_XFER_BULK: + if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ + interval = endpoint->bInterval; + break; + case USB_ENDPOINT_XFER_INT: + if (udev->speed == USB_SPEED_HIGH) { + interval = 1 << (endpoint->bInterval - 1); + } else + interval = endpoint->bInterval; + break; + } + interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; + if (interval % 1000) + unit = 'u'; + else { + unit = 'm'; + interval /= 1000; + } + + return sprintf(buf, "%d%cs\n", interval, unit); +} + +static ssize_t show_ep_direction(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); + char *direction; + + if ((endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) + direction = "both"; + else if (endpoint_attr->endpoint->bEndpointAddress & USB_DIR_IN) + direction = "in"; + else + direction = "out"; + return sprintf(buf, "%s\n", direction); +} + +static struct endpoint_attribute *create_ep_attr(struct usb_endpoint_descriptor *endpoint, + struct usb_device *udev, char *name, + ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf)) +{ + struct endpoint_attribute *ep_attr; + + ep_attr = kzalloc(sizeof(*ep_attr), GFP_KERNEL); + if (ep_attr) { + ep_attr->endpoint = endpoint; + ep_attr->udev = udev; + ep_attr->dev_attr.attr.name = name; + ep_attr->dev_attr.attr.mode = 0444; + ep_attr->dev_attr.attr.owner = THIS_MODULE; + ep_attr->dev_attr.show = show; + } + return ep_attr; +} + +static void usb_create_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint, struct usb_device *udev) +{ + struct usb_endpoint_descriptor *ep; + + ep = &endpoint->desc; + + endpoint->attrs = kzalloc(sizeof(struct attribute *) * 10, GFP_KERNEL); + endpoint->attrs[0] = &(create_ep_attr(ep, udev, "direction", show_ep_direction)->dev_attr.attr); + endpoint->attrs[1] = &(create_ep_attr(ep, udev, "type", show_ep_type)->dev_attr.attr); + endpoint->attrs[2] = &(create_ep_attr(ep, udev, "bLength", show_ep_bLength)->dev_attr.attr); + endpoint->attrs[3] = &(create_ep_attr(ep, udev, "bDescriptorType", show_ep_bDescriptorType)->dev_attr.attr); + endpoint->attrs[4] = &(create_ep_attr(ep, udev, "bEndpointAddress", show_ep_bEndpointAddress)->dev_attr.attr); + endpoint->attrs[5] = &(create_ep_attr(ep, udev, "bmAttributes", show_ep_bmAttributes)->dev_attr.attr); + endpoint->attrs[6] = &(create_ep_attr(ep, udev, "wMaxPacketSize", show_ep_wMaxPacketSize)->dev_attr.attr); + endpoint->attrs[7] = &(create_ep_attr(ep, udev, "bInterval", show_ep_bInterval)->dev_attr.attr); + endpoint->attrs[8] = &(create_ep_attr(ep, udev, "interval", show_ep_interval)->dev_attr.attr); + endpoint->attrs[9] = NULL; + endpoint->num_attrs = 9; + + endpoint->attr_group = kzalloc(sizeof(*endpoint->attr_group), GFP_KERNEL); + endpoint->attr_name = kzalloc(10, GFP_KERNEL); + sprintf(endpoint->attr_name, "ep_%02x", endpoint->desc.bEndpointAddress); + + endpoint->attr_group->attrs = endpoint->attrs; + endpoint->attr_group->name = endpoint->attr_name; + sysfs_create_group(kobj, endpoint->attr_group); +} + +static void usb_remove_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint) +{ + int i; + + sysfs_remove_group(kobj, endpoint->attr_group); + kfree(endpoint->attr_group); + kfree(endpoint->attr_name); + for (i = 0; i < endpoint->num_attrs; ++i) + kfree(endpoint->attrs[i]); + kfree(endpoint->attrs); +} + /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ @@ -236,12 +404,14 @@ void usb_create_sysfs_dev_files (struct usb_device *udev) if (udev->serial) device_create_file (dev, &dev_attr_serial); device_create_file (dev, &dev_attr_configuration); + usb_create_ep_files(&dev->kobj, &udev->ep0, udev); } void usb_remove_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; + usb_remove_ep_files(&dev->kobj, &udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); if (udev->descriptor.iManufacturer) @@ -333,20 +503,41 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; +static void usb_create_intf_ep_files(struct usb_interface *intf) +{ + struct usb_host_interface *iface_desc; + int i; + + iface_desc = intf->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) + usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], + interface_to_usbdev(intf)); +} + +static void usb_remove_intf_ep_files(struct usb_interface *intf) +{ + struct usb_host_interface *iface_desc; + int i; + + iface_desc = intf->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) + usb_remove_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i]); +} + void usb_create_sysfs_intf_files (struct usb_interface *intf) { sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); if (intf->cur_altsetting->string) device_create_file(&intf->dev, &dev_attr_interface); - + usb_create_intf_ep_files(intf); } void usb_remove_sysfs_intf_files (struct usb_interface *intf) { + usb_remove_intf_ep_files(intf); sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); if (intf->cur_altsetting->string) device_remove_file(&intf->dev, &dev_attr_interface); - } diff --git a/include/linux/usb.h b/include/linux/usb.h index 8f731e8f2821..4512210e97e7 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -57,6 +57,10 @@ struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; + char *attr_name; + struct attribute_group *attr_group; + struct attribute **attrs; + int num_attrs; unsigned char *extra; /* Extra descriptors */ int extralen; -- cgit v1.2.3 From d6e5bcf4a7ebbe258124a931f1449338340a99b5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH] devfs: Remove the mode field from usb_class_driver as it's no longer needed Also fixes all drivers that set this field, and removes some other devfs specfic USB logic. Signed-off-by: Greg Kroah-Hartman drivers/usb/class/usblp.c | 3 +-- drivers/usb/core/file.c | 19 ++++--------------- drivers/usb/image/mdc800.c | 3 +-- drivers/usb/input/aiptek.c | 2 +- drivers/usb/input/hiddev.c | 3 +-- drivers/usb/media/dabusb.c | 3 +-- drivers/usb/misc/auerswald.c | 3 +-- drivers/usb/misc/idmouse.c | 5 ++--- drivers/usb/misc/legousbtower.c | 5 ++--- drivers/usb/misc/rio500.c | 3 +-- drivers/usb/misc/sisusbvga/sisusb.c | 5 ----- drivers/usb/misc/usblcd.c | 9 ++++----- drivers/usb/usb-skeleton.c | 3 +-- include/linux/usb.h | 7 ++----- 14 files changed, 22 insertions(+), 51 deletions(-) --- drivers/usb/class/usblp.c | 3 +-- drivers/usb/core/file.c | 19 ++++--------------- drivers/usb/image/mdc800.c | 3 +-- drivers/usb/input/aiptek.c | 2 +- drivers/usb/input/hiddev.c | 3 +-- drivers/usb/media/dabusb.c | 3 +-- drivers/usb/misc/auerswald.c | 3 +-- drivers/usb/misc/idmouse.c | 5 ++--- drivers/usb/misc/legousbtower.c | 5 ++--- drivers/usb/misc/rio500.c | 3 +-- drivers/usb/misc/sisusbvga/sisusb.c | 5 ----- drivers/usb/misc/usblcd.c | 9 ++++----- drivers/usb/usb-skeleton.c | 3 +-- include/linux/usb.h | 7 ++----- 14 files changed, 22 insertions(+), 51 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index e195709c9c7f..357e75335f17 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -844,9 +844,8 @@ static struct file_operations usblp_fops = { }; static struct usb_class_driver usblp_class = { - .name = "usb/lp%d", + .name = "lp%d", .fops = &usblp_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = USBLP_MINOR_BASE, }; diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 78cb4be9529f..e695308095ae 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -88,8 +87,6 @@ int usb_major_init(void) goto out; } - devfs_mk_dir("usb"); - out: return error; } @@ -97,7 +94,6 @@ out: void usb_major_cleanup(void) { class_destroy(usb_class); - devfs_remove("usb"); unregister_chrdev(USB_MAJOR, "usb"); } @@ -112,8 +108,7 @@ void usb_major_cleanup(void) * enabled, the minor number will be based on the next available free minor, * starting at the class_driver->minor_base. * - * This function also creates the devfs file for the usb device, if devfs - * is enabled, and creates a usb class device in the sysfs tree. + * This function also creates a usb class device in the sysfs tree. * * usb_deregister_dev() must be called when the driver is done with * the minor numbers given out by this function. @@ -162,11 +157,8 @@ int usb_register_dev(struct usb_interface *intf, intf->minor = minor; - /* handle the devfs registration */ - snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); - devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); - /* create a usb class device for this usb interface */ + snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); temp = strrchr(name, '/'); if (temp && (temp[1] != 0x00)) ++temp; @@ -179,7 +171,6 @@ int usb_register_dev(struct usb_interface *intf, spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - devfs_remove (name); retval = PTR_ERR(intf->class_dev); } exit: @@ -197,9 +188,8 @@ EXPORT_SYMBOL(usb_register_dev); * call to usb_register_dev() (usually when the device is disconnected * from the system.) * - * This function also cleans up the devfs file for the usb device, if devfs - * is enabled, and removes the usb class device from the sysfs tree. - * + * This function also removes the usb class device from the sysfs tree. + * * This should be called by all drivers that use the USB major number. */ void usb_deregister_dev(struct usb_interface *intf, @@ -222,7 +212,6 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - devfs_remove (name); class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); intf->class_dev = NULL; intf->minor = -1; diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a330a4b50e16..e4ec133ee74a 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -425,9 +425,8 @@ static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res) static struct usb_driver mdc800_usb_driver; static struct file_operations mdc800_device_ops; static struct usb_class_driver mdc800_class = { - .name = "usb/mdc800%d", + .name = "mdc800%d", .fops = &mdc800_device_ops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = MDC800_DEVICE_MINOR_BASE, }; diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 1c5205321d83..1c3b472a3bca 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -2154,7 +2154,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) * input_handles associated with this input device. * What identifies an evdev input_handler is that it begins * with 'event', continues with a digit, and that in turn - * is mapped to /{devfs}/input/eventN. + * is mapped to input/eventN. */ list_for_each_safe(node, next, &inputdev->h_list) { inputhandle = to_handle(node); diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index d32427818af7..440377c7a0da 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -732,9 +732,8 @@ static struct file_operations hiddev_fops = { }; static struct usb_class_driver hiddev_class = { - .name = "usb/hid/hiddev%d", + .name = "hiddev%d", .fops = &hiddev_fops, - .mode = S_IFCHR | S_IRUGO | S_IWUSR, .minor_base = HIDDEV_MINOR_BASE, }; diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 6ca2fae99d2d..27b23c55bbc7 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -707,9 +707,8 @@ static struct file_operations dabusb_fops = }; static struct usb_class_driver dabusb_class = { - .name = "usb/dabusb%d", + .name = "dabusb%d", .fops = &dabusb_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = DABUSB_MINOR, }; diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index ae4681f9f0ea..5f33f7c64885 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1873,9 +1873,8 @@ static struct file_operations auerswald_fops = }; static struct usb_class_driver auerswald_class = { - .name = "usb/auer%d", + .name = "auer%d", .fops = &auerswald_fops, - .mode = S_IFCHR | S_IRUGO | S_IWUGO, .minor_base = AUER_MINOR_BASE, }; diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 733acc213726..3944a55ed74c 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -105,11 +105,10 @@ static struct file_operations idmouse_fops = { .release = idmouse_release, }; -/* class driver information for devfs */ +/* class driver information */ static struct usb_class_driver idmouse_class = { - .name = "usb/idmouse%d", + .name = "idmouse%d", .fops = &idmouse_fops, - .mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */ .minor_base = USB_IDMOUSE_MINOR_BASE, }; diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 7d06105763d4..2703e205bc8f 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -271,12 +271,11 @@ static struct file_operations tower_fops = { /* * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with devfs and the driver core + * and to have the device registered with the driver core */ static struct usb_class_driver tower_class = { - .name = "usb/legousbtower%d", + .name = "legousbtower%d", .fops = &tower_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = LEGO_USB_TOWER_MINOR_BASE, }; diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 26f77e29c7a6..7d02d8ec6b1a 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -443,9 +443,8 @@ file_operations usb_rio_fops = { }; static struct usb_class_driver usb_rio_class = { - .name = "usb/rio500%d", + .name = "rio500%d", .fops = &usb_rio_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, .minor_base = RIO_MINOR, }; diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 39db3155723a..222ae9cd4c7c 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3239,12 +3239,7 @@ static struct file_operations usb_sisusb_fops = { }; static struct usb_class_driver usb_sisusb_class = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) - .name = "usb/sisusbvga%d", - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, -#else .name = "sisusbvga%d", -#endif .fops = &usb_sisusb_fops, .minor_base = SISUSB_MINOR }; diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 096ab3029676..85f3725334b0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -251,13 +251,12 @@ static struct file_operations lcd_fops = { }; /* - * * usb class driver info in order to get a minor number from the usb core, - * * and to have the device registered with devfs and the driver core - * */ + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ static struct usb_class_driver lcd_class = { - .name = "usb/lcd%d", + .name = "lcd%d", .fops = &lcd_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = USBLCD_MINOR, }; diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 353f24d45bc1..6c3a53f8f26c 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -223,9 +223,8 @@ static struct file_operations skel_fops = { * and to have the device registered with devfs and the driver core */ static struct usb_class_driver skel_class = { - .name = "usb/skel%d", + .name = "skel%d", .fops = &skel_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = USB_SKEL_MINOR_BASE, }; diff --git a/include/linux/usb.h b/include/linux/usb.h index 4512210e97e7..04502e183dd1 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -576,10 +576,8 @@ extern struct bus_type usb_bus_type; /** * struct usb_class_driver - identifies a USB driver that wants to use the USB major number - * @name: devfs name for this driver. Will also be used by the driver - * class code to create a usb class device. + * @name: the usb class device name for this driver. Will show up in sysfs. * @fops: pointer to the struct file_operations of this driver. - * @mode: the mode for the devfs file to be created for this driver. * @minor_base: the start of the minor range for this driver. * * This structure is used for the usb_register_dev() and @@ -589,8 +587,7 @@ extern struct bus_type usb_bus_type; struct usb_class_driver { char *name; struct file_operations *fops; - mode_t mode; - int minor_base; + int minor_base; }; /* -- cgit v1.2.3 From 390a8c345e6415cbf811232feedac70b56c9fc8d Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Sep 2005 19:57:27 -0700 Subject: [PATCH] remove usb_suspend_device() parameter This patch removes the extra usb_suspend_device() parameter. The original reason to pass that parameter was so that this routine could suspend any active children. A previous patch removed that functionality ... leaving no reason to pass the parameter. A close analogy is pci_set_power_state, which doesn't need a pm_message_t either. On the internal code path that comes through the driver model, the parameter is now used to distinguish cases where USB devices need to "freeze" but not suspend. It also checks for an error case that's accessible through sysfs: attempting to suspend a device before its interfaces (or for hubs, ports). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/usb/core/hub.c | 34 +++++++++++++++++++++------------- drivers/usb/core/usb.c | 23 +++++++++++++++++++++-- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- include/linux/usb.h | 2 +- 6 files changed, 46 insertions(+), 19 deletions(-) --- drivers/usb/core/hub.c | 34 +++++++++++++++++++++------------- drivers/usb/core/usb.c | 23 +++++++++++++++++++++-- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- include/linux/usb.h | 2 +- 6 files changed, 46 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d3337d9c31dc..33127b828d60 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1323,11 +1323,9 @@ int usb_new_device(struct usb_device *udev) * (Includes HNP test device.) */ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { - static int __usb_suspend_device (struct usb_device *, - int port1, pm_message_t state); - err = __usb_suspend_device(udev, - udev->bus->otg_port, - PMSG_SUSPEND); + static int __usb_suspend_device(struct usb_device *, + int port1); + err = __usb_suspend_device(udev, udev->bus->otg_port); if (err < 0) dev_dbg(&udev->dev, "HNP fail, %d\n", err); } @@ -1517,7 +1515,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) /* FIXME let caller ask to power down the port: * - some devices won't enumerate without a VBUS power cycle * - SRP saves power that way - * - usb_suspend_device(dev, PMSG_SUSPEND) + * - ... new call, TBD ... * That's easy if this hub can switch power per-port, and * khubd reactivates the port later (timer, SRP, etc). * Powerdown must be optional, because of reset/DFU. @@ -1599,9 +1597,12 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, * Other than re-initializing the hub (plug/unplug, except for root hubs), * Linux (2.6) currently has NO mechanisms to initiate that: no khubd * timer, no SRP, no requests through sysfs. + * + * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when + * the root hub for their bus goes into global suspend ... so we don't + * (falsely) update the device power state to say it suspended. */ -static int __usb_suspend_device (struct usb_device *udev, int port1, - pm_message_t state) +static int __usb_suspend_device (struct usb_device *udev, int port1) { int status; @@ -1648,14 +1649,13 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, udev); if (status == 0) - udev->dev.power.power_state = state; + udev->dev.power.power_state = PMSG_SUSPEND; return status; } /** * usb_suspend_device - suspend a usb device * @udev: device that's no longer in active use - * @state: PMSG_SUSPEND to suspend * Context: must be able to sleep; device not locked * * Suspends a USB device that isn't in active use, conserving power. @@ -1664,13 +1664,16 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, * suspend by the host, using usb_resume_device(). It's also routine * to disconnect devices while they are suspended. * + * This only affects the USB hardware for a device; its interfaces + * (and, for hubs, child devices) must already have been suspended. + * * Suspending OTG devices may trigger HNP, if that's been enabled * between a pair of dual-role devices. That will change roles, such * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral. * * Returns 0 on success, else negative errno. */ -int usb_suspend_device(struct usb_device *udev, pm_message_t state) +int usb_suspend_device(struct usb_device *udev) { int port1, status; @@ -1678,12 +1681,15 @@ int usb_suspend_device(struct usb_device *udev, pm_message_t state) if (port1 < 0) return port1; - status = __usb_suspend_device(udev, port1, state); + status = __usb_suspend_device(udev, port1); usb_unlock_device(udev); return status; } /* + * If the USB "suspend" state is in use (rather than "global suspend"), + * many devices will be individually taken out of suspend state using + * special" resume" signaling. These routines kick in shortly after * hardware resume signaling is finished, either because of selective * resume (by host) or remote wakeup (by device) ... now see what changed * in the tree that's rooted at this device. @@ -1986,13 +1992,15 @@ void usb_resume_root_hub(struct usb_device *hdev) #else /* !CONFIG_USB_SUSPEND */ -int usb_suspend_device(struct usb_device *udev, pm_message_t state) +int usb_suspend_device(struct usb_device *udev) { + /* state does NOT lie by saying it's USB_STATE_SUSPENDED! */ return 0; } int usb_resume_device(struct usb_device *udev) { + udev->dev.power_state.event = PM_EVENT_ON; return 0; } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 6ecfdce4f848..e89dbd43e952 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1414,14 +1414,33 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } +static int verify_suspended(struct device *dev, void *unused) +{ + return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; +} + static int usb_generic_suspend(struct device *dev, pm_message_t message) { struct usb_interface *intf; struct usb_driver *driver; int status; - if (dev->driver == &usb_generic_driver) - return usb_suspend_device (to_usb_device(dev), message); + /* USB devices enter SUSPEND state through their hubs, but can be + * marked for FREEZE as soon as their children are already idled. + */ + if (dev->driver == &usb_generic_driver) { + if (dev->power.power_state.event == message.event) + return 0; + /* we need to rule out bogus requests through sysfs */ + status = device_for_each_child(dev, NULL, verify_suspended); + if (status) + return status; + if (message.event == PM_EVENT_FREEZE) { + dev->power.power_state = message; + return 0; + } + return usb_suspend_device (to_usb_device(dev)); + } if ((dev->driver == NULL) || (dev->driver_data == &usb_generic_driver_data)) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b3eb02613bff..513fccbb8e43 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -759,7 +759,7 @@ static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, message); + (void) usb_suspend_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); (void) ehci_hub_suspend (hcd); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 642f35068ce2..554d60282a9d 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1781,7 +1781,7 @@ static int isp116x_suspend(struct device *dev, pm_message_t state) VDBG("%s: state %x\n", __func__, state); - ret = usb_suspend_device(hcd->self.root_hub, state); + ret = usb_suspend_device(hcd->self.root_hub); if (!ret) { dev->power.power_state = state; INFO("%s suspended\n", hcd_name); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index eede6be098d2..41e85980fa7a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -119,7 +119,7 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, message); + (void) usb_suspend_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); diff --git a/include/linux/usb.h b/include/linux/usb.h index 04502e183dd1..25ec91ddcd04 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -976,7 +976,7 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, int timeout); /* selective suspend/resume */ -extern int usb_suspend_device(struct usb_device *dev, pm_message_t message); +extern int usb_suspend_device(struct usb_device *dev); extern int usb_resume_device(struct usb_device *dev); -- cgit v1.2.3 From e9b7bd4ee7f6e3ee002dc72c5211cd97c7186d00 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:30:48 -0700 Subject: [PATCH] one less word in struct device This saves a word from "struct device" ... there's a refcounting mechanism stub that's rather ineffective (the values are never even tested!), which can safely be deleted. With this patch it uses normal device refcounting, so any potential users of the pm_parent mechanism will be more correct. (That mechanism is actually unusable for now though; it does nothing.) Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman drivers/base/power/main.c | 26 +++----------------------- include/linux/pm.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-) --- drivers/base/power/main.c | 26 +++----------------------- include/linux/pm.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 15e6a8f951f1..0d2e101e4f15 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -30,23 +30,6 @@ LIST_HEAD(dpm_off_irq); DECLARE_MUTEX(dpm_sem); DECLARE_MUTEX(dpm_list_sem); -/* - * PM Reference Counting. - */ - -static inline void device_pm_hold(struct device * dev) -{ - if (dev) - atomic_inc(&dev->power.pm_users); -} - -static inline void device_pm_release(struct device * dev) -{ - if (dev) - atomic_dec(&dev->power.pm_users); -} - - /** * device_pm_set_parent - Specify power dependency. * @dev: Device who needs power. @@ -62,10 +45,8 @@ static inline void device_pm_release(struct device * dev) void device_pm_set_parent(struct device * dev, struct device * parent) { - struct device * old_parent = dev->power.pm_parent; - device_pm_release(old_parent); - dev->power.pm_parent = parent; - device_pm_hold(parent); + put_device(dev->power.pm_parent); + dev->power.pm_parent = get_device(parent); } EXPORT_SYMBOL_GPL(device_pm_set_parent); @@ -75,7 +56,6 @@ int device_pm_add(struct device * dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); - atomic_set(&dev->power.pm_users, 0); down(&dpm_list_sem); list_add_tail(&dev->power.entry, &dpm_active); device_pm_set_parent(dev, dev->parent); @@ -91,7 +71,7 @@ void device_pm_remove(struct device * dev) dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); down(&dpm_list_sem); dpm_sysfs_remove(dev); - device_pm_release(dev->power.pm_parent); + put_device(dev->power.pm_parent); list_del_init(&dev->power.entry); up(&dpm_list_sem); } diff --git a/include/linux/pm.h b/include/linux/pm.h index 7897cf500c51..83bae1cbe55b 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -224,7 +224,6 @@ struct dev_pm_info { unsigned should_wakeup:1; pm_message_t prev_state; void * saved_state; - atomic_t pm_users; struct device * pm_parent; struct list_head entry; #endif -- cgit v1.2.3 From 5edbfb7c8af0577097dae87cdd4dfdba82bb9579 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 22 Sep 2005 22:45:26 -0700 Subject: [PATCH] stop exporting two functions The way we're looking at USB suspend lately doesn't expect drivers to call usb_suspend_device() or usb_resume_device() directly; that'll be implicit when no interfaces are in use. This patch removes those APIs from visibility outside usbcore. Signed-off-by: David Brownell drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/usb.h | 4 ++++ include/linux/usb.h | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) --- drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/usb.h | 4 ++++ include/linux/usb.h | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6a601a4547e7..15db5e490aa2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1652,10 +1652,10 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) #endif -/** +/* * usb_suspend_device - suspend a usb device * @udev: device that's no longer in active use - * Context: must be able to sleep; device not locked + * Context: must be able to sleep; device not locked; pm locks held * * Suspends a USB device that isn't in active use, conserving power. * Devices may wake out of a suspend, if anything important happens, @@ -1820,10 +1820,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) #endif -/** +/* * usb_resume_device - re-activate a suspended usb device * @udev: device to re-activate - * Context: must be able to sleep; device not locked + * Context: must be able to sleep; device not locked; pm locks held * * This will re-activate the suspended device, increasing power usage * while letting drivers communicate again with its endpoints. @@ -2024,10 +2024,6 @@ void usb_resume_root_hub(struct usb_device *hdev) kick_khubd(hub); } -EXPORT_SYMBOL(usb_suspend_device); -EXPORT_SYMBOL(usb_resume_device); - - /* USB 2.0 spec, 7.1.7.3 / fig 7-29: * diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 7add46ecc6a2..4d59f6e07999 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -29,6 +29,10 @@ extern void usb_major_cleanup(void); extern int usb_host_init(void); extern void usb_host_cleanup(void); +extern int usb_suspend_device(struct usb_device *dev); +extern int usb_resume_device(struct usb_device *dev); + + /* Interfaces and their "power state" are owned by usbcore */ static inline void mark_active(struct usb_interface *f) diff --git a/include/linux/usb.h b/include/linux/usb.h index 25ec91ddcd04..207b1ad9d990 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -975,11 +975,6 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); -/* selective suspend/resume */ -extern int usb_suspend_device(struct usb_device *dev); -extern int usb_resume_device(struct usb_device *dev); - - /* wrappers around usb_control_msg() for the most common standard requests */ extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, unsigned char descindex, void *buf, int size); -- cgit v1.2.3 From 4e67185a7ac3ecb1710e636e2f7e318e99298c7a Mon Sep 17 00:00:00 2001 From: Juha Yrj?l? Date: Sun, 16 Oct 2005 15:47:04 -0700 Subject: [PATCH] add usb transceiver set_suspend() method When a USB device is put into suspend mode, the current drawn from VBUS has to be less than 500 uA. Some transceivers need to be put into a special power-saving mode to accomplish this, and won't have a separate OTG driver handling that. This adds a suspend method to the "otg_transceiver" struct -- misnamed, it's not only for OTG -- and calls it from the OMAP UDC driver. Signed-off-by: Juha Yrj?l? Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/omap_udc.c | 4 ++++ include/linux/usb_otg.h | 13 +++++++++++++ 2 files changed, 17 insertions(+) (limited to 'include/linux') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index de8a89ae4bc3..b42799bc747a 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1788,8 +1788,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) udc->driver->suspend(&udc->gadget); spin_lock(&udc->lock); } + if (udc->transceiver) + otg_set_suspend(udc->transceiver, 1); } else { VDBG("resume\n"); + if (udc->transceiver) + otg_set_suspend(udc->transceiver, 0); if (udc->gadget.speed == USB_SPEED_FULL && udc->driver->resume) { spin_unlock(&udc->lock); diff --git a/include/linux/usb_otg.h b/include/linux/usb_otg.h index c6683146e9b0..f827f6e203c2 100644 --- a/include/linux/usb_otg.h +++ b/include/linux/usb_otg.h @@ -63,6 +63,10 @@ struct otg_transceiver { int (*set_power)(struct otg_transceiver *otg, unsigned mA); + /* for non-OTG B devices: set transceiver into suspend mode */ + int (*set_suspend)(struct otg_transceiver *otg, + int suspend); + /* for B devices only: start session with A-Host */ int (*start_srp)(struct otg_transceiver *otg); @@ -107,6 +111,15 @@ otg_set_power(struct otg_transceiver *otg, unsigned mA) return otg->set_power(otg, mA); } +static inline int +otg_set_suspend(struct otg_transceiver *otg, int suspend) +{ + if (otg->set_suspend != NULL) + return otg->set_suspend(otg, suspend); + else + return 0; +} + static inline int otg_start_srp(struct otg_transceiver *otg) { -- cgit v1.2.3 From 3099e75a7ccc3c5b0a4cf988a76d9c4a7fa5e91a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2005 21:15:16 -0700 Subject: [PATCH] USB: add notifier functions to the USB core for devices and busses This should let us get rid of all of the different hooks in the USB core for when something has changed. Also, some other parts of the kernel have wanted to know this kind of information at times. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Makefile | 2 +- drivers/usb/core/hcd.c | 2 + drivers/usb/core/hub.c | 3 ++ drivers/usb/core/notify.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/core/usb.h | 6 +++ include/linux/usb.h | 8 ++++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/core/notify.c (limited to 'include/linux') diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index d5503cf0bf74..dd1c4d2a0c31 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -3,7 +3,7 @@ # usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ - config.o file.o buffer.o sysfs.o devio.o + config.o file.o buffer.o sysfs.o devio.o notify.o ifeq ($(CONFIG_PCI),y) usbcore-objs += hcd-pci.o diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9ad3912a5ed7..b700b6cdb683 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -792,6 +792,7 @@ static int usb_register_bus(struct usb_bus *bus) list_add (&bus->bus_list, &usb_bus_list); up (&usb_bus_list_lock); + usb_notify_add_bus(bus); usbfs_add_bus (bus); usbmon_notify_bus_add (bus); @@ -820,6 +821,7 @@ static void usb_deregister_bus (struct usb_bus *bus) list_del (&bus->bus_list); up (&usb_bus_list_lock); + usb_notify_remove_bus(bus); usbmon_notify_bus_remove (bus); usbfs_remove_bus (bus); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 273e6ccca213..4f1a8c8cf92b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1128,6 +1128,8 @@ void usb_disconnect(struct usb_device **pdev) */ usb_disable_device(udev, 0); + usb_notify_remove_device(udev); + /* Free the device number, remove the /proc/bus/usb entry and * the sysfs attributes, and delete the parent's children[] * (or root_hub) pointer. @@ -1371,6 +1373,7 @@ int usb_new_device(struct usb_device *udev) } /* USB device state == configured ... usable */ + usb_notify_add_device(udev); /* add a /proc/bus/usb entry */ usbdev_add(udev); diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c new file mode 100644 index 000000000000..37da059eced7 --- /dev/null +++ b/drivers/usb/core/notify.c @@ -0,0 +1,120 @@ +/* + * All the USB notify logic + * + * (C) Copyright 2005 Greg Kroah-Hartman + * + * notifier functions originally based on those in kernel/sys.c + * but fixed up to not be so broken. + * + */ + + +#include +#include +#include +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif +#include + +#include "usb.h" + + +static struct notifier_block *usb_notifier_list; +static DECLARE_MUTEX(usb_notifier_lock); + +static void usb_notifier_chain_register(struct notifier_block **list, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while (*list) { + if (n->priority > (*list)->priority) + break; + list = &((*list)->next); + } + n->next = *list; + *list = n; + up(&usb_notifier_lock); +} + +static void usb_notifier_chain_unregister(struct notifier_block **nl, + struct notifier_block *n) +{ + down(&usb_notifier_lock); + while ((*nl)!=NULL) { + if ((*nl)==n) { + *nl = n->next; + goto exit; + } + nl=&((*nl)->next); + } +exit: + up(&usb_notifier_lock); +} + +static int usb_notifier_call_chain(struct notifier_block **n, + unsigned long val, void *v) +{ + int ret=NOTIFY_DONE; + struct notifier_block *nb = *n; + + down(&usb_notifier_lock); + while (nb) { + ret = nb->notifier_call(nb,val,v); + if (ret&NOTIFY_STOP_MASK) { + goto exit; + } + nb = nb->next; + } +exit: + up(&usb_notifier_lock); + return ret; +} + +/** + * usb_register_notify - register a notifier callback whenever a usb change happens + * @nb: pointer to the notifier block for the callback events. + * + * These changes are either USB devices or busses being added or removed. + */ +void usb_register_notify(struct notifier_block *nb) +{ + usb_notifier_chain_register(&usb_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(usb_register_notify); + +/** + * usb_unregister_notify - unregister a notifier callback + * @nb: pointer to the notifier block for the callback events. + * + * usb_register_notifier() must have been previously called for this function + * to work properly. + */ +void usb_unregister_notify(struct notifier_block *nb) +{ + usb_notifier_chain_unregister(&usb_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(usb_unregister_notify); + + +void usb_notify_add_device(struct usb_device *udev) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); +} + +void usb_notify_remove_device(struct usb_device *udev) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); +} + +void usb_notify_add_bus(struct usb_bus *ubus) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); +} + +void usb_notify_remove_bus(struct usb_bus *ubus) +{ + usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); +} diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3dc8096c0f92..811cf4482e0d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -80,3 +80,9 @@ struct dev_state { unsigned long ifclaimed; }; +/* internal notify stuff */ +extern void usb_notify_add_device(struct usb_device *udev); +extern void usb_notify_remove_device(struct usb_device *udev); +extern void usb_notify_add_bus(struct usb_bus *ubus); +extern void usb_notify_remove_bus(struct usb_bus *ubus); + diff --git a/include/linux/usb.h b/include/linux/usb.h index 207b1ad9d990..a2d923fd54f9 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1135,6 +1135,14 @@ usb_maxpacket(struct usb_device *udev, int pipe, int is_out) /* -------------------------------------------------------------------------- */ +/* Events from the usb core */ +#define USB_DEVICE_ADD 0x0001 +#define USB_DEVICE_REMOVE 0x0002 +#define USB_BUS_ADD 0x0003 +#define USB_BUS_REMOVE 0x0004 +extern void usb_register_notify(struct notifier_block *nb); +extern void usb_unregister_notify(struct notifier_block *nb); + #ifdef DEBUG #define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg) #else -- cgit v1.2.3 From c36fc889b5a4fd66cfd9ba80d9e038745d349567 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Mon, 17 Oct 2005 18:15:54 -0700 Subject: [PATCH] usb: Patch for USBDEVFS_IOCTL from 32-bit programs Dell supplied me with the following test: #include #include #include #include #include main(int argc,char*argv[]) { struct usbdevfs_hub_portinfo hubPortInfo = {0}; struct usbdevfs_ioctl command = {0}; command.ifno = 0; command.ioctl_code = USBDEVFS_HUB_PORTINFO; command.data = (void*)&hubPortInfo; int fd, ret; if(argc != 2) { fprintf(stderr,"Usage: %s /proc/bus/usb//\n",argv[0]); fprintf(stderr,"Example: %s /proc/bus/usb/001/001\n",argv[0]); exit(1); } errno = 0; fd = open(argv[1],O_RDWR); if(fd < 0) { perror("open failed:"); exit(errno); } errno = 0; ret = ioctl(fd,USBDEVFS_IOCTL,&command); printf("IOCTL return status:%d\n",ret); if(ret<0) { perror("IOCTL failed:"); close(fd); exit(3); } else { printf("IOCTL passed:Num of ports %d\n",hubPortInfo.nports); close(fd); exit(0); } return 0; } I have verified that it breaks if built in 32 bit mode on x86_64 and that the patch below fixes it. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 56 +++++++++++++++++++++++++++++++++----------- fs/compat_ioctl.c | 1 + include/linux/usbdevice_fs.h | 7 ++++++ 3 files changed, 50 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 2bd742ba812d..ffb2e242b100 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1301,23 +1301,20 @@ static int proc_releaseinterface(struct dev_state *ps, void __user *arg) return 0; } -static int proc_ioctl (struct dev_state *ps, void __user *arg) +static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) { - struct usbdevfs_ioctl ctrl; int size; void *buf = NULL; int retval = 0; struct usb_interface *intf = NULL; struct usb_driver *driver = NULL; - /* get input parameters and alloc buffer */ - if (copy_from_user(&ctrl, arg, sizeof (ctrl))) - return -EFAULT; - if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) { + /* alloc buffer */ + if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) { if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) return -ENOMEM; - if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) { - if (copy_from_user (buf, ctrl.data, size)) { + if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { + if (copy_from_user (buf, ctl->data, size)) { kfree(buf); return -EFAULT; } @@ -1333,9 +1330,9 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) if (ps->dev->state != USB_STATE_CONFIGURED) retval = -EHOSTUNREACH; - else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno))) + else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno))) retval = -EINVAL; - else switch (ctrl.ioctl_code) { + else switch (ctl->ioctl_code) { /* disconnect kernel driver from interface */ case USBDEVFS_DISCONNECT: @@ -1367,7 +1364,7 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) if (driver == NULL || driver->ioctl == NULL) { retval = -ENOTTY; } else { - retval = driver->ioctl (intf, ctrl.ioctl_code, buf); + retval = driver->ioctl (intf, ctl->ioctl_code, buf); if (retval == -ENOIOCTLCMD) retval = -ENOTTY; } @@ -1376,15 +1373,42 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) /* cleanup and return */ if (retval >= 0 - && (_IOC_DIR (ctrl.ioctl_code) & _IOC_READ) != 0 + && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0 && size > 0 - && copy_to_user (ctrl.data, buf, size) != 0) + && copy_to_user (ctl->data, buf, size) != 0) retval = -EFAULT; kfree(buf); return retval; } +static int proc_ioctl_default(struct dev_state *ps, void __user *arg) +{ + struct usbdevfs_ioctl ctrl; + + if (copy_from_user(&ctrl, arg, sizeof (ctrl))) + return -EFAULT; + return proc_ioctl(ps, &ctrl); +} + +#ifdef CONFIG_COMPAT +static int proc_ioctl_compat(struct dev_state *ps, void __user *arg) +{ + struct usbdevfs_ioctl32 __user *uioc; + struct usbdevfs_ioctl ctrl; + u32 udata; + + uioc = compat_ptr(arg); + if (get_user(ctrl.ifno, &uioc->ifno) || + get_user(ctrl.ioctl_code, &uioc->ioctl_code) || + __get_user(udata, &uioc->data)) + return -EFAULT; + ctrl.data = compat_ptr(udata); + + return proc_ioctl(ps, &ctrl); +} +#endif + /* * NOTE: All requests here that have interface numbers as parameters * are assuming that somehow the configuration has been prevented from @@ -1485,6 +1509,10 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ret = proc_reapurbnonblock_compat(ps, p); break; + case USBDEVFS_IOCTL32: + snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); + ret = proc_ioctl_compat(ps, p); + break; #endif case USBDEVFS_DISCARDURB: @@ -1519,7 +1547,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd case USBDEVFS_IOCTL: snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); - ret = proc_ioctl(ps, p); + ret = proc_ioctl_default(ps, p); break; } usb_unlock_device(dev); diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e28a74203f3b..a327e03753ac 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -3050,6 +3050,7 @@ HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) +COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) /* i2c */ HANDLE_IOCTL(I2C_FUNCS, w_long) HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h index 9facf733800c..8859f0b41543 100644 --- a/include/linux/usbdevice_fs.h +++ b/include/linux/usbdevice_fs.h @@ -140,6 +140,12 @@ struct usbdevfs_urb32 { compat_caddr_t usercontext; /* unused */ struct usbdevfs_iso_packet_desc iso_frame_desc[0]; }; + +struct usbdevfs_ioctl32 { + s32 ifno; + s32 ioctl_code; + compat_caddr_t data; +}; #endif #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) @@ -160,6 +166,7 @@ struct usbdevfs_urb32 { #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) #define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl) +#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32) #define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo) #define USBDEVFS_RESET _IO('U', 20) #define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int) -- cgit v1.2.3 From 478a3bab8c87a9ba4a4ba338314e32bb0c378e62 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 19 Oct 2005 12:52:02 -0400 Subject: [PATCH] USB: Always do usb-handoff This revised patch (as586b) makes usb-handoff permanently true and no longer a kernel boot parameter. It also removes the piix3_usb quirk code; that was nothing more than an early version of the USB handoff code (written at a time when Intel's PIIX3 was about the only motherboard with USB support). And it adds identifiers for the three PCI USB controller classes to pci_ids.h. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 2 -- drivers/usb/host/pci-quirks.c | 46 ++--------------------------- include/asm-i386/mach-summit/mach_mpparse.h | 3 -- include/linux/pci_ids.h | 3 ++ 4 files changed, 6 insertions(+), 48 deletions(-) (limited to 'include/linux') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 971589a9752d..90766b75d1b7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1517,8 +1517,6 @@ running once the system is up. uart6850= [HW,OSS] Format: , - usb-handoff [HW] Enable early USB BIOS -> OS handoff - usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index f7411ca48835..b7fd3f644e1e 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -23,33 +23,6 @@ #include -/* - * PIIX3 USB: We have to disable USB interrupts that are - * hardwired to PIRQD# and may be shared with an - * external device. - * - * Legacy Support Register (LEGSUP): - * bit13: USB PIRQ Enable (USBPIRQDEN), - * bit4: Trap/SMI On IRQ Enable (USBSMIEN). - * - * We mask out all r/wc bits, too. - */ -static void __devinit quirk_piix3_usb(struct pci_dev *dev) -{ - u16 legsup; - - pci_read_config_word(dev, 0xc0, &legsup); - legsup &= 0x50ef; - pci_write_config_word(dev, 0xc0, legsup); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); - - -/* FIXME these should be the guts of hcd->reset() methods; resolve all - * the differences between this version and the HCD's version. - */ - #define UHCI_USBLEGSUP 0xc0 /* legacy support */ #define UHCI_USBCMD 0 /* command register */ #define UHCI_USBINTR 4 /* interrupt register */ @@ -83,13 +56,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, qui #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ -int usb_early_handoff __devinitdata = 0; -static int __init usb_handoff_early(char *str) -{ - usb_early_handoff = 1; - return 0; -} -__setup("usb-handoff", usb_handoff_early); /* * Make sure the controller is completely inactive, unable to @@ -320,17 +286,11 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) { - if (!usb_early_handoff) - return; - - if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ + if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) quirk_usb_handoff_uhci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ + else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) quirk_usb_handoff_ohci(pdev); - } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ + else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) quirk_usb_disable_ehci(pdev); - } - - return; } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h index 2b9e6d55bef1..1cce2b924a80 100644 --- a/include/asm-i386/mach-summit/mach_mpparse.h +++ b/include/asm-i386/mach-summit/mach_mpparse.h @@ -22,7 +22,6 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, { } -extern int usb_early_handoff; static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { @@ -32,7 +31,6 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, || !strncmp(productid, "RUTHLESS SMP", 12))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); - usb_early_handoff = 1; return 1; } return 0; @@ -46,7 +44,6 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); - usb_early_handoff = 1; return 1; } return 0; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7d300f7469e3..467a096c3b81 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -96,6 +96,9 @@ #define PCI_CLASS_SERIAL_ACCESS 0x0c01 #define PCI_CLASS_SERIAL_SSA 0x0c02 #define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 +#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 +#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 #define PCI_CLASS_SERIAL_FIBER 0x0c04 #define PCI_CLASS_SERIAL_SMBUS 0x0c05 -- cgit v1.2.3 From be69e5b1900a19a545becda822b18d6f09168ba5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 25 Oct 2005 15:56:06 -0400 Subject: [PATCH] usbcore: Improve endpoint sysfs file handling This revised patch (as587b) improves the implementation of USB endpoint sysfs files. Instead of storing a whole bunch of attributes for every single endpoint, each endpoint now gets its own kobject and they can share a static list of attributes. The number of extra fields added to struct usb_host_endpoint has been reduced from 4 to 1. The bEndpointAddress field is retained even though it is redundant (it repeats the same information as the attributes' directory name). The code avoids calling kobject_register, to prevent generating unwanted hotplug events. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 219 +++++++++++++++++++++++++++-------------------- include/linux/usb.h | 5 +- 2 files changed, 125 insertions(+), 99 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4bdbc9df6e03..f18317fb49ee 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -23,43 +23,56 @@ #include "usb.h" /* endpoint stuff */ -struct endpoint_attribute { - struct device_attribute dev_attr; - struct usb_endpoint_descriptor *endpoint; +struct ep_object { + struct usb_endpoint_descriptor *desc; struct usb_device *udev; + struct kobject kobj; }; -#define to_endpoint_attr(_dev_attr) \ - container_of(_dev_attr, struct endpoint_attribute, dev_attr) - -#define usb_ep_attr(field, format_string) \ -static ssize_t show_ep_##field(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); \ - \ - return sprintf(buf, format_string, endpoint_attr->endpoint->field); \ -} +#define to_ep_object(_kobj) \ + container_of(_kobj, struct ep_object, kobj) + +struct ep_attribute { + struct attribute attr; + ssize_t (*show)(struct usb_device *, + struct usb_endpoint_descriptor *, char *); +}; +#define to_ep_attribute(_attr) \ + container_of(_attr, struct ep_attribute, attr) + +#define EP_ATTR(_name) \ +struct ep_attribute ep_##_name = { \ + .attr = {.name = #_name, .owner = THIS_MODULE, \ + .mode = S_IRUGO}, \ + .show = show_ep_##_name} + +#define usb_ep_attr(field, format_string) \ +static ssize_t show_ep_##field(struct usb_device *udev, \ + struct usb_endpoint_descriptor *desc, \ + char *buf) \ +{ \ + return sprintf(buf, format_string, desc->field); \ +} \ +static EP_ATTR(field); + usb_ep_attr(bLength, "%02x\n") -usb_ep_attr(bDescriptorType, "%02x\n") usb_ep_attr(bEndpointAddress, "%02x\n") usb_ep_attr(bmAttributes, "%02x\n") usb_ep_attr(bInterval, "%02x\n") -static ssize_t show_ep_wMaxPacketSize(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); - return sprintf(buf, "%04x\n", - le16_to_cpu(endpoint_attr->endpoint->wMaxPacketSize) & 0x07ff); + le16_to_cpu(desc->wMaxPacketSize) & 0x07ff); } +static EP_ATTR(wMaxPacketSize); -static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_type(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); char *type = "unknown"; - switch (endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_CONTROL: type = "Control"; break; @@ -75,35 +88,34 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, c } return sprintf(buf, "%s\n", type); } +static EP_ATTR(type); -static ssize_t show_ep_interval(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_interval(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); - struct usb_device *udev = endpoint_attr->udev; - struct usb_endpoint_descriptor *endpoint = endpoint_attr->endpoint; char unit; unsigned interval = 0; unsigned in; - in = (endpoint->bEndpointAddress & USB_DIR_IN); + in = (desc->bEndpointAddress & USB_DIR_IN); - switch (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_CONTROL: if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ - interval = endpoint->bInterval; + interval = desc->bInterval; break; case USB_ENDPOINT_XFER_ISOC: - interval = 1 << (endpoint->bInterval - 1); + interval = 1 << (desc->bInterval - 1); break; case USB_ENDPOINT_XFER_BULK: - if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ - interval = endpoint->bInterval; + if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ + interval = desc->bInterval; break; case USB_ENDPOINT_XFER_INT: - if (udev->speed == USB_SPEED_HIGH) { - interval = 1 << (endpoint->bInterval - 1); - } else - interval = endpoint->bInterval; + if (udev->speed == USB_SPEED_HIGH) + interval = 1 << (desc->bInterval - 1); + else + interval = desc->bInterval; break; } interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; @@ -116,78 +128,95 @@ static ssize_t show_ep_interval(struct device *dev, struct device_attribute *att return sprintf(buf, "%d%cs\n", interval, unit); } +static EP_ATTR(interval); -static ssize_t show_ep_direction(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_ep_direction(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) { - struct endpoint_attribute *endpoint_attr = to_endpoint_attr(attr); char *direction; - if ((endpoint_attr->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_CONTROL) + if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) direction = "both"; - else if (endpoint_attr->endpoint->bEndpointAddress & USB_DIR_IN) + else if (desc->bEndpointAddress & USB_DIR_IN) direction = "in"; else direction = "out"; return sprintf(buf, "%s\n", direction); } +static EP_ATTR(direction); + +static struct attribute *ep_attrs[] = { + &ep_bLength.attr, + &ep_bEndpointAddress.attr, + &ep_bmAttributes.attr, + &ep_bInterval.attr, + &ep_wMaxPacketSize.attr, + &ep_type.attr, + &ep_interval.attr, + &ep_direction.attr, + NULL, +}; -static struct endpoint_attribute *create_ep_attr(struct usb_endpoint_descriptor *endpoint, - struct usb_device *udev, char *name, - ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf)) +static void ep_object_release(struct kobject *kobj) { - struct endpoint_attribute *ep_attr; - - ep_attr = kzalloc(sizeof(*ep_attr), GFP_KERNEL); - if (ep_attr) { - ep_attr->endpoint = endpoint; - ep_attr->udev = udev; - ep_attr->dev_attr.attr.name = name; - ep_attr->dev_attr.attr.mode = 0444; - ep_attr->dev_attr.attr.owner = THIS_MODULE; - ep_attr->dev_attr.show = show; - } - return ep_attr; + kfree(to_ep_object(kobj)); } -static void usb_create_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint, struct usb_device *udev) +static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr, + char *buf) { - struct usb_endpoint_descriptor *ep; - - ep = &endpoint->desc; - - endpoint->attrs = kzalloc(sizeof(struct attribute *) * 10, GFP_KERNEL); - endpoint->attrs[0] = &(create_ep_attr(ep, udev, "direction", show_ep_direction)->dev_attr.attr); - endpoint->attrs[1] = &(create_ep_attr(ep, udev, "type", show_ep_type)->dev_attr.attr); - endpoint->attrs[2] = &(create_ep_attr(ep, udev, "bLength", show_ep_bLength)->dev_attr.attr); - endpoint->attrs[3] = &(create_ep_attr(ep, udev, "bDescriptorType", show_ep_bDescriptorType)->dev_attr.attr); - endpoint->attrs[4] = &(create_ep_attr(ep, udev, "bEndpointAddress", show_ep_bEndpointAddress)->dev_attr.attr); - endpoint->attrs[5] = &(create_ep_attr(ep, udev, "bmAttributes", show_ep_bmAttributes)->dev_attr.attr); - endpoint->attrs[6] = &(create_ep_attr(ep, udev, "wMaxPacketSize", show_ep_wMaxPacketSize)->dev_attr.attr); - endpoint->attrs[7] = &(create_ep_attr(ep, udev, "bInterval", show_ep_bInterval)->dev_attr.attr); - endpoint->attrs[8] = &(create_ep_attr(ep, udev, "interval", show_ep_interval)->dev_attr.attr); - endpoint->attrs[9] = NULL; - endpoint->num_attrs = 9; - - endpoint->attr_group = kzalloc(sizeof(*endpoint->attr_group), GFP_KERNEL); - endpoint->attr_name = kzalloc(10, GFP_KERNEL); - sprintf(endpoint->attr_name, "ep_%02x", endpoint->desc.bEndpointAddress); - - endpoint->attr_group->attrs = endpoint->attrs; - endpoint->attr_group->name = endpoint->attr_name; - sysfs_create_group(kobj, endpoint->attr_group); + struct ep_object *ep_obj = to_ep_object(kobj); + struct ep_attribute *ep_attr = to_ep_attribute(attr); + + return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf); } -static void usb_remove_ep_files(struct kobject *kobj, struct usb_host_endpoint *endpoint) +static struct sysfs_ops ep_object_sysfs_ops = { + .show = ep_object_show, +}; + +static struct kobj_type ep_object_ktype = { + .release = ep_object_release, + .sysfs_ops = &ep_object_sysfs_ops, + .default_attrs = ep_attrs, +}; + +static void usb_create_ep_files(struct kobject *parent, + struct usb_host_endpoint *endpoint, + struct usb_device *udev) { - int i; + struct ep_object *ep_obj; + struct kobject *kobj; + + ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL); + if (!ep_obj) + return; - sysfs_remove_group(kobj, endpoint->attr_group); - kfree(endpoint->attr_group); - kfree(endpoint->attr_name); - for (i = 0; i < endpoint->num_attrs; ++i) - kfree(endpoint->attrs[i]); - kfree(endpoint->attrs); + ep_obj->desc = &endpoint->desc; + ep_obj->udev = udev; + + kobj = &ep_obj->kobj; + kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress); + kobj->parent = parent; + kobj->ktype = &ep_object_ktype; + + /* Don't use kobject_register, because it generates a hotplug event */ + kobject_init(kobj); + if (kobject_add(kobj) == 0) + endpoint->kobj = kobj; + else + kobject_put(kobj); +} + +static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) +{ + + if (endpoint->kobj) { + kobject_del(endpoint->kobj); + kobject_put(endpoint->kobj); + endpoint->kobj = NULL; + } } /* Active configuration fields */ @@ -411,7 +440,7 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) { struct device *dev = &udev->dev; - usb_remove_ep_files(&dev->kobj, &udev->ep0); + usb_remove_ep_files(&udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); if (udev->descriptor.iManufacturer) @@ -496,7 +525,7 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; -static void usb_create_intf_ep_files(struct usb_interface *intf) +static inline void usb_create_intf_ep_files(struct usb_interface *intf) { struct usb_host_interface *iface_desc; int i; @@ -504,17 +533,17 @@ static void usb_create_intf_ep_files(struct usb_interface *intf) iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], - interface_to_usbdev(intf)); + interface_to_usbdev(intf)); } -static void usb_remove_intf_ep_files(struct usb_interface *intf) +static inline void usb_remove_intf_ep_files(struct usb_interface *intf) { struct usb_host_interface *iface_desc; int i; iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) - usb_remove_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i]); + usb_remove_ep_files(&iface_desc->endpoint[i]); } void usb_create_sysfs_intf_files (struct usb_interface *intf) diff --git a/include/linux/usb.h b/include/linux/usb.h index a2d923fd54f9..465ff4585ca5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -57,10 +57,7 @@ struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; - char *attr_name; - struct attribute_group *attr_group; - struct attribute **attrs; - int num_attrs; + struct kobject *kobj; /* For sysfs info */ unsigned char *extra; /* Extra descriptors */ int extralen; -- cgit v1.2.3 From b724ae77969fd832be71419dca74bece9af287ff Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 15:36:00 -0400 Subject: [PATCH] usbcore: Wrap lines before column 80 I can't stand text lines that wrap-around in my 80-column windows. This patch (as589) makes cosmetic changes to a couple of source files. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 30 +++++++---- include/linux/usb.h | 132 ++++++++++++++++++++++++++++++----------------- 2 files changed, 106 insertions(+), 56 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index f18317fb49ee..4cca77cf0c48 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -221,7 +221,8 @@ static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ -static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##field (struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ struct usb_host_config *actconfig; \ @@ -243,7 +244,8 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") usb_actconfig_attr (bmAttributes, 1, "%2x\n") usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") -static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_configuration_string(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_device *udev; struct usb_host_config *actconfig; @@ -266,7 +268,8 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); usb_actconfig_show(bConfigurationValue, 1, "%u\n"); static ssize_t -set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +set_bConfigurationValue (struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct usb_device *udev = udev = to_usb_device (dev); int config, value; @@ -284,7 +287,8 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, /* String fields */ #define usb_string_attr(name) \ -static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ int len; \ @@ -364,7 +368,8 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); /* Descriptor fields */ #define usb_descriptor_attr_le16(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_device *udev; \ \ @@ -380,7 +385,8 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") #define usb_descriptor_attr(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_device *udev; \ \ @@ -455,11 +461,13 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) /* Interface fields */ #define usb_intf_attr(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ +show_##field (struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct usb_interface *intf = to_usb_interface (dev); \ \ - return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \ + return sprintf (buf, format_string, \ + intf->cur_altsetting->desc.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); @@ -470,7 +478,8 @@ usb_intf_attr (bInterfaceClass, "%02x\n") usb_intf_attr (bInterfaceSubClass, "%02x\n") usb_intf_attr (bInterfaceProtocol, "%02x\n") -static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_interface_string(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_interface *intf; struct usb_device *udev; @@ -487,7 +496,8 @@ static ssize_t show_interface_string(struct device *dev, struct device_attribute } static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); -static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_modalias(struct device *dev, + struct device_attribute *attr, char *buf) { struct usb_interface *intf; struct usb_device *udev; diff --git a/include/linux/usb.h b/include/linux/usb.h index 465ff4585ca5..c500d6b5a16d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -137,7 +137,8 @@ struct usb_interface { * active alternate setting */ unsigned num_altsetting; /* number of alternate settings */ - int minor; /* minor number this interface is bound to */ + int minor; /* minor number this interface is + * bound to */ enum usb_interface_condition condition; /* state of binding */ struct device dev; /* interface specific device info */ struct class_device *class_dev; @@ -249,7 +250,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\ type,(void**)ptr) -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ struct usb_operations; @@ -269,7 +270,8 @@ struct usb_bus { unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ - int devnum_next; /* Next open device number in round-robin allocation */ + int devnum_next; /* Next open device number in + * round-robin allocation */ struct usb_devmap devmap; /* device address allocation map */ struct usb_operations *op; /* Operations (specific to the HC) */ @@ -290,15 +292,16 @@ struct usb_bus { struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ struct class_device *class_dev; /* class device for this bus */ - struct kref kref; /* handles reference counting this bus */ - void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ + struct kref kref; /* reference counting for this bus */ + void (*release)(struct usb_bus *bus); + #if defined(CONFIG_USB_MON) struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif }; -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* This is arbitrary. * From USB 2.0 spec Table 11-13, offset 7, a hub can @@ -327,7 +330,8 @@ struct usb_device { struct semaphore serialize; - unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ + unsigned int toggle[2]; /* one bit for each endpoint + * ([0] = IN, [1] = OUT) */ struct usb_device *parent; /* our hub, unless we're the root */ struct usb_bus *bus; /* Bus we're part of */ @@ -344,7 +348,7 @@ struct usb_device { char **rawdescriptors; /* Raw descriptors for each config */ - int have_langid; /* whether string_langid is valid yet */ + int have_langid; /* whether string_langid is valid */ int string_langid; /* language ID for strings */ char *product; @@ -441,22 +445,31 @@ extern struct usb_host_interface *usb_altnum_to_altsetting( * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are * high speed, and a different one if they are full or low speed. */ -static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) +static inline int usb_make_path (struct usb_device *dev, char *buf, + size_t size) { int actual; - actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath); + actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, + dev->devpath); return (actual >= (int)size) ? -1 : actual; } /*-------------------------------------------------------------------------*/ -#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) -#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) -#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) +#define USB_DEVICE_ID_MATCH_DEVICE \ + (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) +#define USB_DEVICE_ID_MATCH_DEV_RANGE \ + (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) +#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ + (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) #define USB_DEVICE_ID_MATCH_DEV_INFO \ - (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL) + (USB_DEVICE_ID_MATCH_DEV_CLASS | \ + USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \ + USB_DEVICE_ID_MATCH_DEV_PROTOCOL) #define USB_DEVICE_ID_MATCH_INT_INFO \ - (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL) + (USB_DEVICE_ID_MATCH_INT_CLASS | \ + USB_DEVICE_ID_MATCH_INT_SUBCLASS | \ + USB_DEVICE_ID_MATCH_INT_PROTOCOL) /** * USB_DEVICE - macro used to describe a specific usb device @@ -467,9 +480,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific device. */ #define USB_DEVICE(vend,prod) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod) + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \ + .idProduct = (prod) /** - * USB_DEVICE_VER - macro used to describe a specific usb device with a version range + * USB_DEVICE_VER - macro used to describe a specific usb device with a + * version range * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @lo: the bcdDevice_lo value @@ -479,7 +494,9 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific device, with a version range. */ #define USB_DEVICE_VER(vend,prod,lo,hi) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) + .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \ + .idVendor = (vend), .idProduct = (prod), \ + .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) /** * USB_DEVICE_INFO - macro used to describe a class of usb devices @@ -491,7 +508,8 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific class of devices. */ #define USB_DEVICE_INFO(cl,sc,pr) \ - .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr) + .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \ + .bDeviceSubClass = (sc), .bDeviceProtocol = (pr) /** * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces @@ -503,9 +521,10 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) * specific class of interfaces. */ #define USB_INTERFACE_INFO(cl,sc,pr) \ - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \ + .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /** * struct usb_driver - identifies USB driver to usbcore @@ -558,7 +577,8 @@ struct usb_driver { void (*disconnect) (struct usb_interface *intf); - int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf); + int (*ioctl) (struct usb_interface *intf, unsigned int code, + void *buf); int (*suspend) (struct usb_interface *intf, pm_message_t message); int (*resume) (struct usb_interface *intf); @@ -601,7 +621,7 @@ extern void usb_deregister_dev(struct usb_interface *intf, extern int usb_disabled(void); -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* * URB support, for asynchronous request completions @@ -611,12 +631,14 @@ extern int usb_disabled(void); * urb->transfer_flags: */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ -#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ +#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame + * ignored */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ #define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */ #define URB_NO_FSBR 0x0020 /* UHCI-specific */ -#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ -#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ +#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ +#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt + * needed */ struct usb_iso_packet_descriptor { unsigned int offset; @@ -804,7 +826,8 @@ struct urb u8 reject; /* submissions will fail */ /* public, documented fields in the urb that can be used by drivers */ - struct list_head urb_list; /* list head for use by the urb owner */ + struct list_head urb_list; /* list head for use by the urb's + * current owner */ struct usb_device *dev; /* (in) pointer to associated device */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ @@ -817,14 +840,16 @@ struct urb dma_addr_t setup_dma; /* (in) dma addr for setup_packet */ int start_frame; /* (modify) start frame (ISO) */ int number_of_packets; /* (in) number of ISO packets */ - int interval; /* (modify) transfer interval (INT/ISO) */ + int interval; /* (modify) transfer interval + * (INT/ISO) */ int error_count; /* (return) number of ISO errors */ void *context; /* (in) context for completion */ usb_complete_t complete; /* (in) completion routine */ - struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */ + struct usb_iso_packet_descriptor iso_frame_desc[0]; + /* (in) ISO ONLY */ }; -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /** * usb_fill_control_urb - initializes a control urb @@ -1049,7 +1074,7 @@ void usb_sg_cancel (struct usb_sg_request *io); void usb_sg_wait (struct usb_sg_request *io); -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* * For various legacy reasons, Linux has a small cookie that's paired with @@ -1090,23 +1115,34 @@ void usb_sg_wait (struct usb_sg_request *io); /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) -#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep))) +#define usb_settoggle(dev, ep, out, bit) \ + ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ + ((bit) << (ep))) -static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint) +static inline unsigned int __create_pipe(struct usb_device *dev, + unsigned int endpoint) { return (dev->devnum << 8) | (endpoint << 15); } /* Create various pipes... */ -#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndctrlpipe(dev,endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvctrlpipe(dev,endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndisocpipe(dev,endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvisocpipe(dev,endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndbulkpipe(dev,endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvbulkpipe(dev,endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) +#define usb_sndintpipe(dev,endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) +#define usb_rcvintpipe(dev,endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) /*-------------------------------------------------------------------------*/ @@ -1130,7 +1166,7 @@ usb_maxpacket(struct usb_device *udev, int pipe, int is_out) return le16_to_cpu(ep->desc.wMaxPacketSize); } -/* -------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------- */ /* Events from the usb core */ #define USB_DEVICE_ADD 0x0001 @@ -1141,14 +1177,18 @@ extern void usb_register_notify(struct notifier_block *nb); extern void usb_unregister_notify(struct notifier_block *nb); #ifdef DEBUG -#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg) +#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ + __FILE__ , ## arg) #else #define dbg(format, arg...) do {} while (0) #endif -#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg) +#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ + __FILE__ , ## arg) +#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , \ + __FILE__ , ## arg) +#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , \ + __FILE__ , ## arg) #endif /* __KERNEL__ */ -- cgit v1.2.3 From 4f62efe67f077db17dad03a1d4c9665000a3eb45 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 24 Oct 2005 16:24:14 -0400 Subject: [PATCH] usbcore: Fix handling of sysfs strings and other attributes This patch (as592) makes a few small improvements to the way device strings are handled, and it fixes some bugs in a couple of other sysfs attribute routines. (Look at show_configuration_string() to see what I mean.) Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 10 ++++++---- drivers/usb/core/hub.c | 22 ++++----------------- drivers/usb/core/message.c | 48 +++++++++++++++++++++++++++++----------------- drivers/usb/core/sysfs.c | 36 +++++++++++++++------------------- drivers/usb/core/usb.h | 1 + include/linux/usb.h | 10 ++++++---- 6 files changed, 62 insertions(+), 65 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 63f374e62db2..993019500cc3 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -112,8 +112,12 @@ void usb_release_interface_cache(struct kref *ref) struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); int j; - for (j = 0; j < intfc->num_altsetting; j++) - kfree(intfc->altsetting[j].endpoint); + for (j = 0; j < intfc->num_altsetting; j++) { + struct usb_host_interface *alt = &intfc->altsetting[j]; + + kfree(alt->endpoint); + kfree(alt->string); + } kfree(intfc); } @@ -420,8 +424,6 @@ void usb_destroy_configuration(struct usb_device *dev) struct usb_host_config *cf = &dev->config[c]; kfree(cf->string); - cf->string = NULL; - for (i = 0; i < cf->desc.bNumInterfaces; i++) { if (cf->intf_cache[i]) kref_put(&cf->intf_cache[i]->ref, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8ba5854e5387..1bacb374b007 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1204,21 +1204,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) {} #endif -static void get_string(struct usb_device *udev, char **string, int index) -{ - char *buf; - - if (!index) - return; - buf = kmalloc(256, GFP_KERNEL); - if (!buf) - return; - if (usb_string(udev, index, buf, 256) > 0) - *string = buf; - else - kfree(buf); -} - #ifdef CONFIG_USB_OTG #include "otg_whitelist.h" @@ -1257,9 +1242,10 @@ int usb_new_device(struct usb_device *udev) } /* read the standard strings and cache them if present */ - get_string(udev, &udev->product, udev->descriptor.iProduct); - get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer); - get_string(udev, &udev->serial, udev->descriptor.iSerialNumber); + udev->product = usb_cache_string(udev, udev->descriptor.iProduct); + udev->manufacturer = usb_cache_string(udev, + udev->descriptor.iManufacturer); + udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); /* Tell the world! */ dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3519f317898e..644a3d4f12aa 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -787,6 +787,31 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) return err; } +/** + * usb_cache_string - read a string descriptor and cache it for later use + * @udev: the device whose string descriptor is being read + * @index: the descriptor index + * + * Returns a pointer to a kmalloc'ed buffer containing the descriptor string, + * or NULL if the index is 0 or the string could not be read. + */ +char *usb_cache_string(struct usb_device *udev, int index) +{ + char *buf; + char *smallbuf = NULL; + int len; + + if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) { + if ((len = usb_string(udev, index, buf, 256)) > 0) { + if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL) + return buf; + memcpy(smallbuf, buf, len); + } + kfree(buf); + } + return smallbuf; +} + /* * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) * @dev: the device whose device descriptor is being updated @@ -1008,8 +1033,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); usb_remove_sysfs_intf_files(interface); - kfree(interface->cur_altsetting->string); - interface->cur_altsetting->string = NULL; device_del (&interface->dev); } @@ -1422,12 +1445,9 @@ free_interfaces: } kfree(new_interfaces); - if ((cp->desc.iConfiguration) && - (cp->string == NULL)) { - cp->string = kmalloc(256, GFP_KERNEL); - if (cp->string) - usb_string(dev, cp->desc.iConfiguration, cp->string, 256); - } + if (cp->string == NULL) + cp->string = usb_cache_string(dev, + cp->desc.iConfiguration); /* Now that all the interfaces are set up, register them * to trigger binding of drivers to interfaces. probe() @@ -1437,13 +1457,12 @@ free_interfaces: */ for (i = 0; i < nintf; ++i) { struct usb_interface *intf = cp->interface[i]; - struct usb_interface_descriptor *desc; + struct usb_host_interface *alt = intf->cur_altsetting; - desc = &intf->altsetting [0].desc; dev_dbg (&dev->dev, "adding %s (config #%d, interface %d)\n", intf->dev.bus_id, configuration, - desc->bInterfaceNumber); + alt->desc.bInterfaceNumber); ret = device_add (&intf->dev); if (ret != 0) { dev_err(&dev->dev, @@ -1452,13 +1471,6 @@ free_interfaces: ret); continue; } - if ((intf->cur_altsetting->desc.iInterface) && - (intf->cur_altsetting->string == NULL)) { - intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL); - if (intf->cur_altsetting->string) - usb_string(dev, intf->cur_altsetting->desc.iInterface, - intf->cur_altsetting->string, 256); - } usb_create_sysfs_intf_files (intf); } } diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cca77cf0c48..edd83e014452 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -249,18 +249,12 @@ static ssize_t show_configuration_string(struct device *dev, { struct usb_device *udev; struct usb_host_config *actconfig; - int len; udev = to_usb_device (dev); actconfig = udev->actconfig; if ((!actconfig) || (!actconfig->string)) return 0; - len = sprintf(buf, actconfig->string, PAGE_SIZE); - if (len < 0) - return 0; - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; + return sprintf(buf, "%s\n", actconfig->string); } static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); @@ -291,15 +285,9 @@ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ - int len; \ \ udev = to_usb_device (dev); \ - len = snprintf(buf, 256, "%s", udev->name); \ - if (len < 0) \ - return 0; \ - buf[len] = '\n'; \ - buf[len+1] = 0; \ - return len+1; \ + return sprintf(buf, "%s\n", udev->name); \ } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); @@ -449,11 +437,11 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) usb_remove_ep_files(&udev->ep0); sysfs_remove_group(&dev->kobj, &dev_attr_grp); - if (udev->descriptor.iManufacturer) + if (udev->manufacturer) device_remove_file(dev, &dev_attr_manufacturer); - if (udev->descriptor.iProduct) + if (udev->product) device_remove_file(dev, &dev_attr_product); - if (udev->descriptor.iSerialNumber) + if (udev->serial) device_remove_file(dev, &dev_attr_serial); device_remove_file (dev, &dev_attr_configuration); } @@ -535,7 +523,8 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; -static inline void usb_create_intf_ep_files(struct usb_interface *intf) +static inline void usb_create_intf_ep_files(struct usb_interface *intf, + struct usb_device *udev) { struct usb_host_interface *iface_desc; int i; @@ -543,7 +532,7 @@ static inline void usb_create_intf_ep_files(struct usb_interface *intf) iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], - interface_to_usbdev(intf)); + udev); } static inline void usb_remove_intf_ep_files(struct usb_interface *intf) @@ -558,11 +547,16 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf) void usb_create_sysfs_intf_files (struct usb_interface *intf) { + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_host_interface *alt = intf->cur_altsetting; + sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); - if (intf->cur_altsetting->string) + if (alt->string == NULL) + alt->string = usb_cache_string(udev, alt->desc.iInterface); + if (alt->string) device_create_file(&intf->dev, &dev_attr_interface); - usb_create_intf_ep_files(intf); + usb_create_intf_ep_files(intf, udev); } void usb_remove_sysfs_intf_files (struct usb_interface *intf) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 888dbe443695..1c4a68499dce 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -13,6 +13,7 @@ extern void usb_disable_device (struct usb_device *dev, int skip_ep0); extern int usb_get_device_descriptor(struct usb_device *dev, unsigned int size); +extern char *usb_cache_string(struct usb_device *udev, int index); extern int usb_set_configuration(struct usb_device *dev, int configuration); extern void usb_lock_all_devices(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index c500d6b5a16d..748d04385256 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -231,7 +231,7 @@ struct usb_interface_cache { struct usb_host_config { struct usb_config_descriptor desc; - char *string; + char *string; /* iConfiguration string, if present */ /* the interfaces associated with this configuration, * stored in no particular order */ struct usb_interface *interface[USB_MAXINTERFACES]; @@ -351,9 +351,11 @@ struct usb_device { int have_langid; /* whether string_langid is valid */ int string_langid; /* language ID for strings */ - char *product; - char *manufacturer; - char *serial; /* static strings from the device */ + /* static strings from the device */ + char *product; /* iProduct string, if present */ + char *manufacturer; /* iManufacturer string, if present */ + char *serial; /* iSerialNumber string, if present */ + struct list_head filelist; struct class_device *class_dev; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ -- cgit v1.2.3 From 9a7834d06d553d02cc6e659e94772f69a8b5367f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 23 Oct 2005 23:02:20 -0700 Subject: [PATCH] USB: fix pm patches with CONFIG_PM off part 2 With CONFIG_PM=n: drivers/built-in.o(.text+0x1098c): In function `hub_thread': drivers/usb/core/hub.c:2673: undefined reference to `.dpm_runtime_resume' drivers/built-in.o(.text+0x10998):drivers/usb/core/hub.c:2674: undefined reference to `.dpm_runtime_resume' Please, never ever ever put extern decls into .c files. Use the darn header files :( Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/power.h | 13 ------------- drivers/usb/core/hub.c | 2 -- include/linux/pm.h | 13 +++++++++++++ 3 files changed, 13 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 2e700d795cf1..fb3d35a9e101 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -67,9 +67,6 @@ extern int suspend_device(struct device *, pm_message_t); * runtime.c */ -extern int dpm_runtime_suspend(struct device *, pm_message_t); -extern void dpm_runtime_resume(struct device *); - #else /* CONFIG_PM */ @@ -82,14 +79,4 @@ static inline void device_pm_remove(struct device * dev) } -static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) -{ - return 0; -} - -static inline void dpm_runtime_resume(struct device * dev) -{ - -} - #endif diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1bacb374b007..9660a8909b7c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2652,8 +2652,6 @@ static void hub_events(void) * stub "device" node was never suspended. */ if (i) { - extern void dpm_runtime_resume(struct device *); - dpm_runtime_resume(&hdev->dev); dpm_runtime_resume(&intf->dev); } diff --git a/include/linux/pm.h b/include/linux/pm.h index 83bae1cbe55b..c61d5de837ef 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -243,6 +243,9 @@ extern int device_suspend(pm_message_t state); #define device_may_wakeup(dev) \ (device_can_wakeup(dev) && (dev)->power.should_wakeup) +extern int dpm_runtime_suspend(struct device *, pm_message_t); +extern void dpm_runtime_resume(struct device *); + #else /* !CONFIG_PM */ static inline int device_suspend(pm_message_t state) @@ -253,6 +256,16 @@ static inline int device_suspend(pm_message_t state) #define device_set_wakeup_enable(dev,val) do{}while(0) #define device_may_wakeup(dev) (0) +static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) +{ + return 0; +} + +static inline void dpm_runtime_resume(struct device * dev) +{ + +} + #endif /* changes to device_may_wakeup take effect on the next pm state change. -- cgit v1.2.3 From 360ac8e2f1a38c3497739636c3b702352d1ad0ae Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Oct 2005 15:03:41 -0700 Subject: [ETH]: ether address compare Expose faster ether compare for use by protocols and other driver. And change name to be more consistent with other ether address manipulation routines in same file Signed-off-by: Stephen Hemminger Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/etherdevice.h | 16 ++++++++++++++++ net/ethernet/eth.c | 17 ++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 4522c7186bf3..cc84934f9059 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -104,6 +104,22 @@ static inline void random_ether_addr(u8 *addr) addr [0] &= 0xfe; /* clear multicast bit */ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ } + +/** + * compare_ether_addr - Compare two Ethernet addresses + * @addr1: Pointer to a six-byte array containing the Ethernet address + * @addr2 Pointer other six-byte array containing the Ethernet address + * + * Compare two ethernet addresses, returns 0 if equal + */ +static inline unsigned compare_ether_addr(const u8 *_a, const u8 *_b) +{ + const u16 *a = (const u16 *) _a; + const u16 *b = (const u16 *) _b; + + BUILD_BUG_ON(ETH_ALEN != 6); + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; +} #endif /* __KERNEL__ */ #endif /* _LINUX_ETHERDEVICE_H */ diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 68a5ca866442..e24577367274 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *skb) return 0; } -static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b) -{ - const unsigned short *dest = (unsigned short *) __a; - const unsigned short *devaddr = (unsigned short *) __b; - unsigned int res; - - BUILD_BUG_ON(ETH_ALEN != 6); - res = ((dest[0] ^ devaddr[0]) | - (dest[1] ^ devaddr[1]) | - (dest[2] ^ devaddr[2])) != 0; - - return res; -} /* * Determine the packet's protocol ID. The rule here is that we @@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) eth = eth_hdr(skb); if (*eth->h_dest&1) { - if (!compare_eth_addr(eth->h_dest, dev->broadcast)) + if (!compare_ether_addr(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) */ else if(1 /*dev->flags&IFF_PROMISC*/) { - if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr))) + if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; } -- cgit v1.2.3 From bdf21b18b4abf983db38f04ef7fec88f47389867 Mon Sep 17 00:00:00 2001 From: Pete Popov Date: Thu, 14 Jul 2005 17:47:57 +0000 Subject: Philips PNX8550 support: MIPS32-like core with 2 Trimedias on it. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 21 ++ arch/mips/Makefile | 14 ++ arch/mips/kernel/cpu-probe.c | 19 ++ arch/mips/kernel/proc.c | 3 +- arch/mips/kernel/time.c | 3 + arch/mips/mm/tlbex.c | 1 + arch/mips/pci/Makefile | 1 + arch/mips/pci/fixup-pnx8550.c | 57 +++++ arch/mips/pci/ops-pnx8550.c | 284 +++++++++++++++++++++ arch/mips/philips/pnx8550/common/Kconfig | 1 + arch/mips/philips/pnx8550/common/Makefile | 27 ++ arch/mips/philips/pnx8550/common/gdb_hook.c | 109 ++++++++ arch/mips/philips/pnx8550/common/int.c | 293 ++++++++++++++++++++++ arch/mips/philips/pnx8550/common/mipsIRQ.S | 76 ++++++ arch/mips/philips/pnx8550/common/pci.c | 133 ++++++++++ arch/mips/philips/pnx8550/common/platform.c | 135 ++++++++++ arch/mips/philips/pnx8550/common/proc.c | 113 +++++++++ arch/mips/philips/pnx8550/common/prom.c | 138 ++++++++++ arch/mips/philips/pnx8550/common/reset.c | 49 ++++ arch/mips/philips/pnx8550/common/setup.c | 149 +++++++++++ arch/mips/philips/pnx8550/common/time.c | 105 ++++++++ arch/mips/philips/pnx8550/jbs/Makefile | 4 + arch/mips/philips/pnx8550/jbs/board_setup.c | 65 +++++ arch/mips/philips/pnx8550/jbs/init.c | 57 +++++ arch/mips/philips/pnx8550/jbs/irqmap.c | 36 +++ include/asm-mips/bootinfo.h | 1 + include/asm-mips/cpu.h | 4 +- include/asm-mips/mach-pnx8550/cm.h | 43 ++++ include/asm-mips/mach-pnx8550/glb.h | 86 +++++++ include/asm-mips/mach-pnx8550/int.h | 140 +++++++++++ include/asm-mips/mach-pnx8550/kernel-entry-init.h | 262 +++++++++++++++++++ include/asm-mips/mach-pnx8550/nand.h | 121 +++++++++ include/asm-mips/mach-pnx8550/pci.h | 185 ++++++++++++++ include/asm-mips/mach-pnx8550/uart.h | 16 ++ include/asm-mips/mach-pnx8550/usb.h | 32 +++ include/asm-mips/mipsregs.h | 12 + include/linux/serial_core.h | 3 +- include/linux/serial_ip3106.h | 81 ++++++ 38 files changed, 2876 insertions(+), 3 deletions(-) create mode 100644 arch/mips/pci/fixup-pnx8550.c create mode 100644 arch/mips/pci/ops-pnx8550.c create mode 100644 arch/mips/philips/pnx8550/common/Kconfig create mode 100644 arch/mips/philips/pnx8550/common/Makefile create mode 100644 arch/mips/philips/pnx8550/common/gdb_hook.c create mode 100644 arch/mips/philips/pnx8550/common/int.c create mode 100644 arch/mips/philips/pnx8550/common/mipsIRQ.S create mode 100644 arch/mips/philips/pnx8550/common/pci.c create mode 100644 arch/mips/philips/pnx8550/common/platform.c create mode 100644 arch/mips/philips/pnx8550/common/proc.c create mode 100644 arch/mips/philips/pnx8550/common/prom.c create mode 100644 arch/mips/philips/pnx8550/common/reset.c create mode 100644 arch/mips/philips/pnx8550/common/setup.c create mode 100644 arch/mips/philips/pnx8550/common/time.c create mode 100644 arch/mips/philips/pnx8550/jbs/Makefile create mode 100644 arch/mips/philips/pnx8550/jbs/board_setup.c create mode 100644 arch/mips/philips/pnx8550/jbs/init.c create mode 100644 arch/mips/philips/pnx8550/jbs/irqmap.c create mode 100644 include/asm-mips/mach-pnx8550/cm.h create mode 100644 include/asm-mips/mach-pnx8550/glb.h create mode 100644 include/asm-mips/mach-pnx8550/int.h create mode 100644 include/asm-mips/mach-pnx8550/kernel-entry-init.h create mode 100644 include/asm-mips/mach-pnx8550/nand.h create mode 100644 include/asm-mips/mach-pnx8550/pci.h create mode 100644 include/asm-mips/mach-pnx8550/uart.h create mode 100644 include/asm-mips/mach-pnx8550/usb.h create mode 100644 include/linux/serial_ip3106.h (limited to 'include/linux') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4ef015f580f9..f6b25ae1861b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -489,6 +489,16 @@ config HYPERTRANSPORT bool "Hypertransport Support for PMC-Sierra Yosemite" depends on PMC_YOSEMITE +config PNX8550_V2PCI + bool "Support for Philips PNX8550 based Viper2-PCI board" + select PNX8550 + select SYS_SUPPORTS_LITTLE_ENDIAN + +config PNX8550_JBS + bool "Support for Philips PNX8550 based JBS board" + select PNX8550 + select SYS_SUPPORTS_LITTLE_ENDIAN + config DDB5074 bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -827,6 +837,7 @@ config TOSHIBA_FPCIB0 source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" +source "arch/mips/philips/pnx8550/common/Kconfig" config RWSEM_GENERIC_SPINLOCK bool @@ -954,6 +965,16 @@ config ITE_BOARD_GEN depends on MIPS_IVR || MIPS_ITE8172 default y +config PNX8550 + bool + select SOC_PNX8550 + +config SOC_PNX8550 + bool + select SYS_SUPPORTS_32BIT_KERNEL + select DMA_NONCOHERENT + select HW_HAS_PCI + config SWAP_IO_SPACE bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6780d115a7dc..d62787ab9fff 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -228,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000) += \ $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ -Wa,--trap + cflags-$(CONFIG_CPU_SB1) += \ $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ -Wa,--trap @@ -560,6 +561,19 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000 # load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000 +# +# Common Philips PNX8550 +# +core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/ +cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550 + +# +# Philips PNX8550 JBS board +# +libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/ +#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550 +load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000 + # # SGI IP22 (Indy/Indigo2) # diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 844126b39ed3..70c8ad9bc8fc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -121,6 +121,7 @@ static inline void check_wait(void) case CPU_24K: case CPU_25KF: case CPU_34K: + case CPU_PR4450: cpu_wait = r4k_wait; printk(" available.\n"); break; @@ -624,6 +625,21 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) } } +static inline void cpu_probe_philips(struct cpuinfo_mips *c) +{ + decode_configs(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_PR4450: + c->cputype = CPU_PR4450; + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + panic("Unknown Philips Core!"); /* REVISIT: die? */ + break; + } +} + + __init void cpu_probe(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -649,6 +665,9 @@ __init void cpu_probe(void) case PRID_COMP_SANDCRAFT: cpu_probe_sandcraft(c); break; + case PRID_COMP_PHILIPS: + cpu_probe_philips(c); + break; default: c->cputype = CPU_UNKNOWN; } diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 1bd40af508ed..e46a92d01d51 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -80,7 +80,8 @@ static const char *cpu_name[] = { [CPU_VR4133] = "NEC VR4133", [CPU_VR4181] = "NEC VR4181", [CPU_VR4181A] = "NEC VR4181A", - [CPU_SR71000] = "Sandcraft SR71000" + [CPU_SR71000] = "Sandcraft SR71000", + [CPU_PR4450] = "Philips PR4450", }; diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index fbc153c8f833..a24651dfaaba 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,6 +11,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include #include #include #include @@ -112,8 +113,10 @@ static void c0_timer_ack(void) { unsigned int count; +#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */ /* Ack this timer interrupt and set the next one. */ expirelo += cycles_per_jiffy; +#endif write_c0_compare(expirelo); /* Check to see if we have missed any timer interrupts. */ diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index c1d394d36f6c..a876ed6cde24 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -844,6 +844,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l, case CPU_AU1500: case CPU_AU1550: case CPU_AU1200: + case CPU_PR4450: i_nop(p); tlbw(p); break; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 83d81c9cdc2b..ea8438b81fed 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o +obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c new file mode 100644 index 000000000000..4256b3b30b77 --- /dev/null +++ b/arch/mips/pci/fixup-pnx8550.c @@ -0,0 +1,57 @@ +/* + * Philips PNX8550 pci fixups. + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddealley.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include + +#include +#include + + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +extern char irq_tab_jbs[][5]; + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* no need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return irq_tab_jbs[slot][pin]; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c new file mode 100644 index 000000000000..454b65cc3354 --- /dev/null +++ b/arch/mips/pci/ops-pnx8550.c @@ -0,0 +1,284 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * + * 2.6 port, Embedded Alley Solutions, Inc + * + * Based on: + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +static inline void clear_status(void) +{ + unsigned long pci_stat; + + pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS); + outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR); +} + +static inline unsigned int +calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where) +{ + unsigned int addr; + + addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0); + addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc); + + return addr; +} + +static int +config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val) +{ + unsigned int flags; + unsigned long loops = 0; + unsigned long ioaddr = calc_cfg_addr(bus, devfn, where); + + local_irq_save(flags); + /*Clear pending interrupt status */ + if (inl(PCI_BASE | PCI_GPPM_STATUS)) { + clear_status(); + while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ; + } + + outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR); + + if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE)) + outl(*val, PCI_BASE | PCI_GPPM_WDAT); + + outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK), + PCI_BASE | PCI_GPPM_CTRL); + + loops = + ((loops_per_jiffy * + PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT)); + while (1) { + if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) { + if ((pci_cmd == PCI_CMD_IOR) || + (pci_cmd == PCI_CMD_CONFIG_READ)) + *val = inl(PCI_BASE | PCI_GPPM_RDAT); + clear_status(); + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) { + break; + } + + loops--; + if (loops == 0) { + printk("%s : Arbiter Locked.\n", __FUNCTION__); + } + } + + clear_status(); + if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) { + printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n", + __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr, + pci_cmd); + } + + if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ)) + *val = 0xffffffff; + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int +read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val) +{ + unsigned int data = 0; + int err; + + if (bus == 0) + return -1; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data); + switch (where & 0x03) { + case 0: + *val = (unsigned char)(data & 0x000000ff); + break; + case 1: + *val = (unsigned char)((data & 0x0000ff00) >> 8); + break; + case 2: + *val = (unsigned char)((data & 0x00ff0000) >> 16); + break; + case 3: + *val = (unsigned char)((data & 0xff000000) >> 24); + break; + } + + return err; +} + +static int +read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val) +{ + unsigned int data = 0; + int err; + + if (bus == 0) + return -1; + + if (where & 0x01) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data); + switch (where & 0x02) { + case 0: + *val = (unsigned short)(data & 0x0000ffff); + break; + case 2: + *val = (unsigned short)((data & 0xffff0000) >> 16); + break; + } + + return err; +} + +static int +read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val) +{ + int err; + if (bus == 0) + return -1; + + if (where & 0x03) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val); + + return err; +} + +static int +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val) +{ + unsigned int data = (unsigned int)val; + int err; + + if (bus == 0) + return -1; + + switch (where & 0x03) { + case 1: + data = (data << 8); + break; + case 2: + data = (data << 16); + break; + case 3: + data = (data << 24); + break; + default: + break; + } + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data); + + return err; +} + +static int +write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val) +{ + unsigned int data = (unsigned int)val; + int err; + + if (bus == 0) + return -1; + + if (where & 0x01) + return PCIBIOS_BAD_REGISTER_NUMBER; + + switch (where & 0x02) { + case 2: + data = (data << 16); + break; + default: + break; + } + err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data); + + return err; +} + +static int +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val) +{ + int err; + if (bus == 0) + return -1; + + if (where & 0x03) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val); + + return err; +} + +static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) +{ + switch (size) { + case 1: { + u8 _val; + int rc = read_config_byte(bus, devfn, where, &_val); + *val = _val; + return rc; + } + case 2: { + u16 _val; + int rc = read_config_word(bus, devfn, where, &_val); + *val = _val; + return rc; + } + default: + return read_config_dword(bus, devfn, where, val); + } +} + +static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + switch (size) { + case 1: + return write_config_byte(bus, devfn, where, (u8) val); + case 2: + return write_config_word(bus, devfn, where, (u16) val); + default: + return write_config_dword(bus, devfn, where, val); + } +} + +struct pci_ops pnx8550_pci_ops = { + config_read, + config_write +}; diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig new file mode 100644 index 000000000000..072572d173cc --- /dev/null +++ b/arch/mips/philips/pnx8550/common/Kconfig @@ -0,0 +1 @@ +# Place holder diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile new file mode 100644 index 000000000000..6e38f3bc443c --- /dev/null +++ b/arch/mips/philips/pnx8550/common/Makefile @@ -0,0 +1,27 @@ +# +# Per Hallsmark, per.hallsmark@mvista.com +# +# ######################################################################## +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# ####################################################################### +# +# Makefile for the PNX8550 specific kernel interface routines +# under Linux. +# + +obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_KGDB) += gdb_hook.o diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c new file mode 100644 index 000000000000..ad4624f6d9bc --- /dev/null +++ b/arch/mips/philips/pnx8550/common/gdb_hook.c @@ -0,0 +1,109 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * This is the interface to the remote debugger stub. + * + */ +#include +#include +#include +#include +#include + +#include +#include + +#include + +static struct serial_state rs_table[IP3106_NR_PORTS] = { +}; +static struct async_struct kdb_port_info = {0}; + +void rs_kgdb_hook(int tty_no) +{ + struct serial_state *ser = &rs_table[tty_no]; + + kdb_port_info.state = ser; + kdb_port_info.magic = SERIAL_MAGIC; + kdb_port_info.port = tty_no; + kdb_port_info.flags = ser->flags; + + /* + * Clear all interrupts + */ + /* Clear all the transmitter FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST; + /* Clear all the receiver FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST; + /* Clear all interrupts */ + ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX | + IP3106_UART_INT_ALLTX; + + /* + * Now, initialize the UART + */ + ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT; + ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud +} + +int putDebugChar(char c) +{ + /* Wait until FIFO not full */ + while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16) + ; + /* Send one char */ + ip3106_fifo(UART_BASE, kdb_port_info.port) = c; + + return 1; +} + +char getDebugChar(void) +{ + char ch; + + /* Wait until there is a char in the FIFO */ + while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) & + IP3106_UART_FIFO_RXFIFO) >> 8)) + ; + /* Read one char */ + ch = ip3106_fifo(UART_BASE, kdb_port_info.port) & + IP3106_UART_FIFO_RBRTHR; + /* Advance the RX FIFO read pointer */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT; + return (ch); +} + +void rs_disable_debug_interrupts(void) +{ + ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */ +} + +void rs_enable_debug_interrupts(void) +{ + /* Clear all the transmitter FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST; + /* Clear all the receiver FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST; + /* Clear all interrupts */ + ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX | + IP3106_UART_INT_ALLTX; + ip3106_ien(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */ +} diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c new file mode 100644 index 000000000000..546144988bf5 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/int.c @@ -0,0 +1,293 @@ +/* + * + * Copyright (C) 2005 Embedded Alley Solutions, Inc + * Ported to 2.6. + * + * Per Hallsmark, per.hallsmark@mvista.com + * Copyright (C) 2000, 2001 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * + * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern asmlinkage void cp0_irqdispatch(void); + +static DEFINE_SPINLOCK(irq_lock); + +/* default prio for interrupts */ +/* first one is a no-no so therefore always prio 0 (disabled) */ +static char gic_prio[PNX8550_INT_GIC_TOTINT] = { + 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69 + 1 // 70 +}; + +void hw0_irqdispatch(int irq, struct pt_regs *regs) +{ + /* find out which interrupt */ + irq = PNX8550_GIC_VECTOR_0 >> 3; + + if (irq == 0) { + printk("hw0_irqdispatch: irq 0, spurious interrupt?\n"); + return; + } + do_IRQ(PNX8550_INT_GIC_MIN + irq, regs); +} + + +void timer_irqdispatch(int irq, struct pt_regs *regs) +{ + irq = (0x01c0 & read_c0_config7()) >> 6; + + if (irq == 0) { + printk("timer_irqdispatch: irq 0, spurious interrupt?\n"); + return; + } + + if (irq & 0x1) { + do_IRQ(PNX8550_INT_TIMER1, regs); + } + if (irq & 0x2) { + do_IRQ(PNX8550_INT_TIMER2, regs); + } + if (irq & 0x4) { + do_IRQ(PNX8550_INT_TIMER3, regs); + } +} + +static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) +{ + unsigned long status = read_c0_status(); + + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + + write_c0_status(status); +} + +static inline void mask_gic_int(unsigned int irq_nr) +{ + /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */ + PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */ +} + +static inline void unmask_gic_int(unsigned int irq_nr) +{ + /* set prio mask to lower four bits and enable interrupt */ + PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr]; +} + +static inline void mask_irq(unsigned int irq_nr) +{ + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { + modify_cp0_intmask(1 << irq_nr, 0); + } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_GIC_MAX)) { + mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN); + } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_TIMER_MAX)) { + modify_cp0_intmask(1 << 7, 0); + } else { + printk("mask_irq: irq %d doesn't exist!\n", irq_nr); + } +} + +static inline void unmask_irq(unsigned int irq_nr) +{ + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { + modify_cp0_intmask(0, 1 << irq_nr); + } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_GIC_MAX)) { + unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN); + } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_TIMER_MAX)) { + modify_cp0_intmask(0, 1 << 7); + } else { + printk("mask_irq: irq %d doesn't exist!\n", irq_nr); + } +} + +#define pnx8550_disable pnx8550_ack +static void pnx8550_ack(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define pnx8550_enable pnx8550_unmask +static void pnx8550_unmask(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_irq(unsigned int irq_nr) +{ + pnx8550_unmask(irq_nr); + return 0; +} + +static void shutdown_irq(unsigned int irq_nr) +{ + pnx8550_ack(irq_nr); + return; +} + +int pnx8550_set_gic_priority(int irq, int priority) +{ + int gic_irq = irq-PNX8550_INT_GIC_MIN; + int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf; + + gic_prio[gic_irq] = priority; + PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]); + + return prev_priority; +} + +static inline void mask_and_ack_level_irq(unsigned int irq) +{ + pnx8550_disable(irq); + return; +} + +static void end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + pnx8550_enable(irq); + } +} + +static struct hw_interrupt_type level_irq_type = { + .typename = "PNX Level IRQ", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = pnx8550_enable, + .disable = pnx8550_disable, + .ack = mask_and_ack_level_irq, + .end = end_irq, +}; + +static struct irqaction gic_action = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "GIC", +}; + +static struct irqaction timer_action = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "Timer", +}; + +void __init arch_init_irq(void) +{ + int i; + int configPR; + + /* init of cp0 interrupts */ + set_except_vector(0, cp0_irqdispatch); + + for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { + irq_desc[i].handler = &level_irq_type; + pnx8550_ack(i); /* mask the irq just in case */ + } + + /* init of GIC/IPC interrupts */ + /* should be done before cp0 since cp0 init enables the GIC int */ + for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) { + int gic_int_line = i - PNX8550_INT_GIC_MIN; + if (gic_int_line == 0 ) + continue; // don't fiddle with int 0 + /* + * enable change of TARGET, ENABLE and ACTIVE_LOW bits + * set TARGET 0 to route through hw0 interrupt + * set ACTIVE_LOW 0 active high (correct?) + * + * We really should setup an interrupt description table + * to do this nicely. + * Note, PCI INTA is active low on the bus, but inverted + * in the GIC, so to us it's active high. + */ +#ifdef CONFIG_PNX8550_V2PCI + if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) { + /* PCI INT through gpio 8, which is setup in + * pnx8550_setup.c and routed to GPIO + * Interrupt Level 0 (GPIO Connection 58). + * Set it active low. */ + + PNX8550_GIC_REQ(gic_int_line) = 0x1E020000; + } else +#endif + { + PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000; + } + + /* mask/priority is still 0 so we will not get any + * interrupts until it is unmasked */ + + irq_desc[i].handler = &level_irq_type; + } + + /* Priority level 0 */ + PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0; + + /* Set int vector table address */ + PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; + + irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type; + setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); + + /* init of Timer interrupts */ + for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { + irq_desc[i].handler = &level_irq_type; + } + + /* Stop Timer 1-3 */ + configPR = read_c0_config7(); + configPR |= 0x00000038; + write_c0_config7(configPR); + + irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type; + setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); +} + +EXPORT_SYMBOL(pnx8550_set_gic_priority); diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S new file mode 100644 index 000000000000..338bffda3fab --- /dev/null +++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002 Philips, Inc. All rights. + * Copyright (c) 2002 Red Hat, Inc. All rights. + * + * This software may be freely redistributed under the terms of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon arch/mips/galileo-boards/ev64240/int-handler.S + * + */ +#include +#include +#include +#include +#include + +/* + * cp0_irqdispatch + * + * Code to handle in-core interrupt exception. + */ + + .align 5 + .set reorder + .set noat + NESTED(cp0_irqdispatch, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0,CP0_CAUSE + mfc0 t2,CP0_STATUS + + and t0,t2 + + andi t1,t0,STATUSF_IP2 /* int0 hardware line */ + bnez t1,ll_hw0_irq + nop + + andi t1,t0,STATUSF_IP7 /* int5 hardware line */ + bnez t1,ll_timer_irq + nop + + /* wrong alarm or masked ... */ + + j spurious_interrupt + nop + END(cp0_irqdispatch) + + .align 5 + .set reorder +ll_hw0_irq: + li a0,2 + move a1,sp + jal hw0_irqdispatch + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_timer_irq: + mfc0 t3,CP0_CONFIG,7 + andi t4,t3,0x01c0 + beqz t4,ll_timer_out + nop + li a0,7 + move a1,sp + jal timer_irqdispatch + nop + +ll_timer_out: j ret_from_irq + nop diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c new file mode 100644 index 000000000000..baa6905f649f --- /dev/null +++ b/arch/mips/philips/pnx8550/common/pci.c @@ -0,0 +1,133 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include + +#include +#include +#include + +static struct resource pci_io_resource = { + "pci IO space", + (u32)(PNX8550_PCIIO + 0x1000), /* reserve regacy I/O space */ + (u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE), + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "pci memory space", + (u32)(PNX8550_PCIMEM), + (u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1), + IORESOURCE_MEM +}; + +extern struct pci_ops pnx8550_pci_ops; + +static struct pci_controller pnx8550_controller = { + .pci_ops = &pnx8550_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ +static inline unsigned long get_system_mem_size(void) +{ + /* Read IP2031_RANK0_ADDR_LO */ + unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); + /* Read IP2031_RANK1_ADDR_HI */ + unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); + + return dram_r1_hi - dram_r0_lo + 1; +} + +static int __init pnx8550_pci_setup(void) +{ + int pci_mem_code; + int mem_size = get_system_mem_size() >> 20; + + /* Clear the Global 2 Register, PCI Inta Output Enable Registers + Bit 1:Enable DAC Powerdown + -> 0:DACs are enabled and are working normally + 1:DACs are powerdown + Bit 0:Enable of PCI inta output + -> 0 = Disable PCI inta output + 1 = Enable PCI inta output + */ + PNX8550_GLB2_ENAB_INTA_O = 0; + + /* Calc the PCI mem size code */ + if (mem_size >= 128) + pci_mem_code = SIZE_128M; + else if (mem_size >= 64) + pci_mem_code = SIZE_64M; + else if (mem_size >= 32) + pci_mem_code = SIZE_32M; + else + pci_mem_code = SIZE_16M; + + /* Set PCI_XIO registers */ + outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO); + outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI); + outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO); + outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI); + + /* Send memory transaction via PCI_BASE2 */ + outl(0x00000001, PCI_BASE | PCI_IO); + + /* Unlock the setup register */ + outl(0xca, PCI_BASE | PCI_UNLOCKREG); + + /* + * BAR0 of PNX8550 (pci base 10) must be zero in order for ide + * to work, and in order for bus_to_baddr to work without any + * hacks. + */ + outl(0x00000000, PCI_BASE | PCI_BASE10); + + /* + *These two bars are set by default or the boot code. + * However, it's safer to set them here so we're not boot + * code dependent. + */ + outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */ + outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */ + + outl(PCI_EN_TA | + PCI_EN_PCI2MMI | + PCI_EN_XIO | + PCI_SETUP_BASE18_SIZE(SIZE_32M) | + PCI_SETUP_BASE18_EN | + PCI_SETUP_BASE14_EN | + PCI_SETUP_BASE10_PREF | + PCI_SETUP_BASE10_SIZE(pci_mem_code) | + PCI_SETUP_CFGMANAGE_EN | + PCI_SETUP_PCIARB_EN, + PCI_BASE | + PCI_SETUP); /* PCI_SETUP */ + outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */ + + register_pci_controller(&pnx8550_controller); + + return 0; +} + +arch_initcall(pnx8550_pci_setup); diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c new file mode 100644 index 000000000000..8aa9bd65b45e --- /dev/null +++ b/arch/mips/philips/pnx8550/common/platform.c @@ -0,0 +1,135 @@ +/* + * Platform device support for Philips PNX8550 SoCs + * + * Copyright 2005, Embedded Alley Solutions, Inc + * + * Based on arch/mips/au1000/common/platform.c + * Platform device support for Au1x00 SoCs. + * + * Copyright 2004, Matt Porter + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern struct uart_ops ip3106_pops; + +static struct resource pnx8550_usb_ohci_resources[] = { + [0] = { + .start = PNX8550_USB_OHCI_OP_BASE, + .end = PNX8550_USB_OHCI_OP_BASE + + PNX8550_USB_OHCI_OP_LEN, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8550_INT_USB, + .end = PNX8550_INT_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource pnx8550_uart_resources[] = { + [0] = { + .start = PNX8550_UART_PORT0, + .end = PNX8550_UART_PORT0 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8550_UART_INT(0), + .end = PNX8550_UART_INT(0), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = PNX8550_UART_PORT1, + .end = PNX8550_UART_PORT1 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = PNX8550_UART_INT(1), + .end = PNX8550_UART_INT(1), + .flags = IORESOURCE_IRQ, + }, +}; + +struct ip3106_port ip3106_ports[] = { + [0] = { + .port = { + .type = PORT_IP3106, + .iotype = SERIAL_IO_MEM, + .membase = (void __iomem *)PNX8550_UART_PORT0, + .mapbase = PNX8550_UART_PORT0, + .irq = PNX8550_UART_INT(0), + .uartclk = 3692300, + .fifosize = 16, + .ops = &ip3106_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + }, + [1] = { + .port = { + .type = PORT_IP3106, + .iotype = SERIAL_IO_MEM, + .membase = (void __iomem *)PNX8550_UART_PORT1, + .mapbase = PNX8550_UART_PORT1, + .irq = PNX8550_UART_INT(1), + .uartclk = 3692300, + .fifosize = 16, + .ops = &ip3106_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static u64 uart_dmamask = ~(u32)0; + +static struct platform_device pnx8550_usb_ohci_device = { + .name = "pnx8550-ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), + .resource = pnx8550_usb_ohci_resources, +}; + +static struct platform_device pnx8550_uart_device = { + .name = "ip3106-uart", + .id = -1, + .dev = { + .dma_mask = &uart_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ip3106_ports, + }, + .num_resources = ARRAY_SIZE(pnx8550_uart_resources), + .resource = pnx8550_uart_resources, +}; + +static struct platform_device *pnx8550_platform_devices[] __initdata = { + &pnx8550_usb_ohci_device, + &pnx8550_uart_device, +}; + +int pnx8550_platform_init(void) +{ + return platform_add_devices(pnx8550_platform_devices, + ARRAY_SIZE(pnx8550_platform_devices)); +} + +arch_initcall(pnx8550_platform_init); diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c new file mode 100644 index 000000000000..72a016767e09 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/proc.c @@ -0,0 +1,113 @@ +/* + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data) +{ + int len = 0; + int configPR = read_c0_config7(); + + if (offset==0) { + len += sprintf(&page[len],"Timer: count, compare, tc, status\n"); + len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n", + read_c0_count(), read_c0_compare(), + (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on"); + len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n", + read_c0_count2(), read_c0_compare2(), + (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on"); + len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n", + read_c0_count3(), read_c0_compare3(), + (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on"); + } + + return len; +} + +static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data) +{ + int len = 0; + + if (offset==0) { + len += sprintf(&page[len],"config1: %#10.8x\n",read_c0_config1()); + len += sprintf(&page[len],"config2: %#10.8x\n",read_c0_config2()); + len += sprintf(&page[len],"config3: %#10.8x\n",read_c0_config3()); + len += sprintf(&page[len],"configPR: %#10.8x\n",read_c0_config7()); + len += sprintf(&page[len],"status: %#10.8x\n",read_c0_status()); + len += sprintf(&page[len],"cause: %#10.8x\n",read_c0_cause()); + len += sprintf(&page[len],"count: %#10.8x\n",read_c0_count()); + len += sprintf(&page[len],"count_2: %#10.8x\n",read_c0_count2()); + len += sprintf(&page[len],"count_3: %#10.8x\n",read_c0_count3()); + len += sprintf(&page[len],"compare: %#10.8x\n",read_c0_compare()); + len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2()); + len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3()); + } + + return len; +} + +static struct proc_dir_entry* pnx8550_dir = NULL; +static struct proc_dir_entry* pnx8550_timers = NULL; +static struct proc_dir_entry* pnx8550_registers = NULL; + +static int pnx8550_proc_init( void ) +{ + + // Create /proc/pnx8550 + pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL); + if (pnx8550_dir){ + pnx8550_dir->nlink = 1; + } + else { + printk(KERN_ERR "Can't create pnx8550 proc dir\n"); + return -1; + } + + // Create /proc/pnx8550/timers + pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir ); + if (pnx8550_timers){ + pnx8550_timers->nlink = 1; + pnx8550_timers->read_proc = pnx8550_timers_read; + } + else { + printk(KERN_ERR "Can't create pnx8550 timers proc file\n"); + } + + // Create /proc/pnx8550/registers + pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir ); + if (pnx8550_registers){ + pnx8550_registers->nlink = 1; + pnx8550_registers->read_proc = pnx8550_registers_read; + } + else { + printk(KERN_ERR "Can't create pnx8550 registers proc file\n"); + } + + return 0; +} + +__initcall(pnx8550_proc_init); diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c new file mode 100644 index 000000000000..70aac9759412 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/prom.c @@ -0,0 +1,138 @@ +/* + * + * Per Hallsmark, per.hallsmark@mvista.com + * + * Based on jmr3927/common/prom.c + * + * 2004 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +typedef struct +{ + char *name; +/* char *val; */ +}t_env_var; + + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + * Environment variables are stored in the form of "memsize=64". + */ + + t_env_var *env = (t_env_var *)prom_envp; + int i; + + i = strlen(envname); + + while(env->name) { + if(strncmp(envname, env->name, i) == 0) { + return(env->name + strlen(envname) + 1); + } + env++; + } + return(NULL); +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + return 0; +} + +unsigned long __init prom_free_prom_memory(void) +{ + return 0; +} + +extern int pnx8550_console_port; + +/* used by prom_printf */ +void prom_putchar(char c) +{ + if (pnx8550_console_port != -1) { + /* Wait until FIFO not full */ + while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16) + ; + /* Send one char */ + ip3106_fifo(UART_BASE, pnx8550_console_port) = c; + } +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c new file mode 100644 index 000000000000..7b2cbc5b2c7c --- /dev/null +++ b/arch/mips/philips/pnx8550/common/reset.c @@ -0,0 +1,49 @@ +/*. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Reset the PNX8550 board. + * + */ +#include +#include +#include + +void pnx8550_machine_restart(char *command) +{ + char head[] = "************* Machine restart *************"; + char foot[] = "*******************************************"; + + printk("\n\n"); + printk("%s\n", head); + if (command != NULL) + printk("* %s\n", command); + printk("%s\n", foot); + + PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; +} + +void pnx8550_machine_halt(void) +{ + printk("*** Machine halt. (Not implemented) ***\n"); +} + +void pnx8550_machine_power_off(void) +{ + printk("*** Machine power off. (Not implemented) ***\n"); +} diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c new file mode 100644 index 000000000000..ee6bf72094f6 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/setup.c @@ -0,0 +1,149 @@ +/* + * + * 2.6 port, Embedded Alley Solutions, Inc + * + * Based on Per Hallsmark, per.hallsmark@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern void prom_printf(char *fmt, ...); + +extern void __init board_setup(void); +extern void pnx8550_machine_restart(char *); +extern void pnx8550_machine_halt(void); +extern void pnx8550_machine_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +extern void (*board_time_init)(void); +extern void pnx8550_time_init(void); +extern void (*board_timer_setup)(struct irqaction *irq); +extern void pnx8550_timer_setup(struct irqaction *irq); +extern void rs_kgdb_hook(int tty_no); +extern void prom_printf(char *fmt, ...); +extern char *prom_getcmdline(void); + +struct resource standard_io_resources[] = { + {"dma1", 0x00, 0x1f, IORESOURCE_BUSY}, + {"timer", 0x40, 0x5f, IORESOURCE_BUSY}, + {"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, + {"dma2", 0xc0, 0xdf, IORESOURCE_BUSY}, +}; + +#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ +unsigned long get_system_mem_size(void) +{ + /* Read IP2031_RANK0_ADDR_LO */ + unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); + /* Read IP2031_RANK1_ADDR_HI */ + unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); + + return dram_r1_hi - dram_r0_lo + 1; +} + +int pnx8550_console_port = -1; + +void __init plat_setup(void) +{ + int i; + char* argptr; + + board_setup(); /* board specific setup */ + + _machine_restart = pnx8550_machine_restart; + _machine_halt = pnx8550_machine_halt; + _machine_power_off = pnx8550_machine_power_off; + + board_time_init = pnx8550_time_init; + board_timer_setup = pnx8550_timer_setup; + + /* Clear the Global 2 Register, PCI Inta Output Enable Registers + Bit 1:Enable DAC Powerdown + -> 0:DACs are enabled and are working normally + 1:DACs are powerdown + Bit 0:Enable of PCI inta output + -> 0 = Disable PCI inta output + 1 = Enable PCI inta output + */ + PNX8550_GLB2_ENAB_INTA_O = 0; + + /* IO/MEM resources. */ + set_io_port_base(KSEG1); + ioport_resource.start = 0; + ioport_resource.end = ~0; + iomem_resource.start = 0; + iomem_resource.end = ~0; + + /* Request I/O space for devices on this board */ + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, standard_io_resources + i); + + /* Place the Mode Control bit for GPIO pin 16 in primary function */ + /* Pin 16 is used by UART1, UA1_TX */ + outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) | + (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT), + PNX8550_GPIO_MC1); + + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "console=ttyS")) != NULL) { + argptr += strlen("console=ttyS"); + pnx8550_console_port = *argptr == '0' ? 0 : 1; + + /* We must initialize the UART (console) before prom_printf */ + /* Set LCR to 8-bit and BAUD to 38400 (no 5) */ + ip3106_lcr(UART_BASE, pnx8550_console_port) = + IP3106_UART_LCR_8BIT; + ip3106_baud(UART_BASE, pnx8550_console_port) = 5; + } + +#ifdef CONFIG_KGDB + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { + int line; + argptr += strlen("kgdb=ttyS"); + line = *argptr == '0' ? 0 : 1; + rs_kgdb_hook(line); + prom_printf("KGDB: Using ttyS%i for session, " + "please connect your debugger\n", line ? 1 : 0); + } +#endif + return; +} diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c new file mode 100644 index 000000000000..70664ea96b92 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/time.c @@ -0,0 +1,105 @@ +/* + * Copyright 2001, 2002, 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Common time service routines for MIPS machines. See + * Documents/MIPS/README.txt. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +extern unsigned int mips_hpt_frequency; + +/* + * pnx8550_time_init() - it does the following things: + * + * 1) board_time_init() - + * a) (optional) set up RTC routines, + * b) (optional) calibrate and set the mips_hpt_frequency + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) + */ + +void pnx8550_time_init(void) +{ + unsigned int n; + unsigned int m; + unsigned int p; + unsigned int pow2p; + + /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */ + /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */ + + n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16; + m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8; + p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2; + pow2p = (1 << p); + + db_assert(m != 0 && pow2p != 0); + + /* + * Compute the frequency as in the PNX8550 User Manual 1.0, p.186 + * (a.k.a. 8-10). Divide by HZ for a timer offset that results in + * HZ timer interrupts per second. + */ + mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p)); +} + +/* + * pnx8550_timer_setup() - it does the following things: + * + * 5) board_timer_setup() - + * a) (optional) over-write any choices made above by time_init(). + * b) machine specific code should setup the timer irqaction. + * c) enable the timer interrupt + */ + +void __init pnx8550_timer_setup(struct irqaction *irq) +{ + int configPR; + + setup_irq(PNX8550_INT_TIMER1, irq); + + /* Start timer1 */ + configPR = read_c0_config7(); + configPR &= ~0x00000008; + write_c0_config7(configPR); + + /* Timer 2 stop */ + configPR = read_c0_config7(); + configPR |= 0x00000010; + write_c0_config7(configPR); + + write_c0_count2(0); + write_c0_compare2(0xffffffff); + + /* Timer 3 stop */ + configPR = read_c0_config7(); + configPR |= 0x00000020; + write_c0_config7(configPR); +} diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile new file mode 100644 index 000000000000..e8228dbca8f6 --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/Makefile @@ -0,0 +1,4 @@ + +# Makefile for the Philips JBS Board. + +lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c new file mode 100644 index 000000000000..f92826e0096d --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/board_setup.c @@ -0,0 +1,65 @@ +/* + * JBS Specific board startup routines. + * + * Copyright 2005, Embedded Alley Solutions, Inc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void __init board_setup(void) +{ + unsigned long config0, configpr; + + config0 = read_c0_config(); + + /* clear all three cache coherency fields */ + config0 &= ~(0x7 | (7<<25) | (7<<28)); + config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) | + (CONF_CM_DEFAULT<<28)); + write_c0_config(config0); + BARRIER; + + configpr = read_c0_config7(); + configpr |= (1<<19); /* enable tlb */ + write_c0_config7(configpr); + BARRIER; +} diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c new file mode 100644 index 000000000000..85f449174bc3 --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/init.c @@ -0,0 +1,57 @@ +/* + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddedalley.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Philips PNX8550/JBS"; +} + +void __init prom_init(void) +{ + + unsigned long memsize; + + mips_machgroup = MACH_GROUP_PHILIPS; + mips_machtype = MACH_PHILIPS_JBS; + + //memsize = 0x02800000; /* Trimedia uses memory above */ + memsize = 0x08000000; /* Trimedia uses memory above */ + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c new file mode 100644 index 000000000000..f78e0423dc98 --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/irqmap.c @@ -0,0 +1,36 @@ +/* + * Philips JBS board irqmap. + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddealley.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +char irq_tab_jbs[][5] __initdata = { + [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, +}; + diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index e5c03c525bda..3870a76efc3b 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -137,6 +137,7 @@ #define MACH_GROUP_PHILIPS 14 #define MACH_PHILIPS_NINO 0 /* Nino */ #define MACH_PHILIPS_VELO 1 /* Velo */ +#define MACH_PHILIPS_JBS 2 /* JBS */ /* * Valid machtype for group Globespan diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 3bbb6431d218..ed92c0b14410 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -52,6 +52,7 @@ #define PRID_IMP_VR41XX 0x0c00 #define PRID_IMP_R12000 0x0e00 #define PRID_IMP_R8000 0x1000 +#define PRID_IMP_PR4450 0x1200 #define PRID_IMP_R4600 0x2000 #define PRID_IMP_R4700 0x2100 #define PRID_IMP_TX39 0x2200 @@ -187,7 +188,8 @@ #define CPU_24K 58 #define CPU_AU1200 59 #define CPU_34K 60 -#define CPU_LAST 60 +#define CPU_PR4450 61 +#define CPU_LAST 61 /* * ISA Level encodings diff --git a/include/asm-mips/mach-pnx8550/cm.h b/include/asm-mips/mach-pnx8550/cm.h new file mode 100644 index 000000000000..bb0a56c7d011 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/cm.h @@ -0,0 +1,43 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Clock module specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_CM_H +#define __PNX8550_CM_H + +#define PNX8550_CM_BASE 0xBBE47000 + +#define PNX8550_CM_PLL0_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000) +#define PNX8550_CM_PLL1_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004) +#define PNX8550_CM_PLL2_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008) +#define PNX8550_CM_PLL3_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C) + +// Table not complete..... + +#define PNX8550_CM_PLL_BLOCKED_MASK 0x80000000 +#define PNX8550_CM_PLL_LOCK_MASK 0x40000000 +#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000 +#define PNX8550_CM_PLL_N_MASK 0x01ff0000 +#define PNX8550_CM_PLL_M_MASK 0x00003f00 +#define PNX8550_CM_PLL_P_MASK 0x0000000c +#define PNX8550_CM_PLL_PD_MASK 0x00000002 + + +#endif diff --git a/include/asm-mips/mach-pnx8550/glb.h b/include/asm-mips/mach-pnx8550/glb.h new file mode 100644 index 000000000000..07aa85e609bc --- /dev/null +++ b/include/asm-mips/mach-pnx8550/glb.h @@ -0,0 +1,86 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PNX8550 global definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_GLB_H +#define __PNX8550_GLB_H + +#define PNX8550_GLB1_BASE 0xBBE63000 +#define PNX8550_GLB2_BASE 0xBBE4d000 +#define PNX8550_RESET_BASE 0xBBE60000 + +/* PCI Inta Output Enable Registers */ +#define PNX8550_GLB2_ENAB_INTA_O *(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050) + +/* Bit 1:Enable DAC Powerdown + 0:DACs are enabled and are working normally + 1:DACs are powerdown +*/ +#define PNX8550_GLB_DAC_PD 0x2 +/* Bit 0:Enable of PCI inta output + 0 = Disable PCI inta output + 1 = Enable PCI inta output +*/ +#define PNX8550_GLB_ENABLE_INTA_O 0x1 + +/* PCI Direct Mappings */ +#define PNX8550_PCIMEM 0x12000000 +#define PNX8550_PCIMEM_SIZE 0x08000000 +#define PNX8550_PCIIO 0x1c000000 +#define PNX8550_PCIIO_SIZE 0x02000000 /* 32M */ + +#define PNX8550_PORT_BASE KSEG1 + +// GPIO def +#define PNX8550_GPIO_BASE 0x1Be00000 + +#define PNX8550_GPIO_DIRQ0 (PNX8550_GPIO_BASE + 0x104500) +#define PNX8550_GPIO_MC1 (PNX8550_GPIO_BASE + 0x104004) +#define PNX8550_GPIO_MC_31_BIT 30 +#define PNX8550_GPIO_MC_30_BIT 28 +#define PNX8550_GPIO_MC_29_BIT 26 +#define PNX8550_GPIO_MC_28_BIT 24 +#define PNX8550_GPIO_MC_27_BIT 22 +#define PNX8550_GPIO_MC_26_BIT 20 +#define PNX8550_GPIO_MC_25_BIT 18 +#define PNX8550_GPIO_MC_24_BIT 16 +#define PNX8550_GPIO_MC_23_BIT 14 +#define PNX8550_GPIO_MC_22_BIT 12 +#define PNX8550_GPIO_MC_21_BIT 10 +#define PNX8550_GPIO_MC_20_BIT 8 +#define PNX8550_GPIO_MC_19_BIT 6 +#define PNX8550_GPIO_MC_18_BIT 4 +#define PNX8550_GPIO_MC_17_BIT 2 +#define PNX8550_GPIO_MC_16_BIT 0 + +#define PNX8550_GPIO_MODE_PRIMOP 0x1 +#define PNX8550_GPIO_MODE_NO_OPENDR 0x2 +#define PNX8550_GPIO_MODE_OPENDR 0x3 + +// RESET module +#define PNX8550_RST_CTL *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0) +#define PNX8550_RST_CAUSE *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4) +#define PNX8550_RST_EN_WATCHDOG *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8) + +#define PNX8550_RST_REL_MIPS_RST_N 0x8 +#define PNX8550_RST_DO_SW_RST 0x4 +#define PNX8550_RST_REL_SYS_RST_OUT 0x2 +#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1 +#endif diff --git a/include/asm-mips/mach-pnx8550/int.h b/include/asm-mips/mach-pnx8550/int.h new file mode 100644 index 000000000000..0e0668b524f4 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/int.h @@ -0,0 +1,140 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Interrupt specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_INT_H +#define __PNX8550_INT_H + +#define PNX8550_GIC_BASE 0xBBE3E000 + +#define PNX8550_GIC_PRIMASK_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000) +#define PNX8550_GIC_PRIMASK_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004) +#define PNX8550_GIC_VECTOR_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100) +#define PNX8550_GIC_VECTOR_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104) +#define PNX8550_GIC_PEND_1_31 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200) +#define PNX8550_GIC_PEND_32_63 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204) +#define PNX8550_GIC_PEND_64_70 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208) +#define PNX8550_GIC_FEATURES *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300) +#define PNX8550_GIC_REQ(x) *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4) +#define PNX8550_GIC_MOD_ID *(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC) + +// cp0 is two software + six hw exceptions +#define PNX8550_INT_CP0_TOTINT 8 +#define PNX8550_INT_CP0_MIN 0 +#define PNX8550_INT_CP0_MAX (PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1) + +#define MIPS_CPU_GIC_IRQ 2 +#define MIPS_CPU_TIMER_IRQ 7 + +// GIC are 71 exceptions connected to cp0's first hardware exception +#define PNX8550_INT_GIC_TOTINT 71 +#define PNX8550_INT_GIC_MIN (PNX8550_INT_CP0_MAX+1) +#define PNX8550_INT_GIC_MAX (PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1) + +#define PNX8550_INT_UNDEF (PNX8550_INT_GIC_MIN+0) +#define PNX8550_INT_IPC_TARGET0_MIPS (PNX8550_INT_GIC_MIN+1) +#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2) +#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3) +#define PNX8550_INT_RESERVED_4 (PNX8550_INT_GIC_MIN+4) +#define PNX8550_INT_USB (PNX8550_INT_GIC_MIN+5) +#define PNX8550_INT_GPIO_EQ1 (PNX8550_INT_GIC_MIN+6) +#define PNX8550_INT_GPIO_EQ2 (PNX8550_INT_GIC_MIN+7) +#define PNX8550_INT_GPIO_EQ3 (PNX8550_INT_GIC_MIN+8) +#define PNX8550_INT_GPIO_EQ4 (PNX8550_INT_GIC_MIN+9) + +#define PNX8550_INT_GPIO_EQ5 (PNX8550_INT_GIC_MIN+10) +#define PNX8550_INT_GPIO_EQ6 (PNX8550_INT_GIC_MIN+11) +#define PNX8550_INT_RESERVED_12 (PNX8550_INT_GIC_MIN+12) +#define PNX8550_INT_QVCP1 (PNX8550_INT_GIC_MIN+13) +#define PNX8550_INT_QVCP2 (PNX8550_INT_GIC_MIN+14) +#define PNX8550_INT_I2C1 (PNX8550_INT_GIC_MIN+15) +#define PNX8550_INT_I2C2 (PNX8550_INT_GIC_MIN+16) +#define PNX8550_INT_ISO_UART1 (PNX8550_INT_GIC_MIN+17) +#define PNX8550_INT_ISO_UART2 (PNX8550_INT_GIC_MIN+18) +#define PNX8550_INT_UART1 (PNX8550_INT_GIC_MIN+19) + +#define PNX8550_INT_UART2 (PNX8550_INT_GIC_MIN+20) +#define PNX8550_INT_QNTR (PNX8550_INT_GIC_MIN+21) +#define PNX8550_INT_RESERVED22 (PNX8550_INT_GIC_MIN+22) +#define PNX8550_INT_T_DSC (PNX8550_INT_GIC_MIN+23) +#define PNX8550_INT_M_DSC (PNX8550_INT_GIC_MIN+24) +#define PNX8550_INT_RESERVED25 (PNX8550_INT_GIC_MIN+25) +#define PNX8550_INT_2D_DRAW_ENG (PNX8550_INT_GIC_MIN+26) +#define PNX8550_INT_MEM_BASED_SCALAR1 (PNX8550_INT_GIC_MIN+27) +#define PNX8550_INT_VIDEO_MPEG (PNX8550_INT_GIC_MIN+28) +#define PNX8550_INT_VIDEO_INPUT_P1 (PNX8550_INT_GIC_MIN+29) + +#define PNX8550_INT_VIDEO_INPUT_P2 (PNX8550_INT_GIC_MIN+30) +#define PNX8550_INT_SPDI1 (PNX8550_INT_GIC_MIN+31) +#define PNX8550_INT_SPDO (PNX8550_INT_GIC_MIN+32) +#define PNX8550_INT_AUDIO_INPUT1 (PNX8550_INT_GIC_MIN+33) +#define PNX8550_INT_AUDIO_OUTPUT1 (PNX8550_INT_GIC_MIN+34) +#define PNX8550_INT_AUDIO_INPUT2 (PNX8550_INT_GIC_MIN+35) +#define PNX8550_INT_AUDIO_OUTPUT2 (PNX8550_INT_GIC_MIN+36) +#define PNX8550_INT_MEMBASED_SCALAR2 (PNX8550_INT_GIC_MIN+37) +#define PNX8550_INT_VPK (PNX8550_INT_GIC_MIN+38) +#define PNX8550_INT_MPEG1_MIPS (PNX8550_INT_GIC_MIN+39) + +#define PNX8550_INT_MPEG1_TM (PNX8550_INT_GIC_MIN+40) +#define PNX8550_INT_MPEG2_MIPS (PNX8550_INT_GIC_MIN+41) +#define PNX8550_INT_MPEG2_TM (PNX8550_INT_GIC_MIN+42) +#define PNX8550_INT_TS_DMA (PNX8550_INT_GIC_MIN+43) +#define PNX8550_INT_EDMA (PNX8550_INT_GIC_MIN+44) +#define PNX8550_INT_TM_DEBUG1 (PNX8550_INT_GIC_MIN+45) +#define PNX8550_INT_TM_DEBUG2 (PNX8550_INT_GIC_MIN+46) +#define PNX8550_INT_PCI_INTA (PNX8550_INT_GIC_MIN+47) +#define PNX8550_INT_CLOCK_MODULE (PNX8550_INT_GIC_MIN+48) +#define PNX8550_INT_PCI_XIO_INTA_PCI (PNX8550_INT_GIC_MIN+49) + +#define PNX8550_INT_PCI_XIO_INTB_DMA (PNX8550_INT_GIC_MIN+50) +#define PNX8550_INT_PCI_XIO_INTC_GPPM (PNX8550_INT_GIC_MIN+51) +#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52) +#define PNX8550_INT_DVD_CSS (PNX8550_INT_GIC_MIN+53) +#define PNX8550_INT_VLD (PNX8550_INT_GIC_MIN+54) +#define PNX8550_INT_GPIO_TSU_7_0 (PNX8550_INT_GIC_MIN+55) +#define PNX8550_INT_GPIO_TSU_15_8 (PNX8550_INT_GIC_MIN+56) +#define PNX8550_INT_GPIO_CTU_IR (PNX8550_INT_GIC_MIN+57) +#define PNX8550_INT_GPIO0 (PNX8550_INT_GIC_MIN+58) +#define PNX8550_INT_GPIO1 (PNX8550_INT_GIC_MIN+59) + +#define PNX8550_INT_GPIO2 (PNX8550_INT_GIC_MIN+60) +#define PNX8550_INT_GPIO3 (PNX8550_INT_GIC_MIN+61) +#define PNX8550_INT_GPIO4 (PNX8550_INT_GIC_MIN+62) +#define PNX8550_INT_GPIO5 (PNX8550_INT_GIC_MIN+63) +#define PNX8550_INT_GPIO6 (PNX8550_INT_GIC_MIN+64) +#define PNX8550_INT_GPIO7 (PNX8550_INT_GIC_MIN+65) +#define PNX8550_INT_PMAN_SECURITY (PNX8550_INT_GIC_MIN+66) +#define PNX8550_INT_I2C3 (PNX8550_INT_GIC_MIN+67) +#define PNX8550_INT_RESERVED_68 (PNX8550_INT_GIC_MIN+68) +#define PNX8550_INT_SPDI2 (PNX8550_INT_GIC_MIN+69) + +#define PNX8550_INT_I2C4 (PNX8550_INT_GIC_MIN+70) + +// Timer are 3 exceptions connected to cp0's 7th hardware exception +#define PNX8550_INT_TIMER_TOTINT 3 +#define PNX8550_INT_TIMER_MIN (PNX8550_INT_GIC_MAX+1) +#define PNX8550_INT_TIMER_MAX (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1) + +#define PNX8550_INT_TIMER1 (PNX8550_INT_TIMER_MIN+0) +#define PNX8550_INT_TIMER2 (PNX8550_INT_TIMER_MIN+1) +#define PNX8550_INT_TIMER3 (PNX8550_INT_TIMER_MIN+2) +#define PNX8550_INT_WATCHDOG PNX8550_INT_TIMER3 + +#endif diff --git a/include/asm-mips/mach-pnx8550/kernel-entry-init.h b/include/asm-mips/mach-pnx8550/kernel-entry-init.h new file mode 100644 index 000000000000..57102fa9da51 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/kernel-entry-init.h @@ -0,0 +1,262 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2005 Embedded Alley Solutions, Inc + */ +#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H +#define __ASM_MACH_KERNEL_ENTRY_INIT_H + +#include +#include + +#define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */ +#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; +#define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */ +#define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */ +#define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */ + +#define ICACHE_SET_COUNT 256 /* Instruction cache set count */ +#define DCACHE_SET_COUNT 128 /* Data cache set count */ + +#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE) +#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE) + + .macro kernel_entry_setup + .set push + .set noreorder + /* + * PNX8550 entry point, when running a non compressed + * kernel. When loading a zImage, the head.S code in + * arch/mips/zboot/pnx8550 will init the caches and, + * decompress the kernel, and branch to kernel_entry. + */ +cache_begin: li t0, (1<<28) + mtc0 t0, CP0_STATUS /* cp0 usable */ + HAZARD_CP0 + + mtc0 zero, CP0_CAUSE + HAZARD_CP0 + + + /* Set static virtual to phys address translation and TLB disabled */ + mfc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + and t0,~((1<<19) | (1<<20)) /* TLB/MAP cleared */ + mtc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */ + + init_icache + nop + init_dcache + nop + + cachePr4450ICReset + nop + + cachePr4450DCReset + nop + + /* read ConfigPR into t0 */ + mfc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + /* enable the TLB */ + or t0, (1<<19) + + /* disable the ICACHE: at least 10x slower */ + /* or t0, (1<<26) */ + + /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */ + /* or t0, (1<<27) */ + + and t0, CO_CONFIGPR_VALID + + /* enable TLB. */ + mtc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 +cache_end: + /* Setup CMEM_0 to MMIO address space, 2MB */ + lui t0, 0x1BE0 + addi t0, t0, 0x3 + mtc0 $8, $22, 4 + nop + + /* Setup CMEM_1, 128MB */ + lui t0, 0x1000 + addi t0, t0, 0xf + mtc0 $8, $22, 5 + nop + + + /* Setup CMEM_2, 32MB */ + lui t0, 0x1C00 + addi t0, t0, 0xb + mtc0 $8, $22, 6 + nop + + /* Setup CMEM_3, 0MB */ + lui t0, 0x0 + addi t0, t0, 0x0 + mtc0 $8, $22, 7 + nop + + /* Enable cache */ + mfc0 t0, CP0_CONFIG + HAZARD_CP0 + and t0, t0, 0xFFFFFFF8 + or t0, t0, 3 + mtc0 t0, CP0_CONFIG + HAZARD_CP0 + .set pop + .endm + + .macro init_icache + .set push + .set noreorder + + /* Get Cache Configuration */ + mfc0 t3, CP0_CONFIG, 1 + HAZARD_CP0 + + /* get cache Line size */ + + srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */ + andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */ + beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */ + nop + addiu t0, t1, 1 + ori t1, zero, 1 + sllv t1, t1, t0 + + /* get max cache Index */ + srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */ + andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */ + addiu t0, t2, 6 + ori t2, zero, 1 + sllv t2, t2, t0 + + /* get max cache way */ + srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */ + andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */ + addiu t3, t3, 1 + + /* total no of cache lines */ + multu t2, t3 /* max index * max way */ + mflo t2 + addiu t2, t2, -1 + + move t0, zero +pr4450_next_instruction_cache_set: + cache Index_Invalidate_I, 0(t0) + addu t0, t0, t1 /* add bytes in a line */ + bne t2, zero, pr4450_next_instruction_cache_set + addiu t2, t2, -1 /* reduce no of lines to invalidate by one */ +pr4450_instr_cache_invalidated: + .set pop + .endm + + .macro init_dcache + .set push + .set noreorder + move t1, zero + + /* Store Tag Information */ + mtc0 zero, CP0_TAGLO, 0 + HAZARD_CP0 + + mtc0 zero, CP0_TAGHI, 0 + HAZARD_CP0 + + /* Cache size is 16384 = 512 lines x 32 bytes per line */ + or t2, zero, (128*4)-1 /* 512 lines */ + /* Invalidate all lines */ +2: + cache Index_Store_Tag_D, 0(t1) + addiu t2, t2, -1 + bne t2, zero, 2b + addiu t1, t1, 32 /* 32 bytes in a line */ + .set pop + .endm + + .macro cachePr4450ICReset + .set push + .set noreorder + + /* Save CP0 status reg on entry; */ + /* disable interrupts during cache reset */ + mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */ + HAZARD_CP0 + + mtc0 zero, CP0_STATUS /* disable CPU interrupts */ + HAZARD_CP0 + + or t1, zero, zero /* T1 = starting cache index (0) */ + ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */ + + icache_invd_loop: + /* 9 == register t1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \ + (0 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY0 */ + .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \ + (1 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY1 */ + + addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */ + bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */ + addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */ + + /* Initialize the latches in the instruction cache tag */ + /* that drive the way selection tri-state bus drivers, by doing a */ + /* dummy load while the instruction cache is still disabled. */ + /* TODO: Is this needed ? */ + la t1, KSEG0 /* T1 = cached memory base address */ + lw zero, 0x0000(t1) /* (dummy read of first memory word) */ + + mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ + HAZARD_CP0 + .set pop + .endm + + .macro cachePr4450DCReset + .set push + .set noreorder + mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */ + HAZARD_CP0 + mtc0 zero, CP0_STATUS /* disable CPU interrupts */ + HAZARD_CP0 + + /* Writeback/invalidate entire data cache sets/ways/lines */ + or t1, zero, zero /* T1 = starting cache index (0) */ + ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */ + + dcache_wbinvd_loop: + /* 9 == register t1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (0 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY0 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (1 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (2 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY2 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (3 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY3 */ + + addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */ + bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */ + addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */ + + /* Initialize the latches in the data cache tag that drive the way + selection tri-state bus drivers, by doing a dummy load while the + data cache is still in the disabled mode. TODO: Is this needed ? */ + la t1, KSEG0 /* T1 = cached memory base address */ + lw zero, 0x0000(t1) /* (dummy read of first memory word) */ + + mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ + HAZARD_CP0 + .set pop + .endm + +#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */ diff --git a/include/asm-mips/mach-pnx8550/nand.h b/include/asm-mips/mach-pnx8550/nand.h new file mode 100644 index 000000000000..aefbc514ab09 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/nand.h @@ -0,0 +1,121 @@ +#ifndef __PNX8550_NAND_H +#define __PNX8550_NAND_H + +#define PNX8550_NAND_BASE_ADDR 0x10000000 +#define PNX8550_PCIXIO_BASE 0xBBE40000 + +#define PNX8550_DMA_EXT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800) +#define PNX8550_DMA_INT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804) +#define PNX8550_DMA_TRANS_SIZE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808) +#define PNX8550_DMA_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c) +#define PNX8550_XIO_SEL0 *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814) +#define PNX8550_GPXIO_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820) +#define PNX8550_GPXIO_WR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824) +#define PNX8550_GPXIO_RD *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828) +#define PNX8550_GPXIO_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C) +#define PNX8550_XIO_FLASH_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830) +#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0) +#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4) +#define PNX8550_GPXIO_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8) +#define PNX8550_DMA_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0) +#define PNX8550_DMA_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4) +#define PNX8550_DMA_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8) + +#define PNX8550_XIO_SEL0_EN_16BIT 0x00800000 +#define PNX8550_XIO_SEL0_USE_ACK 0x00400000 +#define PNX8550_XIO_SEL0_REN_HIGH 0x00100000 +#define PNX8550_XIO_SEL0_REN_LOW 0x00040000 +#define PNX8550_XIO_SEL0_WEN_HIGH 0x00010000 +#define PNX8550_XIO_SEL0_WEN_LOW 0x00004000 +#define PNX8550_XIO_SEL0_WAIT 0x00000200 +#define PNX8550_XIO_SEL0_OFFSET 0x00000020 +#define PNX8550_XIO_SEL0_TYPE_68360 0x00000000 +#define PNX8550_XIO_SEL0_TYPE_NOR 0x00000008 +#define PNX8550_XIO_SEL0_TYPE_NAND 0x00000010 +#define PNX8550_XIO_SEL0_TYPE_IDE 0x00000018 +#define PNX8550_XIO_SEL0_SIZE_8MB 0x00000000 +#define PNX8550_XIO_SEL0_SIZE_16MB 0x00000002 +#define PNX8550_XIO_SEL0_SIZE_32MB 0x00000004 +#define PNX8550_XIO_SEL0_SIZE_64MB 0x00000006 +#define PNX8550_XIO_SEL0_ENAB 0x00000001 + +#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT) | \ + (PNX8550_XIO_SEL0_REN_HIGH*0)| \ + (PNX8550_XIO_SEL0_REN_LOW*2) | \ + (PNX8550_XIO_SEL0_WEN_HIGH*0)| \ + (PNX8550_XIO_SEL0_WEN_LOW*2) | \ + (PNX8550_XIO_SEL0_WAIT*4) | \ + (PNX8550_XIO_SEL0_OFFSET*0) | \ + (PNX8550_XIO_SEL0_TYPE_NAND) | \ + (PNX8550_XIO_SEL0_SIZE_32MB) | \ + (PNX8550_XIO_SEL0_ENAB)) + +#define PNX8550_GPXIO_PENDING 0x00000200 +#define PNX8550_GPXIO_DONE 0x00000100 +#define PNX8550_GPXIO_CLR_DONE 0x00000080 +#define PNX8550_GPXIO_INIT 0x00000040 +#define PNX8550_GPXIO_READ_CMD 0x00000010 +#define PNX8550_GPXIO_BEN 0x0000000F + +#define PNX8550_XIO_FLASH_64MB 0x00200000 +#define PNX8550_XIO_FLASH_INC_DATA 0x00100000 +#define PNX8550_XIO_FLASH_CMD_PH 0x000C0000 +#define PNX8550_XIO_FLASH_CMD_PH2 0x00080000 +#define PNX8550_XIO_FLASH_CMD_PH1 0x00040000 +#define PNX8550_XIO_FLASH_CMD_PH0 0x00000000 +#define PNX8550_XIO_FLASH_ADR_PH 0x00030000 +#define PNX8550_XIO_FLASH_ADR_PH3 0x00030000 +#define PNX8550_XIO_FLASH_ADR_PH2 0x00020000 +#define PNX8550_XIO_FLASH_ADR_PH1 0x00010000 +#define PNX8550_XIO_FLASH_ADR_PH0 0x00000000 +#define PNX8550_XIO_FLASH_CMD_B(x) ((x<<8) & 0x0000FF00) +#define PNX8550_XIO_FLASH_CMD_A(x) (x & 0x000000FF) + +#define PNX8550_XIO_INT_ACK 0x00004000 +#define PNX8550_XIO_INT_COMPL 0x00002000 +#define PNX8550_XIO_INT_NONSUP 0x00000200 +#define PNX8550_XIO_INT_ABORT 0x00000004 + +#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400 +#define PNX8550_DMA_CTRL_SND2XIO 0x00000200 +#define PNX8550_DMA_CTRL_FIX_ADDR 0x00000100 +#define PNX8550_DMA_CTRL_BURST_8 0x00000000 +#define PNX8550_DMA_CTRL_BURST_16 0x00000020 +#define PNX8550_DMA_CTRL_BURST_32 0x00000040 +#define PNX8550_DMA_CTRL_BURST_64 0x00000060 +#define PNX8550_DMA_CTRL_BURST_128 0x00000080 +#define PNX8550_DMA_CTRL_BURST_256 0x000000A0 +#define PNX8550_DMA_CTRL_BURST_512 0x000000C0 +#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0 +#define PNX8550_DMA_CTRL_INIT_DMA 0x00000010 +#define PNX8550_DMA_CTRL_CMD_TYPE 0x0000000F + +/* see PCI system arch, page 100 for the full list: */ +#define PNX8550_DMA_CTRL_PCI_CMD_READ 0x00000006 +#define PNX8550_DMA_CTRL_PCI_CMD_WRITE 0x00000007 + +#define PNX8550_DMA_INT_STAT_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_STAT_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_STAT_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_STAT_PERR5 (1<<5) +#define PNX8550_DMA_INT_STAT_PERR4 (1<<4) +#define PNX8550_DMA_INT_STAT_M_ABORT (1<<2) +#define PNX8550_DMA_INT_STAT_T_ABORT (1<<1) + +#define PNX8550_DMA_INT_EN_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_EN_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_EN_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_EN_PERR5 (1<<5) +#define PNX8550_DMA_INT_EN_PERR4 (1<<4) +#define PNX8550_DMA_INT_EN_M_ABORT (1<<2) +#define PNX8550_DMA_INT_EN_T_ABORT (1<<1) + +#define PNX8550_DMA_INT_CLR_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_CLR_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_CLR_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_CLR_PERR5 (1<<5) +#define PNX8550_DMA_INT_CLR_PERR4 (1<<4) +#define PNX8550_DMA_INT_CLR_M_ABORT (1<<2) +#define PNX8550_DMA_INT_CLR_T_ABORT (1<<1) + +#endif diff --git a/include/asm-mips/mach-pnx8550/pci.h b/include/asm-mips/mach-pnx8550/pci.h new file mode 100644 index 000000000000..b921508d701b --- /dev/null +++ b/include/asm-mips/mach-pnx8550/pci.h @@ -0,0 +1,185 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PCI specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_PCI_H +#define __PNX8550_PCI_H + +#include +#include +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define PCI_CMD_IOR 0x20 +#define PCI_CMD_IOW 0x30 +#define PCI_CMD_CONFIG_READ 0xa0 +#define PCI_CMD_CONFIG_WRITE 0xb0 + +#define PCI_IO_TIMEOUT 1000 +#define PCI_IO_RETRY 5 +/* Timeout for IO and CFG accesses. + This is in 1/1024 th of a jiffie(=10ms) + i.e. approx 10us */ +#define PCI_IO_JIFFIES_TIMEOUT 40 +#define PCI_IO_JIFFIES_SHIFT 10 + +#define PCI_BYTE_ENABLE_MASK 0x0000000f +#define PCI_CFG_BUS_SHIFT 16 +#define PCI_CFG_FUNC_SHIFT 8 +#define PCI_CFG_REG_SHIFT 2 + +#define PCI_BASE 0x1be00000 +#define PCI_SETUP 0x00040010 +#define PCI_DIS_REQGNT (1<<30) +#define PCI_DIS_REQGNTA (1<<29) +#define PCI_DIS_REQGNTB (1<<28) +#define PCI_D2_SUPPORT (1<<27) +#define PCI_D1_SUPPORT (1<<26) +#define PCI_EN_TA (1<<24) +#define PCI_EN_PCI2MMI (1<<23) +#define PCI_EN_XIO (1<<22) +#define PCI_BASE18_PREF (1<<21) +#define SIZE_16M 0x3 +#define SIZE_32M 0x4 +#define SIZE_64M 0x5 +#define SIZE_128M 0x6 +#define PCI_SETUP_BASE18_SIZE(X) (X<<18) +#define PCI_SETUP_BASE18_EN (1<<17) +#define PCI_SETUP_BASE14_PREF (1<<16) +#define PCI_SETUP_BASE14_SIZE(X) (X<<12) +#define PCI_SETUP_BASE14_EN (1<<11) +#define PCI_SETUP_BASE10_PREF (1<<10) +#define PCI_SETUP_BASE10_SIZE(X) (X<<7) +#define PCI_SETUP_CFGMANAGE_EN (1<<1) +#define PCI_SETUP_PCIARB_EN (1<<0) + +#define PCI_CTRL 0x040014 +#define PCI_SWPB_DCS_PCI (1<<16) +#define PCI_SWPB_PCI_PCI (1<<15) +#define PCI_SWPB_PCI_DCS (1<<14) +#define PCI_REG_WR_POST (1<<13) +#define PCI_XIO_WR_POST (1<<12) +#define PCI_PCI2_WR_POST (1<<13) +#define PCI_PCI1_WR_POST (1<<12) +#define PCI_SERR_SEEN (1<<11) +#define PCI_B10_SPEC_RD (1<<6) +#define PCI_B14_SPEC_RD (1<<5) +#define PCI_B18_SPEC_RD (1<<4) +#define PCI_B10_NOSUBWORD (1<<3) +#define PCI_B14_NOSUBWORD (1<<2) +#define PCI_B18_NOSUBWORD (1<<1) +#define PCI_RETRY_TMREN (1<<0) + +#define PCI_BASE1_LO 0x040018 +#define PCI_BASE1_HI 0x04001C +#define PCI_BASE2_LO 0x040020 +#define PCI_BASE2_HI 0x040024 +#define PCI_RDLIFETIM 0x040028 +#define PCI_GPPM_ADDR 0x04002C +#define PCI_GPPM_WDAT 0x040030 +#define PCI_GPPM_RDAT 0x040034 +#define PCI_GPPM_CTRL 0x040038 +#define GPPM_DONE (1<<10) +#define INIT_PCI_CYCLE (1<<9) +#define GPPM_CMD(X) (((X)&0xf)<<4) +#define GPPM_BYTEEN(X) ((X)&0xf) +#define PCI_UNLOCKREG 0x04003C +#define UNLOCK_SSID(X) (((X)&0xff)<<8) +#define UNLOCK_SETUP(X) (((X)&0xff)<<0) +#define UNLOCK_MAGIC 0xCA +#define PCI_DEV_VEND_ID 0x040040 +#define DEVICE_ID(X) (((X)>>16)&0xffff) +#define VENDOR_ID(X) (((X)&0xffff)) +#define PCI_CFG_CMDSTAT 0x040044 +#define PCI_CFG_STATUS(X) (((X)>>16)&0xffff) +#define PCI_CFG_COMMAND(X) ((X)&0xffff) +#define PCI_CLASS_REV 0x040048 +#define PCI_CLASSCODE(X) (((X)>>8)&0xffffff) +#define PCI_REVID(X) ((X)&0xff) +#define PCI_LAT_TMR 0x04004c +#define PCI_BASE10 0x040050 +#define PCI_BASE14 0x040054 +#define PCI_BASE18 0x040058 +#define PCI_SUBSYS_ID 0x04006c +#define PCI_CAP_PTR 0x040074 +#define PCI_CFG_MISC 0x04007c +#define PCI_PMC 0x040080 +#define PCI_PWR_STATE 0x040084 +#define PCI_IO 0x040088 +#define PCI_SLVTUNING 0x04008C +#define PCI_DMATUNING 0x040090 +#define PCI_DMAEADDR 0x040800 +#define PCI_DMAIADDR 0x040804 +#define PCI_DMALEN 0x040808 +#define PCI_DMACTRL 0x04080C +#define PCI_XIOCTRL 0x040810 +#define PCI_SEL0PROF 0x040814 +#define PCI_SEL1PROF 0x040818 +#define PCI_SEL2PROF 0x04081C +#define PCI_GPXIOADDR 0x040820 +#define PCI_NANDCTRLS 0x400830 +#define PCI_SEL3PROF 0x040834 +#define PCI_SEL4PROF 0x040838 +#define PCI_GPXIO_STAT 0x040FB0 +#define PCI_GPXIO_IMASK 0x040FB4 +#define PCI_GPXIO_ICLR 0x040FB8 +#define PCI_GPXIO_ISET 0x040FBC +#define PCI_GPPM_STATUS 0x040FC0 +#define GPPM_DONE (1<<10) +#define GPPM_ERR (1<<9) +#define GPPM_MPAR_ERR (1<<8) +#define GPPM_PAR_ERR (1<<7) +#define GPPM_R_MABORT (1<<2) +#define GPPM_R_TABORT (1<<1) +#define PCI_GPPM_IMASK 0x040FC4 +#define PCI_GPPM_ICLR 0x040FC8 +#define PCI_GPPM_ISET 0x040FCC +#define PCI_DMA_STATUS 0x040FD0 +#define PCI_DMA_IMASK 0x040FD4 +#define PCI_DMA_ICLR 0x040FD8 +#define PCI_DMA_ISET 0x040FDC +#define PCI_ISTATUS 0x040FE0 +#define PCI_IMASK 0x040FE4 +#define PCI_ICLR 0x040FE8 +#define PCI_ISET 0x040FEC +#define PCI_MOD_ID 0x040FFC + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +/* + * Ethernet device DP83816 definition + */ +#define DP83816_IRQ_ETHER 66 + +#endif diff --git a/include/asm-mips/mach-pnx8550/uart.h b/include/asm-mips/mach-pnx8550/uart.h new file mode 100644 index 000000000000..e32b9a23d70e --- /dev/null +++ b/include/asm-mips/mach-pnx8550/uart.h @@ -0,0 +1,16 @@ +#ifndef __IP3106_UART_H +#define __IP3106_UART_H + +#include + +/* early macros for kgdb use. fixme: clean this up */ + +#define UART_BASE 0xbbe4a000 /* PNX8550 */ + +#define PNX8550_UART_PORT0 (UART_BASE) +#define PNX8550_UART_PORT1 (UART_BASE + 0x1000) + +#define PNX8550_UART_INT(x) (PNX8550_INT_GIC_MIN+19+x) +#define IRQ_TO_UART(x) (x-PNX8550_INT_GIC_MIN-19) + +#endif diff --git a/include/asm-mips/mach-pnx8550/usb.h b/include/asm-mips/mach-pnx8550/usb.h new file mode 100644 index 000000000000..483b7fc65d41 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/usb.h @@ -0,0 +1,32 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * USB specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_USB_H +#define __PNX8550_USB_H + +/* + * USB Host controller + */ + +#define PNX8550_USB_OHCI_OP_BASE 0x1be48000 +#define PNX8550_USB_OHCI_OP_LEN 0x1000 + +#endif diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index a7a43ff8c5cf..08aa231b4dea 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -841,12 +841,24 @@ do { \ #define read_c0_count() __read_32bit_c0_register($9, 0) #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) +#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ +#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) + +#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ +#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) + #define read_c0_entryhi() __read_ulong_c0_register($10, 0) #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) #define read_c0_compare() __read_32bit_c0_register($11, 0) #define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) +#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ +#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) + +#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ +#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) + #define read_c0_status() __read_32bit_c0_register($12, 0) #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 27db8da43aa4..2b0401b93f2b 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -39,7 +39,8 @@ #define PORT_RSA 13 #define PORT_NS16550A 14 #define PORT_XSCALE 15 -#define PORT_MAX_8250 15 /* max port ID */ +#define PORT_IP3106 16 +#define PORT_MAX_8250 16 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed diff --git a/include/linux/serial_ip3106.h b/include/linux/serial_ip3106.h new file mode 100644 index 000000000000..f500ac602c5c --- /dev/null +++ b/include/linux/serial_ip3106.h @@ -0,0 +1,81 @@ +/* + * Embedded Alley Solutions, source@embeddedalley.com. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_SERIAL_IP3106_H +#define _LINUX_SERIAL_IP3106_H + +#include +#include + +#define IP3106_NR_PORTS 2 + +struct ip3106_port { + struct uart_port port; + struct timer_list timer; + unsigned int old_status; +}; + +/* register offsets */ +#define IP3106_LCR 0 +#define IP3106_MCR 0x004 +#define IP3106_BAUD 0x008 +#define IP3106_CFG 0x00c +#define IP3106_FIFO 0x028 +#define IP3106_ISTAT 0xfe0 +#define IP3106_IEN 0xfe4 +#define IP3106_ICLR 0xfe8 +#define IP3106_ISET 0xfec +#define IP3106_PD 0xff4 +#define IP3106_MID 0xffc + +#define IP3106_UART_LCR_TXBREAK (1<<30) +#define IP3106_UART_LCR_PAREVN 0x10000000 +#define IP3106_UART_LCR_PAREN 0x08000000 +#define IP3106_UART_LCR_2STOPB 0x04000000 +#define IP3106_UART_LCR_8BIT 0x01000000 +#define IP3106_UART_LCR_TX_RST 0x00040000 +#define IP3106_UART_LCR_RX_RST 0x00020000 +#define IP3106_UART_LCR_RX_NEXT 0x00010000 + +#define IP3106_UART_MCR_SCR 0xFF000000 +#define IP3106_UART_MCR_DCD 0x00800000 +#define IP3106_UART_MCR_CTS 0x00100000 +#define IP3106_UART_MCR_LOOP 0x00000010 +#define IP3106_UART_MCR_RTS 0x00000002 +#define IP3106_UART_MCR_DTR 0x00000001 + +#define IP3106_UART_INT_TX 0x00000080 +#define IP3106_UART_INT_EMPTY 0x00000040 +#define IP3106_UART_INT_RCVTO 0x00000020 +#define IP3106_UART_INT_RX 0x00000010 +#define IP3106_UART_INT_RXOVRN 0x00000008 +#define IP3106_UART_INT_FRERR 0x00000004 +#define IP3106_UART_INT_BREAK 0x00000002 +#define IP3106_UART_INT_PARITY 0x00000001 +#define IP3106_UART_INT_ALLRX 0x0000003F +#define IP3106_UART_INT_ALLTX 0x000000C0 + +#define IP3106_UART_FIFO_TXFIFO 0x001F0000 +#define IP3106_UART_FIFO_TXFIFO_STA (0x1f<<16) +#define IP3106_UART_FIFO_RXBRK 0x00008000 +#define IP3106_UART_FIFO_RXFE 0x00004000 +#define IP3106_UART_FIFO_RXPAR 0x00002000 +#define IP3106_UART_FIFO_RXFIFO 0x00001F00 +#define IP3106_UART_FIFO_RBRTHR 0x000000FF + +#endif -- cgit v1.2.3 From 26a940e21752e0de8f068f77dad606a7d1986937 Mon Sep 17 00:00:00 2001 From: Pete Popov Date: Thu, 15 Sep 2005 08:03:12 +0000 Subject: Cleaned up AMD Au1200 IDE driver: - converted to platform bus - removed pci dependencies - removed virt_to_phys/phys_to_virt calls System now can root off of a disk. Signed-off-by: Ralf Baechle diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README new file mode 100644 --- Documentation/mips/AU1xxx_IDE.README | 168 ++++ arch/mips/Kconfig | 2 +- arch/mips/au1000/common/dbdma.c | 6 + arch/mips/au1000/common/platform.c | 32 +- arch/mips/au1000/pb1200/irqmap.c | 6 +- drivers/ide/Kconfig | 31 +- drivers/ide/ide-proc.c | 1 + drivers/ide/mips/au1xxx-ide.c | 1250 +++++++++++++++++++++++++++ include/asm-mips/mach-au1x00/au1xxx.h | 44 + include/asm-mips/mach-au1x00/au1xxx_dbdma.h | 4 + include/asm-mips/mach-au1x00/au1xxx_ide.h | 301 +++++++ include/linux/ide.h | 2 +- 12 files changed, 1840 insertions(+), 7 deletions(-) create mode 100644 Documentation/mips/AU1xxx_IDE.README create mode 100644 drivers/ide/mips/au1xxx-ide.c create mode 100644 include/asm-mips/mach-au1x00/au1xxx.h create mode 100644 include/asm-mips/mach-au1x00/au1xxx_ide.h (limited to 'include/linux') diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README new file mode 100644 index 000000000000..a7e4c4ea3560 --- /dev/null +++ b/Documentation/mips/AU1xxx_IDE.README @@ -0,0 +1,168 @@ +README for MIPS AU1XXX IDE driver - Released 2005-07-15 + +ABOUT +----- +This file describes the 'drivers/ide/mips/au1xxx-ide.c', related files and the +services they provide. + +If you are short in patience and just want to know how to add your hard disc to +the white or black list, go to the 'ADD NEW HARD DISC TO WHITE OR BLACK LIST' +section. + + +LICENSE +------- + +Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +675 Mass Ave, Cambridge, MA 02139, USA. + +Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE + Interface and Linux Device Driver" Application Note. + + +FILES, CONFIGS AND COMPATABILITY +-------------------------------- + +Two files are introduced: + + a) 'include/asm-mips/mach-au1x00/au1xxx_ide.h' + containes : struct _auide_hwif + struct drive_list_entry dma_white_list + struct drive_list_entry dma_black_list + timing parameters for PIO mode 0/1/2/3/4 + timing parameters for MWDMA 0/1/2 + + b) 'drivers/ide/mips/au1xxx-ide.c' + contains the functionality of the AU1XXX IDE driver + +Four configs variables are introduced: + + CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode + CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode + CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA + controler + CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size + per descriptor + +If MWDMA is enabled and the connected hard disc is not on the white list, the +kernel switches to a "safe mwdma mode" at boot time. In this mode the IDE +performance is substantial slower then in full speed mwdma. In this case +please add your hard disc to the white list (follow instruction from 'ADD NEW +HARD DISC TO WHITE OR BLACK LIST' section). + + +SUPPORTED IDE MODES +------------------- + +The AU1XXX IDE driver supported all PIO modes - PIO mode 0/1/2/3/4 - and all +MWDMA modes - MWDMA 0/1/2 -. There is no support for SWDMA and UDMA mode. + +To change the PIO mode use the program hdparm with option -p, e.g. +'hdparm -p0 [device]' for PIO mode 0. To enable the MWDMA mode use the option +-X, e.g. 'hdparm -X32 [device]' for MWDMA mode 0. + + +PERFORMANCE CONFIGURATIONS +-------------------------- + +If the used system doesn't need USB support enable the following kernel configs: + +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDE_AU1XXX=y +CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y +CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y +CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDEDMA_AUTO=y + +If the used system need the USB support enable the following kernel configs for +high IDE to USB throughput. + +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDE_AU1XXX=y +CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y +CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDEDMA_AUTO=y + + +ADD NEW HARD DISC TO WHITE OR BLACK LIST +---------------------------------------- + +Step 1 : detect the model name of your hard disc + + a) connect your hard disc to the AU1XXX + + b) boot your kernel and get the hard disc model. + + Example boot log: + + --snipped-- + Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2 + ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx + Au1xxx IDE(builtin) configured for MWDMA2 + Probing IDE interface ide0... + hda: Maxtor 6E040L0, ATA DISK drive + ide0 at 0xac800000-0xac800007,0xac8001c0 on irq 64 + hda: max request size: 64KiB + hda: 80293248 sectors (41110 MB) w/2048KiB Cache, CHS=65535/16/63, (U)DMA + --snipped-- + + In this example 'Maxtor 6E040L0'. + +Step 2 : edit 'include/asm-mips/mach-au1x00/au1xxx_ide.h' + + Add your hard disc to the dma_white_list or dma_black_list structur. + +Step 3 : Recompile the kernel + + Enable MWDMA support in the kernel configuration. Recompile the kernel and + reboot. + +Step 4 : Tests + + If you have add a hard disc to the white list, please run some stress tests + for verification. + + +ACKNOWLEDGMENTS +--------------- + +These drivers wouldn't have been done without the base of kernel 2.4.x AU1XXX +IDE driver from AMD. + +Additional input also from: +Matthias Lenk + +Happy hacking! +Enrico Walther diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8746e1b1621b..dc5c629af106 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -799,7 +799,7 @@ config MIPS_BOSPORUS config MIPS_DB1200 bool "AMD Alchemy DB1200 board" select SOC_AU1200 - select DMA_NONCOHERENT + select DMA_COHERENT select MIPS_DISABLE_OBSOLETE_IDE select SYS_SUPPORTS_LITTLE_ENDIAN diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index 8f78c2fe7cf5..eb5803aed91b 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c @@ -197,6 +197,12 @@ find_dbdev_id (u32 id) return NULL; } +void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp) +{ + return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +} +EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt); + u32 au1xxx_ddma_add_device(dbdev_tab_t *dev) { diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 0c3fd726c3d6..4aca18f0e290 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -12,7 +12,7 @@ #include #include -#include +#include /* OHCI (USB full speed host controller) */ static struct resource au1xxx_usb_ohci_resources[] = { @@ -154,7 +154,6 @@ static struct platform_device au1xxx_usb_otg_device = { .resource = au1xxx_usb_otg_resources, }; -/*** AU1200 LCD controller ***/ static struct resource au1200_lcd_resources[] = { [0] = { .start = LCD_PHYS_ADDR, @@ -168,6 +167,19 @@ static struct resource au1200_lcd_resources[] = { } }; +static struct resource au1200_ide0_resources[] = { + [0] = { + .start = AU1XXX_ATA_PHYS_ADDR, + .end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AU1XXX_ATA_INT, + .end = AU1XXX_ATA_INT, + .flags = IORESOURCE_IRQ, + } +}; + static u64 au1200_lcd_dmamask = ~(u32)0; static struct platform_device au1200_lcd_device = { @@ -180,6 +192,21 @@ static struct platform_device au1200_lcd_device = { .num_resources = ARRAY_SIZE(au1200_lcd_resources), .resource = au1200_lcd_resources, }; + + +static u64 ide0_dmamask = ~(u32)0; + +static struct platform_device au1200_ide0_device = { + .name = "au1200-ide", + .id = 0, + .dev = { + .dma_mask = &ide0_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(au1200_ide0_resources), + .resource = au1200_ide0_resources, +}; + #endif static struct platform_device *au1xxx_platform_devices[] __initdata = { @@ -194,6 +221,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { &au1xxx_usb_gdt_device, &au1xxx_usb_otg_device, &au1200_lcd_device, + &au1200_ide0_device, #endif }; diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index 2ec64e78aa01..59e70e5cf325 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c @@ -22,6 +22,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include @@ -65,7 +66,7 @@ int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); */ static volatile int pb1200_cascade_en=0; -void pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs) { unsigned short bisr = bcsr->int_status; int extirq_nr = 0; @@ -78,6 +79,7 @@ void pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs) /* Ack and dispatch IRQ */ do_IRQ(extirq_nr,regs); } + return IRQ_RETVAL(1); } inline void pb1200_enable_irq(unsigned int irq_nr) @@ -97,7 +99,7 @@ static unsigned int pb1200_startup_irq( unsigned int irq_nr ) if (++pb1200_cascade_en == 1) { request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, - 0, "Pb1200 Cascade", &pb1200_cascade_handler ); + 0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler ); #ifdef CONFIG_MIPS_PB1200 /* We have a problem with CPLD rev3. Enable a workaround */ if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1cadd2c3cadd..a737886e39d1 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -778,6 +778,35 @@ config BLK_DEV_IDE_PMAC_BLINK This option enables the use of the sleep LED as a hard drive activity LED. +config BLK_DEV_IDE_AU1XXX + bool "IDE for AMD Alchemy Au1200" + depends on SOC_AU1200 +choice + prompt "IDE Mode for AMD Alchemy Au1200" + default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA + depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX + +config BLK_DEV_IDE_AU1XXX_PIO_DBDMA + bool "PIO+DbDMA IDE for AMD Alchemy Au1200" + +config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200" + depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX +endchoice + +config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON + bool "Enable burstable Mode on DbDMA" + default false + depends BLK_DEV_IDE_AU1XXX + help + This option enable the burstable Flag on DbDMA controller + (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY"). + +config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ + int "Maximum transfer size (KB) per request (up to 128)" + default "128" + depends BLK_DEV_IDE_AU1XXX + config IDE_ARM def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) @@ -1013,7 +1042,7 @@ config BLK_DEV_UMC8672 endif config BLK_DEV_IDEDMA - def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS + def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA config IDEDMA_IVB bool "IGNORE word93 Validation BITS" diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4063d2c34e3d..84665e2ba3c8 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -64,6 +64,7 @@ static int proc_ide_read_imodel case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; + case ide_au1xxx: name = "au1xxx"; break; default: name = "(unknown)"; break; } len = sprintf(page, "%s\n", name); diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c new file mode 100644 index 000000000000..2b6327c576b9 --- /dev/null +++ b/drivers/ide/mips/au1xxx-ide.c @@ -0,0 +1,1250 @@ +/* + * linux/drivers/ide/mips/au1xxx-ide.c version 01.30.00 Aug. 02 2005 + * + * BRIEF MODULE DESCRIPTION + * AMD Alchemy Au1xxx IDE interface routines over the Static Bus + * + * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE + * Interface and Linux Device Driver" Application Note. + */ +#undef REALLY_SLOW_IO /* most systems can safely undef this */ + +#include /* for CONFIG_BLK_DEV_IDEPCI */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#if CONFIG_PM +#include +#endif + +#include + +#define DRV_NAME "au1200-ide" +#define DRV_VERSION "1.0" +#define DRV_AUTHOR "AMD PCS / Pete Popov " +#define DRV_DESC "Au1200 IDE" + +static _auide_hwif auide_hwif; +static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED; +static int dbdma_init_done = 0; + +/* + * local I/O functions + */ +u8 auide_inb(unsigned long port) +{ + return (au_readb(port)); +} + +u16 auide_inw(unsigned long port) +{ + return (au_readw(port)); +} + +u32 auide_inl(unsigned long port) +{ + return (au_readl(port)); +} + +void auide_insw(unsigned long port, void *addr, u32 count) +{ +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) + + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + + if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1, + DDMA_FLAGS_NOIE)) { + printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); + return; + } + ctp = *((chan_tab_t **)ahwif->rx_chan); + dp = ctp->cur_ptr; + while (dp->dscr_cmd0 & DSCR_CMD0_V) + ; + ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); +#else + while (count--) + { + *(u16 *)addr = au_readw(port); + addr +=2 ; + } +#endif +} + +void auide_insl(unsigned long port, void *addr, u32 count) +{ + while (count--) + { + *(u32 *)addr = au_readl(port); + /* NOTE: For IDE interfaces over PCMCIA, + * 32-bit access does not work + */ + addr += 4; + } +} + +void auide_outb(u8 addr, unsigned long port) +{ + return (au_writeb(addr, port)); +} + +void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port) +{ + return (au_writeb(addr, port)); +} + +void auide_outw(u16 addr, unsigned long port) +{ + return (au_writew(addr, port)); +} + +void auide_outl(u32 addr, unsigned long port) +{ + return (au_writel(addr, port)); +} + +void auide_outsw(unsigned long port, void *addr, u32 count) +{ +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + + if(!put_source_flags(ahwif->tx_chan, (void*)addr, + count << 1, DDMA_FLAGS_NOIE)) { + printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); + return; + } + ctp = *((chan_tab_t **)ahwif->tx_chan); + dp = ctp->cur_ptr; + while (dp->dscr_cmd0 & DSCR_CMD0_V) + ; + ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); +#else + while (count--) + { + au_writew(*(u16 *)addr, port); + addr += 2; + } +#endif +} + +void auide_outsl(unsigned long port, void *addr, u32 count) +{ + while (count--) + { + au_writel(*(u32 *)addr, port); + /* NOTE: For IDE interfaces over PCMCIA, + * 32-bit access does not work + */ + addr += 4; + } +} + +static void auide_tune_drive(ide_drive_t *drive, byte pio) +{ + int mem_sttime; + int mem_stcfg; + unsigned long flags; + u8 speed; + + /* get the best pio mode for the drive */ + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + + printk("%s: setting Au1XXX IDE to PIO mode%d\n", + drive->name, pio); + + spin_lock_irqsave(&ide_tune_drive_spin_lock, flags); + + mem_sttime = 0; + mem_stcfg = au_readl(MEM_STCFG2); + + /* set pio mode! */ + switch(pio) { + case 0: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_PIO0_TWCS + | SBC_IDE_PIO0_TCSH + | SBC_IDE_PIO0_TCSOFF + | SBC_IDE_PIO0_TWP + | SBC_IDE_PIO0_TCSW + | SBC_IDE_PIO0_TPM + | SBC_IDE_PIO0_TA; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS; + + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); + break; + + case 1: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_PIO1_TWCS + | SBC_IDE_PIO1_TCSH + | SBC_IDE_PIO1_TCSOFF + | SBC_IDE_PIO1_TWP + | SBC_IDE_PIO1_TCSW + | SBC_IDE_PIO1_TPM + | SBC_IDE_PIO1_TA; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS; + break; + + case 2: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_PIO2_TWCS + | SBC_IDE_PIO2_TCSH + | SBC_IDE_PIO2_TCSOFF + | SBC_IDE_PIO2_TWP + | SBC_IDE_PIO2_TCSW + | SBC_IDE_PIO2_TPM + | SBC_IDE_PIO2_TA; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS; + break; + + case 3: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_PIO3_TWCS + | SBC_IDE_PIO3_TCSH + | SBC_IDE_PIO3_TCSOFF + | SBC_IDE_PIO3_TWP + | SBC_IDE_PIO3_TCSW + | SBC_IDE_PIO3_TPM + | SBC_IDE_PIO3_TA; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS; + + break; + + case 4: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_PIO4_TWCS + | SBC_IDE_PIO4_TCSH + | SBC_IDE_PIO4_TCSOFF + | SBC_IDE_PIO4_TWP + | SBC_IDE_PIO4_TCSW + | SBC_IDE_PIO4_TPM + | SBC_IDE_PIO4_TA; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS; + break; + } + + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); + + spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags); + + speed = pio + XFER_PIO_0; + ide_config_drive_speed(drive, speed); +} + +static int auide_tune_chipset (ide_drive_t *drive, u8 speed) +{ + u8 mode = 0; + int mem_sttime; + int mem_stcfg; + unsigned long flags; +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + struct hd_driveid *id = drive->id; + + /* + * Now see what the current drive is capable of, + * selecting UDMA only if the mate said it was ok. + */ + if (id && (id->capability & 1) && drive->autodma && + !__ide_dma_bad_drive(drive)) { + if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { + if (id->dma_mword & 4) + mode = XFER_MW_DMA_2; + else if (id->dma_mword & 2) + mode = XFER_MW_DMA_1; + else if (id->dma_mword & 1) + mode = XFER_MW_DMA_0; + } + } +#endif + + spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags); + + mem_sttime = 0; + mem_stcfg = au_readl(MEM_STCFG2); + + switch(speed) { + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + auide_tune_drive(drive, (speed - XFER_PIO_0)); + break; +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + case XFER_MW_DMA_2: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_MDMA2_TWCS + | SBC_IDE_MDMA2_TCSH + | SBC_IDE_MDMA2_TCSOFF + | SBC_IDE_MDMA2_TWP + | SBC_IDE_MDMA2_TCSW + | SBC_IDE_MDMA2_TPM + | SBC_IDE_MDMA2_TA; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS; + + mode = XFER_MW_DMA_2; + break; + case XFER_MW_DMA_1: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_MDMA1_TWCS + | SBC_IDE_MDMA1_TCSH + | SBC_IDE_MDMA1_TCSOFF + | SBC_IDE_MDMA1_TWP + | SBC_IDE_MDMA1_TCSW + | SBC_IDE_MDMA1_TPM + | SBC_IDE_MDMA1_TA; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS; + + mode = XFER_MW_DMA_1; + break; + case XFER_MW_DMA_0: + /* set timing parameters for RCS2# */ + mem_sttime = SBC_IDE_MDMA0_TWCS + | SBC_IDE_MDMA0_TCSH + | SBC_IDE_MDMA0_TCSOFF + | SBC_IDE_MDMA0_TWP + | SBC_IDE_MDMA0_TCSW + | SBC_IDE_MDMA0_TPM + | SBC_IDE_MDMA0_TA; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS; + + mode = XFER_MW_DMA_0; + break; +#endif + default: + return 1; + } + + /* + * Tell the drive to switch to the new mode; abort on failure. + */ + if (!mode || ide_config_drive_speed(drive, mode)) + { + return 1; /* failure */ + } + + + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); + + spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags); + + return 0; +} + +/* + * Multi-Word DMA + DbDMA functions + */ +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + +static int in_drive_list(struct hd_driveid *id, + const struct drive_list_entry *drive_table) +{ + for ( ; drive_table->id_model ; drive_table++){ + if ((!strcmp(drive_table->id_model, id->model)) && + ((strstr(drive_table->id_firmware, id->fw_rev)) || + (!strcmp(drive_table->id_firmware, "ALL"))) + ) + return 1; + } + return 0; +} + +static int auide_build_sglist(ide_drive_t *drive, struct request *rq) +{ + ide_hwif_t *hwif = drive->hwif; + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + struct scatterlist *sg = hwif->sg_table; + + ide_map_sg(drive, rq); + + if (rq_data_dir(rq) == READ) + hwif->sg_dma_direction = DMA_FROM_DEVICE; + else + hwif->sg_dma_direction = DMA_TO_DEVICE; + + return dma_map_sg(ahwif->dev, sg, hwif->sg_nents, + hwif->sg_dma_direction); +} + +static int auide_build_dmatable(ide_drive_t *drive) +{ + int i, iswrite, count = 0; + ide_hwif_t *hwif = HWIF(drive); + + struct request *rq = HWGROUP(drive)->rq; + + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + struct scatterlist *sg; + + iswrite = (rq_data_dir(rq) == WRITE); + /* Save for interrupt context */ + ahwif->drive = drive; + + /* Build sglist */ + hwif->sg_nents = i = auide_build_sglist(drive, rq); + + if (!i) + return 0; + + /* fill the descriptors */ + sg = hwif->sg_table; + while (i && sg_dma_len(sg)) { + u32 cur_addr; + u32 cur_len; + + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + while (cur_len) { + u32 flags = DDMA_FLAGS_NOIE; + unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; + + if (++count >= PRD_ENTRIES) { + printk(KERN_WARNING "%s: DMA table too small\n", + drive->name); + goto use_pio_instead; + } + + /* Lets enable intr for the last descriptor only */ + if (1==i) + flags = DDMA_FLAGS_IE; + else + flags = DDMA_FLAGS_NOIE; + + if (iswrite) { + if(!put_source_flags(ahwif->tx_chan, + (void*)(page_address(sg->page) + + sg->offset), + tc, flags)) { + printk(KERN_ERR "%s failed %d\n", + __FUNCTION__, __LINE__); + } + } else + { + if(!put_dest_flags(ahwif->rx_chan, + (void*)(page_address(sg->page) + + sg->offset), + tc, flags)) { + printk(KERN_ERR "%s failed %d\n", + __FUNCTION__, __LINE__); + } + } + + cur_addr += tc; + cur_len -= tc; + } + sg++; + i--; + } + + if (count) + return 1; + +use_pio_instead: + dma_unmap_sg(ahwif->dev, + hwif->sg_table, + hwif->sg_nents, + hwif->sg_dma_direction); + + return 0; /* revert to PIO for this request */ +} + +static int auide_dma_end(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + + if (hwif->sg_nents) { + dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents, + hwif->sg_dma_direction); + hwif->sg_nents = 0; + } + + return 0; +} + +static void auide_dma_start(ide_drive_t *drive ) +{ +// printk("%s\n", __FUNCTION__); +} + +ide_startstop_t auide_dma_intr(ide_drive_t *drive) +{ + //printk("%s\n", __FUNCTION__); + + u8 stat = 0, dma_stat = 0; + + dma_stat = HWIF(drive)->ide_dma_end(drive); + stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */ + if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { + if (!dma_stat) { + struct request *rq = HWGROUP(drive)->rq; + + ide_end_request(drive, 1, rq->nr_sectors); + return ide_stopped; + } + printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", + drive->name, dma_stat); + } + return ide_error(drive, "dma_intr", stat); +} + +static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + //printk("%s\n", __FUNCTION__); + + /* issue cmd to drive */ + ide_execute_command(drive, command, &auide_dma_intr, + (2*WAIT_CMD), NULL); +} + +static int auide_dma_setup(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + + if (drive->media != ide_disk) + return 1; + + if (!auide_build_dmatable(drive)) + /* try PIO instead of DMA */ + return 1; + + drive->waiting_for_dma = 1; + + return 0; +} + +static int auide_dma_check(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + if( !dbdma_init_done ){ + auide_hwif.white_list = in_drive_list(drive->id, + dma_white_list); + auide_hwif.black_list = in_drive_list(drive->id, + dma_black_list); + auide_hwif.drive = drive; + auide_ddma_init(&auide_hwif); + dbdma_init_done = 1; + } +#endif + + /* Is the drive in our DMA black list? */ + if ( auide_hwif.black_list ) { + drive->using_dma = 0; + printk("%s found in dma_blacklist[]! Disabling DMA.\n", + drive->id->model); + } + else + drive->using_dma = 1; + + return HWIF(drive)->ide_dma_host_on(drive); +} + +static int auide_dma_test_irq(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: ide_dma_test_irq \ + called while not waiting\n", drive->name); + + /* If dbdma didn't execute the STOP command yet, the + * active bit is still set + */ + drive->waiting_for_dma++; + if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { + printk(KERN_WARNING "%s: timeout waiting for ddma to \ + complete\n", drive->name); + return 1; + } + udelay(10); + return 0; +} + +static int auide_dma_host_on(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + return 0; +} + +static int auide_dma_on(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + drive->using_dma = 1; + return auide_dma_host_on(drive); +} + + +static int auide_dma_host_off(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + return 0; +} + +static int auide_dma_off_quietly(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + drive->using_dma = 0; + return auide_dma_host_off(drive); +} + +static int auide_dma_lostirq(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + + printk(KERN_ERR "%s: IRQ lost\n", drive->name); + return 0; +} + +static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs) +{ +// printk("%s\n", __FUNCTION__); + + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; + return; +} + +static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs) +{ +// printk("%s\n", __FUNCTION__); + + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; + return; +} + +static int auide_dma_timeout(ide_drive_t *drive) +{ +// printk("%s\n", __FUNCTION__); + + printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); + + if (HWIF(drive)->ide_dma_test_irq(drive)) + return 0; + + return HWIF(drive)->ide_dma_end(drive); +} +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ + + +static int auide_ddma_init( _auide_hwif *auide ) +{ +// printk("%s\n", __FUNCTION__); + + dbdev_tab_t source_dev_tab; +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + dbdev_tab_t target_dev_tab; + ide_hwif_t *hwif = auide->hwif; + char warning_output [2][80]; + int i; +#endif + + /* Add our custom device to DDMA device table */ + /* Create our new device entries in the table */ +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ; + + if( auide->white_list || auide->black_list ){ + source_dev_tab.dev_tsize = 8; + source_dev_tab.dev_devwidth = 32; + source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + source_dev_tab.dev_intlevel = 0; + source_dev_tab.dev_intpolarity = 0; + + /* init device table for target - static bus controller - */ + target_dev_tab.dev_id = DSCR_CMD0_ALWAYS; + target_dev_tab.dev_tsize = 8; + target_dev_tab.dev_devwidth = 32; + target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + target_dev_tab.dev_intlevel = 0; + target_dev_tab.dev_intpolarity = 0; + target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE; + } + else{ + source_dev_tab.dev_tsize = 1; + source_dev_tab.dev_devwidth = 16; + source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + source_dev_tab.dev_intlevel = 0; + source_dev_tab.dev_intpolarity = 0; + + /* init device table for target - static bus controller - */ + target_dev_tab.dev_id = DSCR_CMD0_ALWAYS; + target_dev_tab.dev_tsize = 1; + target_dev_tab.dev_devwidth = 16; + target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + target_dev_tab.dev_intlevel = 0; + target_dev_tab.dev_intpolarity = 0; + target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE; + + sprintf(&warning_output[0][0], + "%s is not on ide driver white list.", + auide_hwif.drive->id->model); + for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){ + sprintf(&warning_output[0][i]," "); + } + + sprintf(&warning_output[1][0], + "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.", + auide_hwif.drive->id->model); + for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){ + sprintf(&warning_output[1][i]," "); + } + + printk("\n****************************************"); + printk("****************************************\n"); + printk("* %s *\n",&warning_output[0][0]); + printk("* Switch to safe MWDMA Mode! "); + printk(" *\n"); + printk("* %s *\n",&warning_output[1][0]); + printk("****************************************"); + printk("****************************************\n\n"); + } +#else + source_dev_tab.dev_id = DSCR_CMD0_ALWAYS; + source_dev_tab.dev_tsize = 8; + source_dev_tab.dev_devwidth = 32; + source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + source_dev_tab.dev_intlevel = 0; + source_dev_tab.dev_intpolarity = 0; +#endif + +#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON + /* set flags for tx channel */ + source_dev_tab.dev_flags = DEV_FLAGS_OUT + | DEV_FLAGS_SYNC + | DEV_FLAGS_BURSTABLE; + auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); + /* set flags for rx channel */ + source_dev_tab.dev_flags = DEV_FLAGS_IN + | DEV_FLAGS_SYNC + | DEV_FLAGS_BURSTABLE; + auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); +#else + /* set flags for tx channel */ + source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC; + auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); + /* set flags for rx channel */ + source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC; + auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); +#endif + +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + + auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); + + /* Get a channel for TX */ + auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id, + auide->tx_dev_id, + auide_ddma_tx_callback, + (void*)auide); + /* Get a channel for RX */ + auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, + auide->target_dev_id, + auide_ddma_rx_callback, + (void*)auide); +#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */ + /* + * Note: if call back is not enabled, update ctp->cur_ptr manually + */ + auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, + auide->tx_dev_id, + NULL, + (void*)auide); + auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, + DSCR_CMD0_ALWAYS, + NULL, + (void*)auide); +#endif + auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, + NUM_DESCRIPTORS); + auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, + NUM_DESCRIPTORS); + +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + hwif->dmatable_cpu = dma_alloc_coherent(auide->dev, + PRD_ENTRIES * PRD_BYTES, /* 1 Page */ + &hwif->dmatable_dma, GFP_KERNEL); + + auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES, + GFP_KERNEL|GFP_DMA); + if (auide->sg_table == NULL) { + return -ENOMEM; + } +#endif + au1xxx_dbdma_start( auide->tx_chan ); + au1xxx_dbdma_start( auide->rx_chan ); + return 0; +} + +static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif) +{ + int i; +#define ide_ioreg_t unsigned long + ide_ioreg_t *ata_regs = hw->io_ports; + + /* fixme */ + for (i = 0; i < IDE_CONTROL_OFFSET; i++) { + *ata_regs++ = (ide_ioreg_t) ahwif->regbase + + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET); + } + + /* set the Alternative Status register */ + *ata_regs = (ide_ioreg_t) ahwif->regbase + + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET); +} + +static int au_ide_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + _auide_hwif *ahwif = &auide_hwif; + ide_hwif_t *hwif; + struct resource *res; + int ret = 0; + +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + char *mode = "MWDMA2"; +#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) + char *mode = "PIO+DDMA(offload)"; +#endif + + memset(&auide_hwif, 0, sizeof(_auide_hwif)); + auide_hwif.dev = 0; + + ahwif->dev = dev; + ahwif->irq = platform_get_irq(pdev, 0); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (res == NULL) { + pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id); + ret = -ENODEV; + goto out; + } + + if (!request_mem_region (res->start, res->end-res->start, pdev->name)) { + pr_debug("%s: request_mem_region failed\n", DRV_NAME); + ret = -EBUSY; + goto out; + } + + ahwif->regbase = (u32)ioremap(res->start, res->end-res->start); + if (ahwif->regbase == 0) { + ret = -ENOMEM; + goto out; + } + + hwif = &ide_hwifs[pdev->id]; + hw_regs_t *hw = &hwif->hw; + hwif->irq = hw->irq = ahwif->irq; + hwif->chipset = ide_au1xxx; + + auide_setup_ports(hw, ahwif); + memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ + hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ; + hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE) + || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize; +#else /* if kernel config is not set */ + hwif->rqsize = AU1XXX_ATA_RQSIZE; +#endif + + hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */ + hwif->swdma_mask = 0x07; +#else + hwif->mwdma_mask = 0x0; + hwif->swdma_mask = 0x0; +#endif + //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; + hwif->noprobe = 0; + hwif->drives[0].unmask = 1; + hwif->drives[1].unmask = 1; + + /* hold should be on in all cases */ + hwif->hold = 1; + hwif->mmio = 2; + + /* set up local I/O function entry points */ + hwif->INB = auide_inb; + hwif->INW = auide_inw; + hwif->INL = auide_inl; + hwif->INSW = auide_insw; + hwif->INSL = auide_insl; + hwif->OUTB = auide_outb; + hwif->OUTBSYNC = auide_outbsync; + hwif->OUTW = auide_outw; + hwif->OUTL = auide_outl; + hwif->OUTSW = auide_outsw; + hwif->OUTSL = auide_outsl; + + hwif->tuneproc = &auide_tune_drive; + hwif->speedproc = &auide_tune_chipset; + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + hwif->ide_dma_off_quietly = &auide_dma_off_quietly; + hwif->ide_dma_timeout = &auide_dma_timeout; + + hwif->ide_dma_check = &auide_dma_check; + hwif->dma_exec_cmd = &auide_dma_exec_cmd; + hwif->dma_start = &auide_dma_start; + hwif->ide_dma_end = &auide_dma_end; + hwif->dma_setup = &auide_dma_setup; + hwif->ide_dma_test_irq = &auide_dma_test_irq; + hwif->ide_dma_host_off = &auide_dma_host_off; + hwif->ide_dma_host_on = &auide_dma_host_on; + hwif->ide_dma_lostirq = &auide_dma_lostirq; + hwif->ide_dma_on = &auide_dma_on; + + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + hwif->atapi_dma = 1; + hwif->drives[0].using_dma = 1; + hwif->drives[1].using_dma = 1; +#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ + hwif->autodma = 0; + hwif->channel = 0; + hwif->hold = 1; + hwif->select_data = 0; /* no chipset-specific code */ + hwif->config_data = 0; /* no chipset-specific code */ + + hwif->drives[0].autodma = 0; + hwif->drives[0].drive_data = 0; /* no drive data */ + hwif->drives[0].using_dma = 0; + hwif->drives[0].waiting_for_dma = 0; + hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ + /* secondary hdd not supported */ + hwif->drives[1].autodma = 0; + + hwif->drives[1].drive_data = 0; + hwif->drives[1].using_dma = 0; + hwif->drives[1].waiting_for_dma = 0; + hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */ +#endif + hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ + hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ + + /*Register Driver with PM Framework*/ +#ifdef CONFIG_PM + auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED; + auide_hwif.pm.stopped = 0; + + auide_hwif.pm.dev = new_au1xxx_power_device( "ide", + &au1200ide_pm_callback, + NULL); + if ( auide_hwif.pm.dev == NULL ) + printk(KERN_INFO "Unable to create a power management \ + device entry for the au1200-IDE.\n"); + else + printk(KERN_INFO "Power management device entry for the \ + au1200-IDE loaded.\n"); +#endif + + auide_hwif.hwif = hwif; + hwif->hwif_data = &auide_hwif; + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA + auide_ddma_init(&auide_hwif); + dbdma_init_done = 1; +#endif + + probe_hwif_init(hwif); + dev_set_drvdata(dev, hwif); + + printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); + +out: + return ret; +} + +static int au_ide_remove(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct resource *res; + ide_hwif_t *hwif = dev_get_drvdata(dev); + _auide_hwif *ahwif = &auide_hwif; + + ide_unregister(hwif - ide_hwifs); + + iounmap((void *)ahwif->regbase); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, res->end - res->start); + + return 0; +} + +static struct device_driver au1200_ide_driver = { + .name = "au1200-ide", + .bus = &platform_bus_type, + .probe = au_ide_probe, + .remove = au_ide_remove, +}; + +static int __init au_ide_init(void) +{ + return driver_register(&au1200_ide_driver); +} + +static void __init au_ide_exit(void) +{ + driver_unregister(&au1200_ide_driver); +} + +#ifdef CONFIG_PM +int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\ + au1xxx_request_t request, void *data) { + + unsigned int d, err = 0; + unsigned long flags; + + spin_lock_irqsave(auide_hwif.pm.lock, flags); + + switch (request){ + case AU1XXX_PM_SLEEP: + err = au1xxxide_pm_sleep(dev); + break; + case AU1XXX_PM_WAKEUP: + d = *((unsigned int*)data); + if ( d > 0 && d <= 99) { + err = au1xxxide_pm_standby(dev); + } + else { + err = au1xxxide_pm_resume(dev); + } + break; + case AU1XXX_PM_GETSTATUS: + err = au1xxxide_pm_getstatus(dev); + break; + case AU1XXX_PM_ACCESS: + err = au1xxxide_pm_access(dev); + break; + case AU1XXX_PM_IDLE: + err = au1xxxide_pm_idle(dev); + break; + case AU1XXX_PM_CLEANUP: + err = au1xxxide_pm_cleanup(dev); + break; + default: + err = -1; + break; + } + + spin_unlock_irqrestore(auide_hwif.pm.lock, flags); + + return err; +} + +static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) { + return 0; +} + +static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) { + + int retval; + ide_hwif_t *hwif = auide_hwif.hwif; + struct request rq; + struct request_pm_state rqpm; + ide_task_t args; + + if(auide_hwif.pm.stopped) + return -1; + + /* + * wait until hard disc is ready + */ + if ( wait_for_ready(&hwif->drives[0], 35000) ) { + printk("Wait for drive sleep timeout!\n"); + retval = -1; + } + + /* + * sequenz to tell the high level ide driver that pm is resuming + */ + memset(&rq, 0, sizeof(rq)); + memset(&rqpm, 0, sizeof(rqpm)); + memset(&args, 0, sizeof(args)); + rq.flags = REQ_PM_SUSPEND; + rq.special = &args; + rq.pm = &rqpm; + rqpm.pm_step = ide_pm_state_start_suspend; + rqpm.pm_state = PMSG_SUSPEND; + + retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait); + + if (wait_for_ready (&hwif->drives[0], 35000)) { + printk("Wait for drive sleep timeout!\n"); + retval = -1; + } + + /* + * stop dbdma channels + */ + au1xxx_dbdma_reset(auide_hwif.tx_chan); + au1xxx_dbdma_reset(auide_hwif.rx_chan); + + auide_hwif.pm.stopped = 1; + + return retval; +} + +static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) { + + int retval; + ide_hwif_t *hwif = auide_hwif.hwif; + struct request rq; + struct request_pm_state rqpm; + ide_task_t args; + + if(!auide_hwif.pm.stopped) + return -1; + + /* + * start dbdma channels + */ + au1xxx_dbdma_start(auide_hwif.tx_chan); + au1xxx_dbdma_start(auide_hwif.rx_chan); + + /* + * wait until hard disc is ready + */ + if (wait_for_ready ( &hwif->drives[0], 35000)) { + printk("Wait for drive wake up timeout!\n"); + retval = -1; + } + + /* + * sequenz to tell the high level ide driver that pm is resuming + */ + memset(&rq, 0, sizeof(rq)); + memset(&rqpm, 0, sizeof(rqpm)); + memset(&args, 0, sizeof(args)); + rq.flags = REQ_PM_RESUME; + rq.special = &args; + rq.pm = &rqpm; + rqpm.pm_step = ide_pm_state_start_resume; + rqpm.pm_state = PMSG_ON; + + retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait); + + /* + * wait for hard disc + */ + if ( wait_for_ready(&hwif->drives[0], 35000) ) { + printk("Wait for drive wake up timeout!\n"); + retval = -1; + } + + auide_hwif.pm.stopped = 0; + + return retval; +} + +static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) { + return dev->cur_state; +} + +static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) { + if (dev->cur_state != AWAKE_STATE) + return 0; + else + return -1; +} + +static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) { + return 0; +} + +static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) { + return 0; +} +#endif /* CONFIG_PM */ + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("AU1200 IDE driver"); + +module_init(au_ide_init); +module_exit(au_ide_exit); diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h new file mode 100644 index 000000000000..b7b46dd9b929 --- /dev/null +++ b/include/asm-mips/mach-au1x00/au1xxx.h @@ -0,0 +1,44 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _AU1XXX_H_ +#define _AU1XXX_H_ + +#include + +#include + +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) +#include + +#elif defined(CONFIG_MIPS_PB1550) +#include + +#elif defined(CONFIG_MIPS_PB1200) +#include + +#elif defined(CONFIG_MIPS_DB1200) +#include + +#endif + +#endif /* _AU1XXX_H_ */ diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h index ddbd9f5a2489..b327bcd3fee1 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h +++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h @@ -368,6 +368,7 @@ void au1xxx_dbdma_dump(u32 chanid); u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ); u32 au1xxx_ddma_add_device( dbdev_tab_t *dev ); +void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); /* Some compatibilty macros -- @@ -375,9 +376,12 @@ u32 au1xxx_ddma_add_device( dbdev_tab_t *dev ); */ #define au1xxx_dbdma_put_source(chanid,buf,nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE) #define au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags) +#define put_source_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) + #define au1xxx_dbdma_put_dest(chanid,buf,nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE) #define au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags) +#define put_dest_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) /* * Flags for the put_source/put_dest functions. diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h new file mode 100644 index 000000000000..33d275c3b84c --- /dev/null +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -0,0 +1,301 @@ +/* + * include/asm-mips/mach-au1x00/au1xxx_ide.h version 01.30.00 Aug. 02 2005 + * + * BRIEF MODULE DESCRIPTION + * AMD Alchemy Au1xxx IDE interface routines over the Static Bus + * + * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE + * Interface and Linux Device Driver" Application Note. + */ +#include + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + #define DMA_WAIT_TIMEOUT 100 + #define NUM_DESCRIPTORS PRD_ENTRIES +#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */ + #define NUM_DESCRIPTORS 2 +#endif + +#ifndef AU1XXX_ATA_RQSIZE + #define AU1XXX_ATA_RQSIZE 128 +#endif + +/* Disable Burstable-Support for DBDMA */ +#ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON + #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0 +#endif + +#ifdef CONFIG_PM +/* +* This will enable the device to be powered up when write() or read() +* is called. If this is not defined, the driver will return -EBUSY. +*/ +#define WAKE_ON_ACCESS 1 + +typedef struct +{ + spinlock_t lock; /* Used to block on state transitions */ + au1xxx_power_dev_t *dev; /* Power Managers device structure */ + unsigned stopped; /* USed to signaling device is stopped */ +} pm_state; +#endif + + +typedef struct +{ + u32 tx_dev_id, rx_dev_id, target_dev_id; + u32 tx_chan, rx_chan; + void *tx_desc_head, *rx_desc_head; + ide_hwif_t *hwif; +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + ide_drive_t *drive; + u8 white_list, black_list; + struct dbdma_cmd *dma_table_cpu; + dma_addr_t dma_table_dma; + struct scatterlist *sg_table; + int sg_nents; + int sg_dma_direction; +#endif + struct device *dev; + int irq; + u32 regbase; +#ifdef CONFIG_PM + pm_state pm; +#endif +} _auide_hwif; + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA +struct drive_list_entry { + const char * id_model; + const char * id_firmware; +}; + +/* HD white list */ +static const struct drive_list_entry dma_white_list [] = { +/* + * Hitachi + */ + { "HITACHI_DK14FA-20" , "ALL" }, + { "HTS726060M9AT00" , "ALL" }, +/* + * Maxtor + */ + { "Maxtor 6E040L0" , "ALL" }, + { "Maxtor 6Y080P0" , "ALL" }, + { "Maxtor 6Y160P0" , "ALL" }, +/* + * Seagate + */ + { "ST3120026A" , "ALL" }, + { "ST320014A" , "ALL" }, + { "ST94011A" , "ALL" }, + { "ST340016A" , "ALL" }, +/* + * Western Digital + */ + { "WDC WD400UE-00HCT0" , "ALL" }, + { "WDC WD400JB-00JJC0" , "ALL" }, + { NULL , NULL } +}; + +/* HD black list */ +static const struct drive_list_entry dma_black_list [] = { +/* + * Western Digital + */ + { "WDC WD100EB-00CGH0" , "ALL" }, + { "WDC WD200BB-00AUA1" , "ALL" }, + { "WDC AC24300L" , "ALL" }, + { NULL , NULL } +}; +#endif + +/* function prototyping */ +u8 auide_inb(unsigned long port); +u16 auide_inw(unsigned long port); +u32 auide_inl(unsigned long port); +void auide_insw(unsigned long port, void *addr, u32 count); +void auide_insl(unsigned long port, void *addr, u32 count); +void auide_outb(u8 addr, unsigned long port); +void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port); +void auide_outw(u16 addr, unsigned long port); +void auide_outl(u32 addr, unsigned long port); +void auide_outsw(unsigned long port, void *addr, u32 count); +void auide_outsl(unsigned long port, void *addr, u32 count); +static void auide_tune_drive(ide_drive_t *drive, byte pio); +static int auide_tune_chipset (ide_drive_t *drive, u8 speed); +static int auide_ddma_init( _auide_hwif *auide ); +static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif); +int __init auide_probe(void); + +#ifdef CONFIG_PM + int au1200ide_pm_callback( au1xxx_power_dev_t *dev, + au1xxx_request_t request, void *data); + static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ); + static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ); +#endif + + +/* + * Multi-Word DMA + DbDMA functions + */ +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + + static int in_drive_list(struct hd_driveid *id, + const struct drive_list_entry *drive_table); + static int auide_build_sglist(ide_drive_t *drive, struct request *rq); + static int auide_build_dmatable(ide_drive_t *drive); + static int auide_dma_end(ide_drive_t *drive); + static void auide_dma_start(ide_drive_t *drive ); + ide_startstop_t auide_dma_intr (ide_drive_t *drive); + static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command); + static int auide_dma_setup(ide_drive_t *drive); + static int auide_dma_check(ide_drive_t *drive); + static int auide_dma_test_irq(ide_drive_t *drive); + static int auide_dma_host_off(ide_drive_t *drive); + static int auide_dma_host_on(ide_drive_t *drive); + static int auide_dma_lostirq(ide_drive_t *drive); + static int auide_dma_on(ide_drive_t *drive); + static void auide_ddma_tx_callback(int irq, void *param, + struct pt_regs *regs); + static void auide_ddma_rx_callback(int irq, void *param, + struct pt_regs *regs); + static int auide_dma_off_quietly(ide_drive_t *drive); + static int auide_dma_timeout(ide_drive_t *drive); + +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ + +/******************************************************************************* +* PIO Mode timing calculation : * +* * +* Static Bus Spec ATA Spec * +* Tcsoe = t1 * +* Toecs = t9 * +* Twcs = t9 * +* Tcsh = t2i | t2 * +* Tcsoff = t2i | t2 * +* Twp = t2 * +* Tcsw = t1 * +* Tpm = 0 * +* Ta = t1+t2 * +*******************************************************************************/ + +#define TCSOE_MASK (0x07<<29) +#define TOECS_MASK (0x07<<26) +#define TWCS_MASK (0x07<<28) +#define TCSH_MASK (0x0F<<24) +#define TCSOFF_MASK (0x07<<20) +#define TWP_MASK (0x3F<<14) +#define TCSW_MASK (0x0F<<10) +#define TPM_MASK (0x0F<<6) +#define TA_MASK (0x3F<<0) +#define TS_MASK (1<<8) + +/* Timing parameters PIO mode 0 */ +#define SBC_IDE_PIO0_TCSOE (0x04<<29) +#define SBC_IDE_PIO0_TOECS (0x01<<26) +#define SBC_IDE_PIO0_TWCS (0x02<<28) +#define SBC_IDE_PIO0_TCSH (0x08<<24) +#define SBC_IDE_PIO0_TCSOFF (0x07<<20) +#define SBC_IDE_PIO0_TWP (0x10<<14) +#define SBC_IDE_PIO0_TCSW (0x04<<10) +#define SBC_IDE_PIO0_TPM (0x0<<6) +#define SBC_IDE_PIO0_TA (0x15<<0) +/* Timing parameters PIO mode 1 */ +#define SBC_IDE_PIO1_TCSOE (0x03<<29) +#define SBC_IDE_PIO1_TOECS (0x01<<26) +#define SBC_IDE_PIO1_TWCS (0x01<<28) +#define SBC_IDE_PIO1_TCSH (0x06<<24) +#define SBC_IDE_PIO1_TCSOFF (0x06<<20) +#define SBC_IDE_PIO1_TWP (0x08<<14) +#define SBC_IDE_PIO1_TCSW (0x03<<10) +#define SBC_IDE_PIO1_TPM (0x00<<6) +#define SBC_IDE_PIO1_TA (0x0B<<0) +/* Timing parameters PIO mode 2 */ +#define SBC_IDE_PIO2_TCSOE (0x05<<29) +#define SBC_IDE_PIO2_TOECS (0x01<<26) +#define SBC_IDE_PIO2_TWCS (0x01<<28) +#define SBC_IDE_PIO2_TCSH (0x07<<24) +#define SBC_IDE_PIO2_TCSOFF (0x07<<20) +#define SBC_IDE_PIO2_TWP (0x1F<<14) +#define SBC_IDE_PIO2_TCSW (0x05<<10) +#define SBC_IDE_PIO2_TPM (0x00<<6) +#define SBC_IDE_PIO2_TA (0x22<<0) +/* Timing parameters PIO mode 3 */ +#define SBC_IDE_PIO3_TCSOE (0x05<<29) +#define SBC_IDE_PIO3_TOECS (0x01<<26) +#define SBC_IDE_PIO3_TWCS (0x01<<28) +#define SBC_IDE_PIO3_TCSH (0x0D<<24) +#define SBC_IDE_PIO3_TCSOFF (0x0D<<20) +#define SBC_IDE_PIO3_TWP (0x15<<14) +#define SBC_IDE_PIO3_TCSW (0x05<<10) +#define SBC_IDE_PIO3_TPM (0x00<<6) +#define SBC_IDE_PIO3_TA (0x1A<<0) +/* Timing parameters PIO mode 4 */ +#define SBC_IDE_PIO4_TCSOE (0x04<<29) +#define SBC_IDE_PIO4_TOECS (0x01<<26) +#define SBC_IDE_PIO4_TWCS (0x01<<28) +#define SBC_IDE_PIO4_TCSH (0x04<<24) +#define SBC_IDE_PIO4_TCSOFF (0x04<<20) +#define SBC_IDE_PIO4_TWP (0x0D<<14) +#define SBC_IDE_PIO4_TCSW (0x03<<10) +#define SBC_IDE_PIO4_TPM (0x00<<6) +#define SBC_IDE_PIO4_TA (0x12<<0) +/* Timing parameters MDMA mode 0 */ +#define SBC_IDE_MDMA0_TCSOE (0x03<<29) +#define SBC_IDE_MDMA0_TOECS (0x01<<26) +#define SBC_IDE_MDMA0_TWCS (0x01<<28) +#define SBC_IDE_MDMA0_TCSH (0x07<<24) +#define SBC_IDE_MDMA0_TCSOFF (0x07<<20) +#define SBC_IDE_MDMA0_TWP (0x0C<<14) +#define SBC_IDE_MDMA0_TCSW (0x03<<10) +#define SBC_IDE_MDMA0_TPM (0x00<<6) +#define SBC_IDE_MDMA0_TA (0x0F<<0) +/* Timing parameters MDMA mode 1 */ +#define SBC_IDE_MDMA1_TCSOE (0x05<<29) +#define SBC_IDE_MDMA1_TOECS (0x01<<26) +#define SBC_IDE_MDMA1_TWCS (0x01<<28) +#define SBC_IDE_MDMA1_TCSH (0x05<<24) +#define SBC_IDE_MDMA1_TCSOFF (0x05<<20) +#define SBC_IDE_MDMA1_TWP (0x0F<<14) +#define SBC_IDE_MDMA1_TCSW (0x05<<10) +#define SBC_IDE_MDMA1_TPM (0x00<<6) +#define SBC_IDE_MDMA1_TA (0x15<<0) +/* Timing parameters MDMA mode 2 */ +#define SBC_IDE_MDMA2_TCSOE (0x04<<29) +#define SBC_IDE_MDMA2_TOECS (0x01<<26) +#define SBC_IDE_MDMA2_TWCS (0x01<<28) +#define SBC_IDE_MDMA2_TCSH (0x04<<24) +#define SBC_IDE_MDMA2_TCSOFF (0x04<<20) +#define SBC_IDE_MDMA2_TWP (0x0D<<14) +#define SBC_IDE_MDMA2_TCSW (0x04<<10) +#define SBC_IDE_MDMA2_TPM (0x00<<6) +#define SBC_IDE_MDMA2_TA (0x12<<0) + diff --git a/include/linux/ide.h b/include/linux/ide.h index a6dbb51ecd7b..3461abc1e854 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -218,7 +218,7 @@ typedef enum { ide_unknown, ide_generic, ide_pci, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, ide_pmac, ide_etrax100, ide_acorn, - ide_forced + ide_au1xxx, ide_forced } hwif_chipset_t; /* -- cgit v1.2.3