From 4b95320fc4d21b0ff2f8604305dd6c851aff6096 Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Wed, 17 Jan 2007 11:07:54 +0800 Subject: [AGPGART] intel_agp: restore graphics device's pci space early in resume Currently in resuming path graphics device's pci space restore is behind host bridge, so resume function wrongly accesses graphics device's space. This makes resuming failure which crashed X. here's a patch to restore device's pci space early, which makes resuming ok with X. Signed-off-by: Wang Zhenyu Signed-off-by: Dave Jones --- drivers/char/agp/intel-agp.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index ab0a9c0ad7c0..a3011de51f7c 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1955,6 +1955,15 @@ static int agp_intel_resume(struct pci_dev *pdev) pci_restore_state(pdev); + /* We should restore our graphics device's config space, + * as host bridge (00:00) resumes before graphics device (02:00), + * then our access to its pci space can work right. + */ + if (intel_i810_private.i810_dev) + pci_restore_state(intel_i810_private.i810_dev); + if (intel_i830_private.i830_dev) + pci_restore_state(intel_i830_private.i830_dev); + if (bridge->driver == &intel_generic_driver) intel_configure(); else if (bridge->driver == &intel_850_driver) -- cgit v1.2.3 From a20f3a6d7e67a8aee571fb04634a631ba59f6e92 Mon Sep 17 00:00:00 2001 From: Ishai Rabinovitz Date: Tue, 16 Jan 2007 17:20:25 +0200 Subject: IB/srp: Check match_strdup() return Checks if the kmalloc in match_strdup() was successful, and bail out on looking at the token if it failed. Signed-off-by: Ishai Rabinovitz Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index cdecbf5911c8..72611fd15103 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1621,18 +1621,30 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) switch (token) { case SRP_OPT_ID_EXT: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; case SRP_OPT_IOC_GUID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; case SRP_OPT_DGID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } if (strlen(p) != 32) { printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); kfree(p); @@ -1656,6 +1668,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) case SRP_OPT_SERVICE_ID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; @@ -1693,6 +1709,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) case SRP_OPT_INITIATOR_EXT: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; -- cgit v1.2.3 From ce29d72cc737df3573854a4719f00385adf1c9a6 Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Fri, 19 Jan 2007 22:50:10 +0100 Subject: IB/ehca: Fix improper use of yield() with spinlock held Signed-off-by: Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_cq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 93995b658d94..6074c897f51c 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -344,8 +344,11 @@ int ehca_destroy_cq(struct ib_cq *cq) unsigned long flags; spin_lock_irqsave(&ehca_cq_idr_lock, flags); - while (my_cq->nr_callbacks) + while (my_cq->nr_callbacks) { + spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); yield(); + spin_lock_irqsave(&ehca_cq_idr_lock, flags); + } idr_remove(&ehca_cq_idr, my_cq->token); spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); -- cgit v1.2.3 From cea9ea67e9927da18af89b49bd949a8d65ba1b15 Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Fri, 19 Jan 2007 22:50:10 +0100 Subject: IB/ehca: Fix mismatched spin_unlock in irq handler The lock is taken with _irqsave and hence must be released with _irqrestore on all paths. Signed-off-by Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index e7209afb4250..c069be8cbcb2 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -440,7 +440,8 @@ void ehca_tasklet_eq(unsigned long data) cq = idr_find(&ehca_cq_idr, token); if (cq == NULL) { - spin_unlock(&ehca_cq_idr_lock); + spin_unlock_irqrestore(&ehca_cq_idr_lock, + flags); break; } -- cgit v1.2.3 From d08d283974f96cb30d78ba24282a0a7d6709af32 Mon Sep 17 00:00:00 2001 From: Komuro Date: Sat, 2 Dec 2006 11:53:27 +0900 Subject: modify 3c589_cs to be SMP safe 1. EL3WINDOW is always 1 when lock is not held. 2. The second argument of el3_interrupt is 'void *dev_id', not 'struct el3_private *lp'. Signed-off-by: komurojun-mbn@nifty.com Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/3c589_cs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 342f4062de0b..461e8274ef69 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -606,11 +606,14 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; struct el3_private *priv = netdev_priv(dev); + unsigned long flags; DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " "status %4.4x.\n", dev->name, (long)skb->len, inw(ioaddr + EL3_STATUS)); + spin_lock_irqsave(&priv->lock, flags); + priv->stats.tx_bytes += skb->len; /* Put out the doubleword header... */ @@ -628,6 +631,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); pop_tx_status(dev); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -729,14 +733,13 @@ static void media_check(unsigned long arg) if (!netif_device_present(dev)) goto reschedule; - EL3WINDOW(1); /* Check for pending interrupt with expired latency timer: with this, we can limp along even if the interrupt is blocked */ if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, lp); + el3_interrupt(dev->irq, dev); lp->fast_poll = HZ; } if (lp->fast_poll) { -- cgit v1.2.3 From 9f6d55d0846dd8628fd3eac15be377c4d3493c3e Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sat, 20 Jan 2007 16:38:26 -0600 Subject: PHY: Export phy ethtool helpers We need to export phy_ethtool_gset and phy_ethtool_sset to allow drivers that use these functions to be built as modules. Signed-off-by: Kumar Gala Signed-off-by: Jeff Garzik --- drivers/net/phy/phy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e175f3910b18..9765fa661467 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -286,6 +286,7 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) return 0; } +EXPORT_SYMBOL(phy_ethtool_sset); int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) { @@ -302,7 +303,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) return 0; } - +EXPORT_SYMBOL(phy_ethtool_gset); /* Note that this function is currently incompatible with the * PHYCONTROL layer. It changes registers without regard to -- cgit v1.2.3 From 061bf3cdba753ae7b52fba8cc324d81adac77696 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:52:20 +0100 Subject: ehea: Fixed wrong dereferencation Not only check the pointer against 0 but also the dereferenced value Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 2 +- drivers/net/ehea/ehea_main.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 39ad9f73d1ec..be10a3a26b5b 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0043" +#define DRV_VERSION "EHEA_0044" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 83fa32f72398..49f669c4b019 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2471,14 +2471,16 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", NULL); - if (!adapter_handle) { + if (adapter_handle) + adapter->handle = *adapter_handle; + + if (!adapter->handle) { dev_err(&dev->ofdev.dev, "failed getting handle for adapter" " '%s'\n", dev->ofdev.node->full_name); ret = -ENODEV; goto out_free_ad; } - adapter->handle = *adapter_handle; adapter->pd = EHEA_PD_ID; dev->ofdev.dev.driver_data = adapter; -- cgit v1.2.3 From 602e0d100daa9ba9bc7c17e0014a6f76b638dc80 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:52:50 +0100 Subject: ehea: Fixing firmware queue config issue Fix to use exactly one queue for incoming packets in all firmware configurations Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 49f669c4b019..3e9c760cb283 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -998,7 +998,7 @@ static int ehea_configure_port(struct ehea_port *port) | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); for (i = 0; i < port->num_def_qps; i++) - cb0->default_qpn_arr[i] = port->port_res[i].qp->init_attr.qp_nr; + cb0->default_qpn_arr[i] = port->port_res[0].qp->init_attr.qp_nr; if (netif_msg_ifup(port)) ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); -- cgit v1.2.3 From e919b5938b11e1d48a6dcdcb2860e890a954f10d Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:53:20 +0100 Subject: ehea: Modified initial autoneg state determination Logical partitions are not allowed to (try to) set the autonegotiation status. This patch removes the respective function call from the port setup function. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3e9c760cb283..d84d0950b658 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -642,6 +642,8 @@ int ehea_sense_port_attr(struct ehea_port *port) break; } + port->autoneg = 1; + /* Number of default QPs */ port->num_def_qps = cb0->num_default_qps; @@ -2334,8 +2336,6 @@ static int ehea_setup_single_port(struct ehea_port *port, INIT_LIST_HEAD(&port->mc_list->list); - ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); - ret = ehea_sense_port_attr(port); if (ret) goto out; -- cgit v1.2.3 From 4e996b32e0585756c335b35980dc68852c33f297 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:53:50 +0100 Subject: ehea: New method to determine number of available ports Count OFDT nodes to determine the number of available ports instead of using the possibly outdated value from the hypervisor Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d84d0950b658..9486e0a8ec8b 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2269,6 +2269,8 @@ static void ehea_tx_watchdog(struct net_device *dev) int ehea_sense_adapter_attr(struct ehea_adapter *adapter) { struct hcp_query_ehea *cb; + struct device_node *lhea_dn = NULL; + struct device_node *eth_dn = NULL; u64 hret; int ret; @@ -2285,7 +2287,18 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) goto out_herr; } - adapter->num_ports = cb->num_ports; + /* Determine the number of available logical ports + * by counting the child nodes of the lhea OFDT entry + */ + adapter->num_ports = 0; + lhea_dn = of_find_node_by_name(lhea_dn, "lhea"); + do { + eth_dn = of_get_next_child(lhea_dn, eth_dn); + if (eth_dn) + adapter->num_ports++; + } while ( eth_dn ); + of_node_put(lhea_dn); + adapter->max_mc_mac = cb->max_mc_mac - 1; ret = 0; -- cgit v1.2.3 From 7674a588e93c6fa1fde8e452a4c025c49037cb96 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:54:20 +0100 Subject: ehea: Improved logging of permission issues Disabled dump of hcall regs on some permission issues and fixed appropriate misleading logmessages Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 16 +++++++--------- drivers/net/ehea/ehea_phyp.c | 10 ++++++++-- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 9486e0a8ec8b..8281b30da32d 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -730,10 +730,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) } } else { if (hret == H_AUTHORITY) { - ehea_info("Hypervisor denied setting port speed. Either" - " this partition is not authorized to set " - "port speed or another partition has modified" - " port speed first."); + ehea_info("Hypervisor denied setting port speed"); ret = -EPERM; } else { ret = -EIO; @@ -1487,11 +1484,12 @@ out: static void ehea_promiscuous_error(u64 hret, int enable) { - ehea_info("Hypervisor denied %sabling promiscuous mode.%s", - enable == 1 ? "en" : "dis", - hret != H_AUTHORITY ? "" : " Another partition owning a " - "logical port on the same physical port might have altered " - "promiscuous mode first."); + if (hret == H_AUTHORITY) + ehea_info("Hypervisor denied %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); + else + ehea_error("failed %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); } static void ehea_promiscuous(struct net_device *dev, int enable) diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 0cfc2bc1a27b..37716e05e808 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -94,6 +94,7 @@ static long ehea_plpar_hcall9(unsigned long opcode, { long ret; int i, sleep_msecs; + u8 cb_cat; for (i = 0; i < 5; i++) { ret = plpar_hcall9(opcode, outs, @@ -106,7 +107,13 @@ static long ehea_plpar_hcall9(unsigned long opcode, continue; } - if (ret < H_SUCCESS) + cb_cat = EHEA_BMASK_GET(H_MEHEAPORT_CAT, arg2); + + if ((ret < H_SUCCESS) && !(((ret == H_AUTHORITY) + && (opcode == H_MODIFY_HEA_PORT)) + && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) + || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) + && (arg3 == H_PORT_CB7_DUCQPN))))) ehea_error("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" @@ -120,7 +127,6 @@ static long ehea_plpar_hcall9(unsigned long opcode, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); - return ret; } -- cgit v1.2.3 From bb3a6449c18f6203e59195a98d633f5b5b57c133 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:54:50 +0100 Subject: ehea: Added logging off associated errors Added logging of error events associated with a specific queue pair Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 8281b30da32d..22c81ae4f9ad 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -558,12 +558,12 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) u32 qp_token; eqe = ehea_poll_eq(port->qp_eq); - ehea_debug("eqe=%p", eqe); + while (eqe) { - ehea_debug("*eqe=%lx", *(u64*)eqe); - eqe = ehea_poll_eq(port->qp_eq); qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_debug("next eqe=%p", eqe); + ehea_error("QP aff_err: entry=0x%lx, token=0x%x", + eqe->entry, qp_token); + eqe = ehea_poll_eq(port->qp_eq); } return IRQ_HANDLED; -- cgit v1.2.3 From 41b69c705152e93b3c6c872678dffd8a19b14d61 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 22 Jan 2007 12:55:20 +0100 Subject: ehea: Fixed possible nullpointer access Fixed possible nullpointer access in event queue processing Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 22c81ae4f9ad..1072e69ef85d 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -575,8 +575,9 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, int i; for (i = 0; i < adapter->num_ports; i++) - if (adapter->port[i]->logical_port_id == logical_port) - return adapter->port[i]; + if (adapter->port[i]) + if (adapter->port[i]->logical_port_id == logical_port) + return adapter->port[i]; return NULL; } -- cgit v1.2.3 From 90f8b1d295e0c4a2148776e6cf801391cf07ae92 Mon Sep 17 00:00:00 2001 From: Amit S. Kale Date: Mon, 22 Jan 2007 06:38:05 -0800 Subject: NetXen: Firmware check modifications This patch is to make the driver work with multiple minor firmware versions Signed-off-by: Amit S. Kale Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 7 +++---- drivers/net/netxen/netxen_nic_hw.c | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6490acf05305..663fa2fbe9f5 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,12 +63,11 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "4" +#define NETXEN_NIC_BUILD_NO "1" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 -#define _NETXEN_NIC_LINUX_SUBVERSION 2 -#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO -#define NETXEN_NIC_FW_VERSIONID "3.3.2" +#define _NETXEN_NIC_LINUX_SUBVERSION 3 +#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" "-" NETXEN_NIC_BUILD_NO #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c0c31d1914a7..191e2336e323 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -984,7 +984,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) _NETXEN_NIC_LINUX_MAJOR, fw_major); adapter->driver_mismatch = 1; } - if (fw_minor != _NETXEN_NIC_LINUX_MINOR) { + if (fw_minor != _NETXEN_NIC_LINUX_MINOR && + fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { printk(KERN_ERR "The mismatch in driver version and firmware " "version minor number\n" "Driver version minor number = %d \t" -- cgit v1.2.3 From 184231bdb41fc4c385ae8e115f5afaff02fe1690 Mon Sep 17 00:00:00 2001 From: Amit S. Kale Date: Mon, 22 Jan 2007 06:52:53 -0800 Subject: NetXen: Use pci_register_driver() instead of pci_module_init() in init_module This will use pci_register_driver() instead of pci_module_init(). Signed-off-by: Amit S. Kale Signed-off-by: Richard Knutsson Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 2 +- drivers/net/netxen/netxen_nic_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 663fa2fbe9f5..59324b1693d6 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,7 +63,7 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "1" +#define NETXEN_NIC_BUILD_NO "2" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 #define _NETXEN_NIC_LINUX_SUBVERSION 3 diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 8a5792fea774..96e1bee19ba0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1144,7 +1144,7 @@ static int __init netxen_init_module(void) if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0) return -ENOMEM; - return pci_module_init(&netxen_driver); + return pci_register_driver(&netxen_driver); } module_init(netxen_init_module); -- cgit v1.2.3 From 084384754ebe6636f9e5554ad30b3143b4a26c84 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 22 Jan 2007 20:40:38 -0800 Subject: [PATCH] KVM: make sure there is a vcpu context loaded when destroying the mmu This makes the vmwrite errors on vm shutdown go away. Signed-off-by: Avi Kivity Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/kvm_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 67c1154960f0..be4651abe72c 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -272,7 +272,9 @@ static void kvm_free_physmem(struct kvm *kvm) static void kvm_free_vcpu(struct kvm_vcpu *vcpu) { + vcpu_load(vcpu->kvm, vcpu_slot(vcpu)); kvm_mmu_destroy(vcpu); + vcpu_put(vcpu); kvm_arch_ops->vcpu_free(vcpu); } -- cgit v1.2.3 From cccf748b810832cfab4dbb3ed4c7cf1a1ee35ad2 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 22 Jan 2007 20:40:39 -0800 Subject: [PATCH] KVM: fix race between mmio reads and injected interrupts The kvm mmio read path looks like: 1. guest read faults 2. kvm emulates read, calls emulator_read_emulated() 3. fails as a read requires userspace help 4. exit to userspace 5. userspace emulates read, kvm sets vcpu->mmio_read_completed 6. re-enter guest, fault again 7. kvm emulates read, calls emulator_read_emulated() 8. succeeds as vcpu->mmio_read_emulated is set 9. instruction completes and guest is resumed A problem surfaces if the userspace exit (step 5) also requests an interrupt injection. In that case, the guest does not re-execute the original instruction, but the interrupt handler. The next time an mmio read is exectued (likely for a different address), step 3 will find vcpu->mmio_read_completed set and return the value read for the original instruction. The problem manifested itself in a few annoying ways: - little squares appear randomly on console when switching virtual terminals - ne2000 fails under nfs read load - rtl8139 complains about "pci errors" even though the device model is incapable of issuing them. Fix by skipping interrupt injection if an mmio read is pending. A better fix is to avoid re-entry into the guest, and re-emulating immediately instead. However that's a bit more complex. Signed-off-by: Avi Kivity Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/svm.c | 3 ++- drivers/kvm/vmx.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 714f6a7841cd..7397bfbbcb1c 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -1407,7 +1407,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int r; again: - do_interrupt_requests(vcpu, kvm_run); + if (!vcpu->mmio_read_completed) + do_interrupt_requests(vcpu, kvm_run); clgi(); diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 0aa2659f6ae5..27f2751c3baa 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1717,7 +1717,8 @@ again: vmcs_writel(HOST_GS_BASE, segment_base(gs_sel)); #endif - do_interrupt_requests(vcpu, kvm_run); + if (!vcpu->mmio_read_completed) + do_interrupt_requests(vcpu, kvm_run); if (vcpu->guest_debug.enabled) kvm_guest_debug_pre(vcpu); -- cgit v1.2.3 From 038e51de2e7ae2c8e9d8a0b15231f8509875dc33 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 22 Jan 2007 20:40:40 -0800 Subject: [PATCH] KVM: x86 emulator: fix bit string instructions The various bit string instructions (bts, btc, etc.) fail to adjust the address correctly if the bit address is beyond BITS_PER_LONG. This bug creeped in as the emulator originally relied on cr2 to contain the memory address; however we now decode it from the mod r/m bits, and must adjust the offset to account for large bit indices. The patch is rather large because it switches src and dst decoding around, so that the bit index is available when decoding the memory address. This fixes workloads like the FC5 installer. Signed-off-by: Avi Kivity Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/x86_emulate.c | 98 +++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index be70795b4822..7513cddb929f 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -61,6 +61,7 @@ #define ModRM (1<<6) /* Destination is only written; never read. */ #define Mov (1<<7) +#define BitOp (1<<8) static u8 opcode_table[256] = { /* 0x00 - 0x07 */ @@ -148,7 +149,7 @@ static u8 opcode_table[256] = { 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM }; -static u8 twobyte_table[256] = { +static u16 twobyte_table[256] = { /* 0x00 - 0x0F */ 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, @@ -180,16 +181,16 @@ static u8 twobyte_table[256] = { /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xA7 */ - 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, /* 0xA8 - 0xAF */ - 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, /* 0xB0 - 0xB7 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, - DstMem | SrcReg | ModRM, + DstMem | SrcReg | ModRM | BitOp, 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xB8 - 0xBF */ - 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM, + 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xC0 - 0xCF */ @@ -469,7 +470,8 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, int x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { - u8 b, d, sib, twobyte = 0, rex_prefix = 0; + unsigned d; + u8 b, sib, twobyte = 0, rex_prefix = 0; u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; unsigned long *override_base = NULL; unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; @@ -726,46 +728,6 @@ done_prefixes: ; } - /* Decode and fetch the destination operand: register or memory. */ - switch (d & DstMask) { - case ImplicitOps: - /* Special instructions do their own operand decoding. */ - goto special_insn; - case DstReg: - dst.type = OP_REG; - if ((d & ByteOp) - && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { - dst.ptr = decode_register(modrm_reg, _regs, - (rex_prefix == 0)); - dst.val = *(u8 *) dst.ptr; - dst.bytes = 1; - } else { - dst.ptr = decode_register(modrm_reg, _regs, 0); - switch ((dst.bytes = op_bytes)) { - case 2: - dst.val = *(u16 *)dst.ptr; - break; - case 4: - dst.val = *(u32 *)dst.ptr; - break; - case 8: - dst.val = *(u64 *)dst.ptr; - break; - } - } - break; - case DstMem: - dst.type = OP_MEM; - dst.ptr = (unsigned long *)cr2; - dst.bytes = (d & ByteOp) ? 1 : op_bytes; - if (!(d & Mov) && /* optimisation - avoid slow emulated read */ - ((rc = ops->read_emulated((unsigned long)dst.ptr, - &dst.val, dst.bytes, ctxt)) != 0)) - goto done; - break; - } - dst.orig_val = dst.val; - /* * Decode and fetch the source operand: register, memory * or immediate. @@ -838,6 +800,50 @@ done_prefixes: break; } + /* Decode and fetch the destination operand: register or memory. */ + switch (d & DstMask) { + case ImplicitOps: + /* Special instructions do their own operand decoding. */ + goto special_insn; + case DstReg: + dst.type = OP_REG; + if ((d & ByteOp) + && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { + dst.ptr = decode_register(modrm_reg, _regs, + (rex_prefix == 0)); + dst.val = *(u8 *) dst.ptr; + dst.bytes = 1; + } else { + dst.ptr = decode_register(modrm_reg, _regs, 0); + switch ((dst.bytes = op_bytes)) { + case 2: + dst.val = *(u16 *)dst.ptr; + break; + case 4: + dst.val = *(u32 *)dst.ptr; + break; + case 8: + dst.val = *(u64 *)dst.ptr; + break; + } + } + break; + case DstMem: + dst.type = OP_MEM; + dst.ptr = (unsigned long *)cr2; + dst.bytes = (d & ByteOp) ? 1 : op_bytes; + if (d & BitOp) { + dst.ptr += src.val / BITS_PER_LONG; + dst.bytes = sizeof(long); + } + if (!(d & Mov) && /* optimisation - avoid slow emulated read */ + ((rc = ops->read_emulated((unsigned long)dst.ptr, + &dst.val, dst.bytes, ctxt)) != 0)) + goto done; + break; + } + dst.orig_val = dst.val; + if (twobyte) goto twobyte_insn; -- cgit v1.2.3 From fc3dffe12148b9612870eb21b24f2aecefa9ea24 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 22 Jan 2007 20:40:40 -0800 Subject: [PATCH] KVM: fix bogus pagefault on writable pages If a page is marked as dirty in the guest pte, set_pte_common() can set the writable bit on newly-instantiated shadow pte. This optimization avoids a write fault after the initial read fault. However, if a write fault instantiates the pte, fix_write_pf() incorrectly reports the fault as a guest page fault, and the guest oopses on what appears to be a correctly-mapped page. Fix is to detect the condition and only report a guest page fault on a user access to a kernel page. With the fix, a kvm guest can survive a whole night of running the kernel hacker's screensaver (make -j9 in a loop). Signed-off-by: Avi Kivity Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/paging_tmpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 2dbf4307ed9e..6bc41950fbb3 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -274,7 +274,7 @@ static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page; if (is_writeble_pte(*shadow_ent)) - return 0; + return !user || (*shadow_ent & PT_USER_MASK); writable_shadow = *shadow_ent & PT_SHADOW_WRITABLE_MASK; if (user) { -- cgit v1.2.3 From 15c945c3d0913d73a7d57d7a0a3c4e2902598cc6 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Mon, 22 Jan 2007 20:40:41 -0800 Subject: [PATCH] rtc-sh: act on rtc_wkalrm.enabled when setting an alarm This fixes the SH rtc driver correctly act on the "enabled" flag when setting an alarm. Signed-off-by: Jamie Lenehan Cc: David Brownell Cc: Alessandro Zummo Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-sh.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index e9e0934380b8..198b9f22fbff 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -492,10 +492,10 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) spin_lock_irq(&rtc->lock); - /* disable alarm interrupt and clear flag */ + /* disable alarm interrupt and clear the alarm flag */ rcr1 = readb(rtc->regbase + RCR1); - rcr1 &= ~RCR1_AF; - writeb(rcr1 & ~RCR1_AIE, rtc->regbase + RCR1); + rcr1 &= ~(RCR1_AF|RCR1_AIE); + writeb(rcr1, rtc->regbase + RCR1); rtc->rearm_aie = 0; @@ -510,8 +510,10 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) mon += 1; sh_rtc_write_alarm_value(rtc, mon, RMONAR); - /* Restore interrupt activation status */ - writeb(rcr1, rtc->regbase + RCR1); + if (wkalrm->enabled) { + rcr1 |= RCR1_AIE; + writeb(rcr1, rtc->regbase + RCR1); + } spin_unlock_irq(&rtc->lock); -- cgit v1.2.3 From 79603a35009ff39562cd5634fa1cf513eb080f27 Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Mon, 22 Jan 2007 20:40:44 -0800 Subject: [PATCH] tlclk: bug fix + misc fixes The following patch fixes a few problems with the tlclk driver. * bug in the select_amcb1_transmit_clock * racy read sys call * racy open sys call * use of add_timer where mod_timer would be better * change to the timer data parameter use Signed-off-by: Mark Gross Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tlclk.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 448d5083c381..4fac2bdf6215 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -186,6 +186,7 @@ static int got_event; /* if events processing have been done */ static void switchover_timeout(unsigned long data); static struct timer_list switchover_timer = TIMER_INITIALIZER(switchover_timeout , 0, 0); +static unsigned long tlclk_timer_data; static struct tlclk_alarms *alarm_events; @@ -197,10 +198,19 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id); static DECLARE_WAIT_QUEUE_HEAD(wq); +static unsigned long useflags; +static DEFINE_MUTEX(tlclk_mutex); + static int tlclk_open(struct inode *inode, struct file *filp) { int result; + if (test_and_set_bit(0, &useflags)) + return -EBUSY; + /* this legacy device is always one per system and it doesn't + * know how to handle multiple concurrent clients. + */ + /* Make sure there is no interrupt pending while * initialising interrupt handler */ inb(TLCLK_REG6); @@ -221,6 +231,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) static int tlclk_release(struct inode *inode, struct file *filp) { free_irq(telclk_interrupt, tlclk_interrupt); + clear_bit(0, &useflags); return 0; } @@ -230,26 +241,25 @@ static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, { if (count < sizeof(struct tlclk_alarms)) return -EIO; + if (mutex_lock_interruptible(&tlclk_mutex)) + return -EINTR; + wait_event_interruptible(wq, got_event); - if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) + if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) { + mutex_unlock(&tlclk_mutex); return -EFAULT; + } memset(alarm_events, 0, sizeof(struct tlclk_alarms)); got_event = 0; + mutex_unlock(&tlclk_mutex); return sizeof(struct tlclk_alarms); } -static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos) -{ - return 0; -} - static const struct file_operations tlclk_fops = { .read = tlclk_read, - .write = tlclk_write, .open = tlclk_open, .release = tlclk_release, @@ -540,7 +550,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); switch (val) { case CLK_8_592MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); break; case CLK_11_184MHz: SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); @@ -549,7 +559,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); break; case CLK_44_736MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); break; } } else @@ -839,11 +849,13 @@ static void __exit tlclk_cleanup(void) static void switchover_timeout(unsigned long data) { - if ((data & 1)) { - if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) + unsigned long flags = *(unsigned long *) data; + + if ((flags & 1)) { + if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) alarm_events->switchover_primary++; } else { - if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) + if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) alarm_events->switchover_secondary++; } @@ -901,8 +913,9 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id) /* TIMEOUT in ~10ms */ switchover_timer.expires = jiffies + msecs_to_jiffies(10); - switchover_timer.data = inb(TLCLK_REG1); - add_timer(&switchover_timer); + tlclk_timer_data = inb(TLCLK_REG1); + switchover_timer.data = (unsigned long) &tlclk_timer_data; + mod_timer(&switchover_timer, switchover_timer.expires); } else { got_event = 1; wake_up(&wq); -- cgit v1.2.3 From 3a7122923e87fc5cdf8affa1845924a0def4657d Mon Sep 17 00:00:00 2001 From: Jeff Chua Date: Mon, 22 Jan 2007 20:40:50 -0800 Subject: [PATCH] acpi: remove "video device notify" message Seems to be some left-over debug code. Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/video.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 36b37d755dbc..3d54680d0333 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1677,8 +1677,6 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; - - printk("video device notify\n"); if (!video_device) return; -- cgit v1.2.3 From 364ca8a897eadb2f0e76b7f0ffe94168f6d83d66 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 22 Jan 2007 23:01:06 +0900 Subject: [MIPS] Vr41xx: Fix after GENERIC_HARDIRQS_NO__DO_IRQ change Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/vr41xx/common/irq.c | 12 +++-- drivers/char/vr41xx_giu.c | 114 +++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 397ba94cd7ec..16decf4ac2f4 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -1,7 +1,7 @@ /* * Interrupt handing routines for NEC VR4100 series. * - * Copyright (C) 2005 Yoichi Yuasa + * Copyright (C) 2005-2007 Yoichi Yuasa * * 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 @@ -73,13 +73,19 @@ static void irq_dispatch(unsigned int irq) if (cascade->get_irq != NULL) { unsigned int source_irq = irq; desc = irq_desc + source_irq; - desc->chip->ack(source_irq); + if (desc->chip->mask_ack) + desc->chip->mask_ack(source_irq); + else { + desc->chip->mask(source_irq); + desc->chip->ack(source_irq); + } irq = cascade->get_irq(irq); if (irq < 0) atomic_inc(&irq_err_count); else irq_dispatch(irq); - desc->chip->end(source_irq); + if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) + desc->chip->unmask(source_irq); } else do_IRQ(irq); } diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index a744dad9cf45..0cea8d4907df 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -3,7 +3,7 @@ * * Copyright (C) 2002 MontaVista Software Inc. * Author: Yoichi Yuasa - * Copyright (C) 2003-2005 Yoichi Yuasa + * Copyright (C) 2003-2007 Yoichi Yuasa * * 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 @@ -125,30 +125,17 @@ static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) return data; } -static unsigned int startup_giuint_low_irq(unsigned int irq) +static void ack_giuint_low(unsigned int irq) { - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq); - giu_write(GIUINTSTATL, 1 << pin); - giu_set(GIUINTENL, 1 << pin); - - return 0; + giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static void shutdown_giuint_low_irq(unsigned int irq) +static void mask_giuint_low(unsigned int irq) { giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static void enable_giuint_low_irq(unsigned int irq) -{ - giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); -} - -#define disable_giuint_low_irq shutdown_giuint_low_irq - -static void ack_giuint_low_irq(unsigned int irq) +static void mask_ack_giuint_low(unsigned int irq) { unsigned int pin; @@ -157,46 +144,30 @@ static void ack_giuint_low_irq(unsigned int irq) giu_write(GIUINTSTATL, 1 << pin); } -static void end_giuint_low_irq(unsigned int irq) +static void unmask_giuint_low(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static struct hw_interrupt_type giuint_low_irq_type = { - .typename = "GIUINTL", - .startup = startup_giuint_low_irq, - .shutdown = shutdown_giuint_low_irq, - .enable = enable_giuint_low_irq, - .disable = disable_giuint_low_irq, - .ack = ack_giuint_low_irq, - .end = end_giuint_low_irq, +static struct irq_chip giuint_low_irq_chip = { + .name = "GIUINTL", + .ack = ack_giuint_low, + .mask = mask_giuint_low, + .mask_ack = mask_ack_giuint_low, + .unmask = unmask_giuint_low, }; -static unsigned int startup_giuint_high_irq(unsigned int irq) +static void ack_giuint_high(unsigned int irq) { - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; - giu_write(GIUINTSTATH, 1 << pin); - giu_set(GIUINTENH, 1 << pin); - - return 0; + giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static void shutdown_giuint_high_irq(unsigned int irq) +static void mask_giuint_high(unsigned int irq) { giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static void enable_giuint_high_irq(unsigned int irq) -{ - giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); -} - -#define disable_giuint_high_irq shutdown_giuint_high_irq - -static void ack_giuint_high_irq(unsigned int irq) +static void mask_ack_giuint_high(unsigned int irq) { unsigned int pin; @@ -205,20 +176,17 @@ static void ack_giuint_high_irq(unsigned int irq) giu_write(GIUINTSTATH, 1 << pin); } -static void end_giuint_high_irq(unsigned int irq) +static void unmask_giuint_high(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static struct hw_interrupt_type giuint_high_irq_type = { - .typename = "GIUINTH", - .startup = startup_giuint_high_irq, - .shutdown = shutdown_giuint_high_irq, - .enable = enable_giuint_high_irq, - .disable = disable_giuint_high_irq, - .ack = ack_giuint_high_irq, - .end = end_giuint_high_irq, +static struct irq_chip giuint_high_irq_chip = { + .name = "GIUINTH", + .ack = ack_giuint_high, + .mask = mask_giuint_high, + .mask_ack = mask_ack_giuint_high, + .unmask = unmask_giuint_high, }; static int giu_get_irq(unsigned int irq) @@ -282,9 +250,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ break; } } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_edge_irq); } else { giu_clear(GIUINTTYPL, mask); giu_clear(GIUINTHTSELL, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_level_irq); } giu_write(GIUINTSTATL, mask); } else if (pin < GIUINT_HIGH_MAX) { @@ -311,9 +285,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ break; } } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_edge_irq); } else { giu_clear(GIUINTTYPH, mask); giu_clear(GIUINTHTSELH, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_level_irq); } giu_write(GIUINTSTATH, mask); } @@ -617,10 +597,11 @@ static const struct file_operations gpio_fops = { static int __devinit giu_probe(struct platform_device *dev) { unsigned long start, size, flags = 0; - unsigned int nr_pins = 0; + unsigned int nr_pins = 0, trigger, i, pin; struct resource *res1, *res2 = NULL; void *base; - int retval, i; + struct irq_chip *chip; + int retval; switch (current_cpu_data.cputype) { case CPU_VR4111: @@ -688,11 +669,20 @@ static int __devinit giu_probe(struct platform_device *dev) giu_write(GIUINTENL, 0); giu_write(GIUINTENH, 0); + trigger = giu_read(GIUINTTYPH) << 16; + trigger |= giu_read(GIUINTTYPL); for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) - irq_desc[i].chip = &giuint_low_irq_type; + pin = GPIO_PIN_OF_IRQ(i); + if (pin < GIUINT_HIGH_OFFSET) + chip = &giuint_low_irq_chip; else - irq_desc[i].chip = &giuint_high_irq_type; + chip = &giuint_high_irq_chip; + + if (trigger & (1 << pin)) + set_irq_chip_and_handler(i, chip, handle_edge_irq); + else + set_irq_chip_and_handler(i, chip, handle_level_irq); + } return cascade_irq(GIUINT_IRQ, giu_get_irq); -- cgit v1.2.3 From c3ea6729feb304e0c3be74e8eca001215e78d1bc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 23 Jan 2007 12:25:08 +0000 Subject: [PATCH] funsoft: ktermios fix Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/serial/funsoft.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 31501c9361b9..2bebd63d5ed1 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c @@ -27,7 +27,7 @@ MODULE_DEVICE_TABLE(usb, id_table); static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { - struct termios t; + struct ktermios t; dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); -- cgit v1.2.3 From 0a3c4bdc1b197a7d37fc75643a68daf45fe0a7cc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 23 Jan 2007 12:25:08 +0000 Subject: [PATCH] horizon.c: missing __devinit Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/atm/horizon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 4dc10105d610..f96446c358ba 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1845,7 +1845,7 @@ static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) /********** initialise a card **********/ -static int __init hrz_init (hrz_dev * dev) { +static int __devinit hrz_init (hrz_dev * dev) { int onefivefive; u16 chan; -- cgit v1.2.3 From 4384247b6910df91049f8d0bbd5c1075898ac290 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 23 Jan 2007 12:25:08 +0000 Subject: [PATCH] s2io bogus memset memset() after kmalloc() on size * 8 would better be on size * 8, not just size; fixed by switching to kcalloc() - it's more idiomatic anyway. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/s2io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 250cdbeefdfd..1dd66b8ea0fa 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -556,10 +556,9 @@ static int init_shared_mem(struct s2io_nic *nic) } } - nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); + nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; - memset(nic->ufo_in_band_v, 0, size); /* Allocation and initialization of RXDs in Rings */ size = 0; -- cgit v1.2.3 From 3196265e97c661d9e9be04d5d64ca8ff3186536d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 23 Jan 2007 12:25:08 +0000 Subject: s2io bogus memset memset() after kmalloc() on size * 8 would better be on size * 8, not just size; fixed by switching to kcalloc() - it's more idiomatic anyway. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 250cdbeefdfd..1dd66b8ea0fa 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -556,10 +556,9 @@ static int init_shared_mem(struct s2io_nic *nic) } } - nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); + nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; - memset(nic->ufo_in_band_v, 0, size); /* Allocation and initialization of RXDs in Rings */ size = 0; -- cgit v1.2.3 From d344bff9c36db17dc4765215495aaa7212c1eb6c Mon Sep 17 00:00:00 2001 From: Dale Farnsworth Date: Tue, 23 Jan 2007 09:52:25 -0700 Subject: mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs This bug was found and isolated by Thibaut VARENE and Jarek Poplawski . This patch is a modification of their fixes. We acquire and release the lock for each descriptor that is freed to minimize the time the lock is held. Signed-off-by: Jeff Garzik --- drivers/net/mv643xx_eth.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c41ae4286eea..b3bf86422734 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -314,6 +314,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) while (mp->tx_desc_count > 0) { spin_lock_irqsave(&mp->lock, flags); + + /* tx_desc_count might have changed before acquiring the lock */ + if (mp->tx_desc_count <= 0) { + spin_unlock_irqrestore(&mp->lock, flags); + return released; + } + tx_index = mp->tx_used_desc_q; desc = &mp->p_tx_desc_area[tx_index]; cmd_sts = desc->cmd_sts; @@ -332,13 +339,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) if (skb) mp->tx_skb[tx_index] = NULL; - spin_unlock_irqrestore(&mp->lock, flags); - if (cmd_sts & ETH_ERROR_SUMMARY) { printk("%s: Error in TX\n", dev->name); mp->stats.tx_errors++; } + spin_unlock_irqrestore(&mp->lock, flags); + if (cmd_sts & ETH_TX_FIRST_DESC) dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); else -- cgit v1.2.3 From 65ebe63420eae40fba73d3b4f79f99adc8e148b3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 23 Jan 2007 11:38:57 -0800 Subject: [PATCH] email change for shemminger@osdl.org Change my email address to reflect OSDL merger. Signed-off-by: Stephen Hemminger [ The irony. Somebody still has his sign-off message hardcoded in a script or his brainstem ;^] Signed-off-by: Linus Torvalds --- MAINTAINERS | 6 +++--- drivers/net/irda/stir4200.c | 2 +- drivers/net/skge.c | 2 +- drivers/net/sky2.c | 2 +- net/ipv4/tcp_probe.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index b0e33617273d..d6f04a81f761 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1254,7 +1254,7 @@ S: Maintained ETHERNET BRIDGE P: Stephen Hemminger -M: shemminger@osdl.org +M: shemminger@linux-foundation.org L: bridge@osdl.org W: http://bridge.sourceforge.net/ S: Maintained @@ -2277,7 +2277,7 @@ S: Maintained NETEM NETWORK EMULATOR P: Stephen Hemminger -M: shemminger@osdl.org +M: shemminger@linux-foundation.org L: netem@osdl.org S: Maintained @@ -3081,7 +3081,7 @@ S: Maintained SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS P: Stephen Hemminger -M: shemminger@osdl.org +M: shemminger@linux-foundation.org L: netdev@vger.kernel.org S: Maintained diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index c14a74634fd5..20d306fea4cb 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -59,7 +59,7 @@ #include #include -MODULE_AUTHOR("Stephen Hemminger "); +MODULE_AUTHOR("Stephen Hemminger "); MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index deedfd5f8226..45283f3f95e4 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -60,7 +60,7 @@ #define LINK_HZ (HZ/2) MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); -MODULE_AUTHOR("Stephen Hemminger "); +MODULE_AUTHOR("Stephen Hemminger "); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a6601e8d423c..a2e804ddca6c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3691,6 +3691,6 @@ module_init(sky2_init_module); module_exit(sky2_cleanup_module); MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver"); -MODULE_AUTHOR("Stephen Hemminger "); +MODULE_AUTHOR("Stephen Hemminger "); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index f230eeecf092..41c157848181 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -30,7 +30,7 @@ #include -MODULE_AUTHOR("Stephen Hemminger "); +MODULE_AUTHOR("Stephen Hemminger "); MODULE_DESCRIPTION("TCP cwnd snooper"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 419dd8378dfa32985672ab7927b4bc827f33b332 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 23 Jan 2007 20:04:13 -0300 Subject: V4L/DVB (5123): Buf_qbuf: fix: videobuf_queue->stream corruption and lockup We are doing ->buf_prepare(buf) before adding buf to q->stream list. This means that videobuf_qbuf() should not try to re-add a STATE_PREPARED buffer. Signed-off-by: Oleg Nesterov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/video-buf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index 635d102c86f0..6504a5866849 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -700,6 +700,7 @@ videobuf_qbuf(struct videobuf_queue *q, goto done; } if (buf->state == STATE_QUEUED || + buf->state == STATE_PREPARED || buf->state == STATE_ACTIVE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; -- cgit v1.2.3 From 3958fb34ef18529c1e4a3eca44b7aaf94d4f4697 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 15 Jan 2007 19:37:25 -0800 Subject: [IrDA]: irda-usb TX path optimization (was Re: IrDA spams logfiles - since 2.6.19) Since we stop using dev_alloc_skb on the IrDA TX frame, we constantly run into the case of the skb headroom being 0, and thus we call skb_cow for every IrDA TX frame. This patch uses a local buffer and memcpy the skb to it, saving us a kmalloc for each of those IrDA TX frames. Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 43 ++++++++++++++++++++----------------------- drivers/net/irda/irda-usb.h | 1 + 2 files changed, 21 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 3ca1082ec776..80cbf3f80432 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -441,25 +441,13 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) goto drop; } - /* Make sure there is room for IrDA-USB header. The actual - * allocation will be done lower in skb_push(). - * Also, we don't use directly skb_cow(), because it require - * headroom >= 16, which force unnecessary copies - Jean II */ - if (skb_headroom(skb) < self->header_length) { - IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); - if (skb_cow(skb, self->header_length)) { - IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); - goto drop; - } - } + memcpy(self->tx_buff + self->header_length, skb->data, skb->len); /* Change setting for next frame */ - if (self->capability & IUC_STIR421X) { __u8 turnaround_time; - __u8* frame; + __u8* frame = self->tx_buff; turnaround_time = get_turnaround_time( skb ); - frame= skb_push(skb, self->header_length); irda_usb_build_header(self, frame, 0); frame[2] = turnaround_time; if ((skb->len != 0) && @@ -472,17 +460,17 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) frame[1] = 0; } } else { - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); + irda_usb_build_header(self, self->tx_buff, 0); } /* FIXME: Make macro out of this one */ ((struct irda_skb_cb *)skb->cb)->context = self; - usb_fill_bulk_urb(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), - skb->data, IRDA_SKB_MAX_MTU, + self->tx_buff, skb->len + self->header_length, write_bulk_callback, skb); - urb->transfer_buffer_length = skb->len; + /* This flag (URB_ZERO_PACKET) indicates that what we send is not * a continuous stream of data but separate packets. * In this case, the USB layer will insert an empty USB frame (TD) @@ -1455,6 +1443,9 @@ static inline void irda_usb_close(struct irda_usb_cb *self) /* Remove the speed buffer */ kfree(self->speed_buff); self->speed_buff = NULL; + + kfree(self->tx_buff); + self->tx_buff = NULL; } /********************** USB CONFIG SUBROUTINES **********************/ @@ -1753,9 +1744,14 @@ static int irda_usb_probe(struct usb_interface *intf, memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); + self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, + GFP_KERNEL); + if (self->tx_buff == NULL) + goto err_out_4; + ret = irda_usb_open(self); if (ret) - goto err_out_4; + goto err_out_5; IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); @@ -1766,14 +1762,14 @@ static int irda_usb_probe(struct usb_interface *intf, self->needspatch = (ret < 0); if (self->needspatch) { IRDA_ERROR("STIR421X: Couldn't upload patch\n"); - goto err_out_5; + goto err_out_6; } /* replace IrDA class descriptor with what patched device is now reporting */ irda_desc = irda_usb_find_class_desc (self->usbintf); if (irda_desc == NULL) { ret = -ENODEV; - goto err_out_5; + goto err_out_6; } if (self->irda_desc) kfree (self->irda_desc); @@ -1782,9 +1778,10 @@ static int irda_usb_probe(struct usb_interface *intf, } return 0; - -err_out_5: +err_out_6: unregister_netdev(self->netdev); +err_out_5: + kfree(self->tx_buff); err_out_4: kfree(self->speed_buff); err_out_3: diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 6b2271f18e77..e846c38224a3 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -156,6 +156,7 @@ struct irda_usb_cb { struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; char *speed_buff; /* Buffer for speed changes */ + char *tx_buff; struct timeval stamp; struct timeval now; -- cgit v1.2.3 From 8f1adb5f27d352c776ac34648cc277d1f8199dba Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 15 Jan 2007 19:40:34 -0800 Subject: [IrDA]: Removed incorrect IRDA_ASSERT() With USB2.0 bulk out MTU can be 512 bytes, so checking it only for 64 bytes is incorrect. Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 80cbf3f80432..340ee99652eb 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1515,8 +1515,6 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", __FUNCTION__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - /* Should be 8, 16, 32 or 64 bytes */ - IRDA_ASSERT(self->bulk_out_mtu == 64, ;); return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); } -- cgit v1.2.3 From 778a43fd626b710faca32038afc7460f314ba82a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 23 Jan 2007 21:16:40 -0800 Subject: [IRDA] vlsi_ir.{h,c}: remove kernel 2.4 code This patch removes kernel 2.4 compatibility code. Signed-off-by: Adrian Bunk Acked-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/vlsi_ir.c | 16 ++++++++-------- drivers/net/irda/vlsi_ir.h | 33 --------------------------------- 2 files changed, 8 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 18c68193bf14..e2b1af618450 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -166,7 +166,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) unsigned i; seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n", - PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); + pci_name(pdev), (int)pdev->vendor, (int)pdev->device); seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state); seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); @@ -1401,7 +1401,7 @@ static void vlsi_tx_timeout(struct net_device *ndev) if (vlsi_start_hw(idev)) IRDA_ERROR("%s: failed to restart hw - %s(%s) unusable!\n", - __FUNCTION__, PCIDEV_NAME(idev->pdev), ndev->name); + __FUNCTION__, pci_name(idev->pdev), ndev->name); else netif_start_queue(ndev); } @@ -1643,7 +1643,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->current_state = 0; /* hw must be running now */ IRDA_MESSAGE("%s: IrDA PCI controller %s detected\n", - drivername, PCIDEV_NAME(pdev)); + drivername, pci_name(pdev)); if ( !pci_resource_start(pdev,0) || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { @@ -1728,7 +1728,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); - IRDA_MESSAGE("%s: %s removed\n", drivername, PCIDEV_NAME(pdev)); + IRDA_MESSAGE("%s: %s removed\n", drivername, pci_name(pdev)); } #ifdef CONFIG_PM @@ -1748,7 +1748,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) if (!ndev) { IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } idev = ndev->priv; @@ -1759,7 +1759,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) pdev->current_state = state.event; } else - IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, PCIDEV_NAME(pdev), pdev->current_state, state.event); + IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, pci_name(pdev), pdev->current_state, state.event); up(&idev->sem); return 0; } @@ -1787,7 +1787,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) if (!ndev) { IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } idev = ndev->priv; @@ -1795,7 +1795,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) if (pdev->current_state == 0) { up(&idev->sem); IRDA_WARNING("%s - %s: already resumed\n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index c37f0bc4c7f9..2d3b773d8e35 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -41,39 +41,6 @@ #define PCI_CLASS_SUBCLASS_MASK 0xffff #endif -/* in recent 2.5 interrupt handlers have non-void return value */ -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -/* some stuff need to check kernelversion. Not all 2.5 stuff was present - * in early 2.5.x - the test is merely to separate 2.4 from 2.5 - */ -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -/* PDE() introduced in 2.5.4 */ -#ifdef CONFIG_PROC_FS -#define PDE(inode) ((inode)->i_private) -#endif - -/* irda crc16 calculation exported in 2.5.42 */ -#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) - -/* we use this for unified pci device name access */ -#define PCIDEV_NAME(pdev) ((pdev)->name) - -#else /* 2.5 or later */ - -/* whatever we get from the associated struct device - bus:slot:dev.fn id */ -#define PCIDEV_NAME(pdev) (pci_name(pdev)) - -#endif - /* ================================================================ */ /* non-standard PCI registers */ -- cgit v1.2.3 From 82490c0937cb455e7e4150455ff52e89a9fc5ab8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 23 Jan 2007 15:13:39 +0900 Subject: ahci: make ULi M5288 ignore interface fatal error bit As with JMicron controllers, ULi M5288 sets interface fatal error bit on device error including ATAPI CC. This makes libata hardreset the port on ATAPI CC thus making it impossible to use. Ignore interface fatal error bit on ULi M5288. This fixes bugzilla bug #7837. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b517d2493551..bd241767caea 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -361,7 +361,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */ { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */ - { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */ + { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */ { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ -- cgit v1.2.3 From f740d1689d91415cfc749d17138a11ed03b7d38b Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 23 Jan 2007 20:09:02 -0600 Subject: sata_nv: don't rely on NV_INT_DEV indication with ADMA Several people reported issues with certain drive commands timing out on sata_nv controllers running in ADMA mode. The commands in question were non-DMA-mapped commands, usually FLUSH CACHE or FLUSH CACHE EXT. From experimentation it appears that the NV_INT_DEV indication isn't always set when a legitimate command completion interrupt is received on a legacy-mode command, at least not on these controllers in ADMA mode. When a command is pending on the port, force the flag on always in the irq_stat value before calling nv_host_intr so that the drive busy state is always checked by ata_host_intr. This also fixes some questionable code in nv_host_intr which called ata_check_status when a command was pending and ata_host_intr returned "unhandled". If the device interrupted at just the wrong time this could cause interrupts to be lost. Signed-off-by: Robert Hancock Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index f6d498e1cf80..f7a963eb1f02 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -700,7 +700,6 @@ static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) static int nv_host_intr(struct ata_port *ap, u8 irq_stat) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - int handled; /* freeze if hotplugged */ if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) { @@ -719,13 +718,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) } /* handle interrupt */ - handled = ata_host_intr(ap, qc); - if (unlikely(!handled)) { - /* spurious, clear it */ - ata_check_status(ap); - } - - return 1; + return ata_host_intr(ap, qc); } static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) @@ -752,6 +745,11 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804) >> (NV_INT_PORT_SHIFT * i); + if(ata_tag_valid(ap->active_tag)) + /** NV_INT_DEV indication seems unreliable at times + at least in ADMA mode. Force it on always when a + command is active, to prevent losing interrupts. */ + irq_stat |= NV_INT_DEV; handled += nv_host_intr(ap, irq_stat); continue; } -- cgit v1.2.3 From 07c53dac4904206a50dd7c87adabbb1acff903fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 21 Jan 2007 02:10:11 +0900 Subject: ahci: don't enter slumber on power down Some ATA/ATAPI devices act weirdly after the link is put into slumber mode. Some hang completely requiring physical power removal while others fail to wake up till the link is hardreset a couple of times. The addition of slumber on power down was never driven by real need. It just followed what ahci spec said literally. The spec itself seems faulty in that it doesn't consider devices (not controllers) which don't support link powersaving mode. Theory never matches reality when it comes to dark allys of cheap ATA/ATAPI world. It's just unrealistic to expect vendors to test rarely used link powersaving feature rigorously. This patch makes ahci more friendly to the coldness of reality. This shouldn't have any negative effect - when suspend operation succeeds, we power off the whole machine; otherwise, we wake up everything. I can't see any reason to be so elaborate with powering down the link in the first place. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index bd241767caea..e3c7b312287a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -586,35 +586,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) { u32 cmd, scontrol; - cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; - - if (cap & HOST_CAP_SSC) { - /* enable transitions to slumber mode */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - if ((scontrol & 0x0f00) > 0x100) { - scontrol &= ~0xf00; - writel(scontrol, port_mmio + PORT_SCR_CTL); - } - - /* put device into slumber mode */ - writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); - - /* wait for the transition to complete */ - ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, - PORT_CMD_ICC_SLUMBER, 1, 50); - } + if (!(cap & HOST_CAP_SSS)) + return; - /* put device into listen mode */ - if (cap & HOST_CAP_SSS) { - /* first set PxSCTL.DET to 0 */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - scontrol &= ~0xf; - writel(scontrol, port_mmio + PORT_SCR_CTL); + /* put device into listen mode, first set PxSCTL.DET to 0 */ + scontrol = readl(port_mmio + PORT_SCR_CTL); + scontrol &= ~0xf; + writel(scontrol, port_mmio + PORT_SCR_CTL); - /* then set PxCMD.SUD to 0 */ - cmd &= ~PORT_CMD_SPIN_UP; - writel(cmd, port_mmio + PORT_CMD); - } + /* then set PxCMD.SUD to 0 */ + cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; + cmd &= ~PORT_CMD_SPIN_UP; + writel(cmd, port_mmio + PORT_CMD); } static void ahci_init_port(void __iomem *port_mmio, u32 cap, -- cgit v1.2.3 From 7a801184fa480e11e6431f184a5bdf31f63326fb Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 17 Jan 2007 12:32:12 -0600 Subject: libata: Fixup n_elem initialization Fixup the inialization of qc->n_elem. It currently gets initialized to 1 for commands that do not transfer any data. Fix this by initializing n_elem to 0 and only setting to 1 in ata_scsi_qc_new when there is data to transfer. This fixes some problems seen with SATA devices attached to ipr adapters. Signed-off-by: Brian King Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- include/linux/libata.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 836947da5b14..7cc5a4a910a4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -372,7 +372,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, if (cmd->use_sg) { qc->__sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; - } else { + } else if (cmd->request_bufflen) { qc->__sg = &qc->sgent; qc->n_elem = 1; } diff --git a/include/linux/libata.h b/include/linux/libata.h index e53a13ba7f78..65d318746ac6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1149,6 +1149,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->cursect = qc->cursg = qc->cursg_ofs = 0; qc->nsect = 0; qc->nbytes = qc->curbytes = 0; + qc->n_elem = 0; qc->err_mask = 0; ata_tf_init(qc->dev, &qc->tf); -- cgit v1.2.3 From a14d527306dc7dbc38e4607c3cc3a50a600fc98b Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Tue, 9 Jan 2007 09:03:42 +0100 Subject: [ARM] 4086/1: AT91: Whitespace cleanup A couple of whitespace cleanups, mainly in the AT91 header files. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200_devices.c | 2 +- drivers/serial/atmel_serial.c | 4 ++-- drivers/serial/atmel_serial.h | 2 +- include/asm-arm/arch-at91rm9200/at91_ecc.h | 8 ++++---- include/asm-arm/arch-at91rm9200/at91_pmc.h | 2 +- include/asm-arm/arch-at91rm9200/at91_rtc.h | 16 ++++++++-------- include/asm-arm/arch-at91rm9200/at91rm9200.h | 2 +- include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h | 2 +- include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h | 4 ++-- include/asm-arm/arch-at91rm9200/at91sam926x_mc.h | 8 ++++---- 10 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91rm9200/at91rm9200_devices.c index 4641b99db0ee..57fac7203fe4 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_devices.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_devices.c @@ -272,7 +272,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ /* nWAIT is _not_ a default setting */ - at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ cf_data = *data; platform_device_register(&at91rm9200_cf_device); diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index ed7f7209ea59..1f9222c2e656 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -689,9 +689,9 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct struct atmel_uart_data *data = pdev->dev.platform_data; port->iotype = UPIO_MEM; - port->flags = UPF_BOOT_AUTOCONF; + port->flags = UPF_BOOT_AUTOCONF; port->ops = &atmel_pops; - port->fifosize = 1; + port->fifosize = 1; port->line = pdev->id; port->dev = &pdev->dev; diff --git a/drivers/serial/atmel_serial.h b/drivers/serial/atmel_serial.h index fe1763b2a6d5..11b44360e108 100644 --- a/drivers/serial/atmel_serial.h +++ b/drivers/serial/atmel_serial.h @@ -106,7 +106,7 @@ #define ATMEL_US_CSR 0x14 /* Channel Status Register */ #define ATMEL_US_RHR 0x18 /* Receiver Holding Register */ #define ATMEL_US_THR 0x1c /* Transmitter Holding Register */ -#define ATMEL_US_SYNH (1 << 15) /* Transmit/Receive Sync [SAM9 only] */ +#define ATMEL_US_SYNH (1 << 15) /* Transmit/Receive Sync [AT91SAM9261 only] */ #define ATMEL_US_BRGR 0x20 /* Baud Rate Generator Register */ #define ATMEL_US_CD (0xffff << 0) /* Clock Divider */ diff --git a/include/asm-arm/arch-at91rm9200/at91_ecc.h b/include/asm-arm/arch-at91rm9200/at91_ecc.h index fddf256a98d3..5c564ede5c5d 100644 --- a/include/asm-arm/arch-at91rm9200/at91_ecc.h +++ b/include/asm-arm/arch-at91rm9200/at91_ecc.h @@ -14,7 +14,7 @@ #define AT91_ECC_H #define AT91_ECC_CR (AT91_ECC + 0x00) /* Control register */ -#define AT91_ECC_RST (1 << 0) /* Reset parity */ +#define AT91_ECC_RST (1 << 0) /* Reset parity */ #define AT91_ECC_MR (AT91_ECC + 0x04) /* Mode register */ #define AT91_ECC_PAGESIZE (3 << 0) /* Page Size */ @@ -23,16 +23,16 @@ #define AT91_ECC_PAGESIZE_2112 (2) #define AT91_ECC_PAGESIZE_4224 (3) -#define AT91_ECC_SR (AT91_ECC + 0x08) /* Status register */ +#define AT91_ECC_SR (AT91_ECC + 0x08) /* Status register */ #define AT91_ECC_RECERR (1 << 0) /* Recoverable Error */ #define AT91_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ #define AT91_ECC_MULERR (1 << 2) /* Multiple Errors */ -#define AT91_ECC_PR (AT91_ECC + 0x0c) /* Parity register */ +#define AT91_ECC_PR (AT91_ECC + 0x0c) /* Parity register */ #define AT91_ECC_BITADDR (0xf << 0) /* Bit Error Address */ #define AT91_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ -#define AT91_ECC_NPR (AT91_ECC + 0x10) /* NParity register */ +#define AT91_ECC_NPR (AT91_ECC + 0x10) /* NParity register */ #define AT91_ECC_NPARITY (0xffff << 0) /* NParity */ #endif diff --git a/include/asm-arm/arch-at91rm9200/at91_pmc.h b/include/asm-arm/arch-at91rm9200/at91_pmc.h index de8c3da74a01..c3b489d09b6c 100644 --- a/include/asm-arm/arch-at91rm9200/at91_pmc.h +++ b/include/asm-arm/arch-at91rm9200/at91_pmc.h @@ -61,7 +61,7 @@ #define AT91_PMC_CSS_PLLA (2 << 0) #define AT91_PMC_CSS_PLLB (3 << 0) #define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ -#define AT91_PMC_PRES_1 (0 << 2) +#define AT91_PMC_PRES_1 (0 << 2) #define AT91_PMC_PRES_2 (1 << 2) #define AT91_PMC_PRES_4 (2 << 2) #define AT91_PMC_PRES_8 (3 << 2) diff --git a/include/asm-arm/arch-at91rm9200/at91_rtc.h b/include/asm-arm/arch-at91rm9200/at91_rtc.h index 6e5065d56260..095fe0883102 100644 --- a/include/asm-arm/arch-at91rm9200/at91_rtc.h +++ b/include/asm-arm/arch-at91rm9200/at91_rtc.h @@ -21,21 +21,21 @@ #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ #define AT91_RTC_TIMEVSEL_MINUTE (0 << 8) -#define AT91_RTC_TIMEVSEL_HOUR (1 << 8) -#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8) -#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8) +#define AT91_RTC_TIMEVSEL_HOUR (1 << 8) +#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8) +#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8) #define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */ -#define AT91_RTC_CALEVSEL_WEEK (0 << 16) -#define AT91_RTC_CALEVSEL_MONTH (1 << 16) -#define AT91_RTC_CALEVSEL_YEAR (2 << 16) +#define AT91_RTC_CALEVSEL_WEEK (0 << 16) +#define AT91_RTC_CALEVSEL_MONTH (1 << 16) +#define AT91_RTC_CALEVSEL_YEAR (2 << 16) #define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ -#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ +#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ #define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ #define AT91_RTC_SEC (0x7f << 0) /* Current Second */ #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ -#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ +#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ #define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200.h b/include/asm-arm/arch-at91rm9200/at91rm9200.h index 4d51177efddd..c569b6a21a42 100644 --- a/include/asm-arm/arch-at91rm9200/at91rm9200.h +++ b/include/asm-arm/arch-at91rm9200/at91rm9200.h @@ -274,7 +274,7 @@ #define AT91_PD19_TPK7 (1 << 19) /* B: ETM Trace Packet Port 7 */ #define AT91_PD20_NPCS3 (1 << 20) /* A: SPI Peripheral Chip Select 3 */ #define AT91_PD20_TPK8 (1 << 20) /* B: ETM Trace Packet Port 8 */ -#define AT91_PD21_RTS0 (1 << 21) /* A: USART Ready To Send 0 */ +#define AT91_PD21_RTS0 (1 << 21) /* A: USART Ready To Send 0 */ #define AT91_PD21_TPK9 (1 << 21) /* B: ETM Trace Packet Port 9 */ #define AT91_PD22_RTS1 (1 << 22) /* A: USART Ready To Send 1 */ #define AT91_PD22_TPK10 (1 << 22) /* B: ETM Trace Packet Port 10 */ diff --git a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h b/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h index 746d973705bf..78f6b4917b8b 100644 --- a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h +++ b/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h @@ -58,7 +58,7 @@ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */ -#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) #define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ diff --git a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h b/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h index ab25f9e94d69..ec88efabbe6c 100644 --- a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h +++ b/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h @@ -43,8 +43,8 @@ #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ -#define AT91_MATRIX_CS1A_SMC (0 << 1) -#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS1A_SMC (0 << 1) +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) #define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ #define AT91_MATRIX_CS3A_SMC (0 << 3) #define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) diff --git a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h b/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h index 8ac797e39a14..972e7531c7f4 100644 --- a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h +++ b/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h @@ -33,14 +33,14 @@ #define AT91_SDRAMC_NC_9 (1 << 0) #define AT91_SDRAMC_NC_10 (2 << 0) #define AT91_SDRAMC_NC_11 (3 << 0) -#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ #define AT91_SDRAMC_NR_11 (0 << 2) #define AT91_SDRAMC_NR_12 (1 << 2) #define AT91_SDRAMC_NR_13 (2 << 2) -#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ #define AT91_SDRAMC_NB_2 (0 << 4) -#define AT91_SDRAMC_NB_4 (1 << 4) -#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91_SDRAMC_NB_4 (1 << 4) +#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ #define AT91_SDRAMC_CAS_1 (1 << 5) #define AT91_SDRAMC_CAS_2 (2 << 5) #define AT91_SDRAMC_CAS_3 (3 << 5) -- cgit v1.2.3 From 9b938166907558e664d8fa413e6233a36669e0c0 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Tue, 9 Jan 2007 13:20:54 +0100 Subject: [ARM] 4088/1: AT91: Unbalanced IRQ in serial driver suspend/resume This patch fixes the unbalanced calls to enable_irq_wake() and disable_irq_wake() in the AT91 (and AVR32) serial driver. It should resolve these kernel messages: Unbalanced IRQ x wake disable BUG: warning at kernel/irq/manage.c:167/set_irq_wake() Original patch from Marc Pignat. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- drivers/serial/atmel_serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 1f9222c2e656..881f886b91c6 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -890,7 +890,6 @@ static int atmel_serial_suspend(struct platform_device *pdev, pm_message_t state if (device_may_wakeup(&pdev->dev) && !at91_suspend_entering_slow_clock()) enable_irq_wake(port->irq); else { - disable_irq_wake(port->irq); uart_suspend_port(&atmel_uart, port); atmel_port->suspended = 1; } @@ -907,6 +906,8 @@ static int atmel_serial_resume(struct platform_device *pdev) uart_resume_port(&atmel_uart, port); atmel_port->suspended = 0; } + else + disable_irq_wake(port->irq); return 0; } -- cgit v1.2.3 From d28122a5877cc40350fa801353fd5a9350563ec3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 22 Jan 2007 18:59:42 +0000 Subject: [ARM] Fix AMBA serial drivers for non-first serial ports Using console=ttyAM1 or console=ttyAMA1 resulted in an oops during boot due to trying to drive the console before that port had been registered. Fix this by checking whether the port is present before allowing console setup to proceed. Signed-off-by: Russell King --- drivers/serial/amba-pl010.c | 2 ++ drivers/serial/amba-pl011.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 61db6973755a..f69bd097166e 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -589,6 +589,8 @@ static int __init pl010_console_setup(struct console *co, char *options) */ if (co->index >= UART_NR) co->index = 0; + if (!amba_ports[co->index]) + return -ENODEV; port = &amba_ports[co->index]->port; if (options) diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 9a3b374b2a08..44639e71372a 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -661,6 +661,8 @@ static int __init pl011_console_setup(struct console *co, char *options) if (co->index >= UART_NR) co->index = 0; uap = amba_ports[co->index]; + if (!uap) + return -ENODEV; uap->port.uartclk = clk_get_rate(uap->clk); -- cgit v1.2.3 From 6a40da02be1e1d74eee653c6d181934d35cbca7d Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:49:03 +0000 Subject: libata cmd64x: whack into a shape that looks like the documentation Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 15841a563694..449162cbf93e 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) { static const u8 udma_data[] = { - 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 + 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 }; static const u8 mwdma_data[] = { 0x30, 0x20, 0x10 @@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) pci_read_config_byte(pdev, pciD, ®D); pci_read_config_byte(pdev, pciU, ®U); - regD &= ~(0x20 << shift); - regU &= ~(0x35 << shift); + /* DMA bits off */ + regD &= ~(0x20 << adev->devno); + /* DMA control bits */ + regU &= ~(0x30 << shift); + /* DMA timing bits */ + regU &= ~(0x05 << adev->devno); - if (adev->dma_mode >= XFER_UDMA_0) + if (adev->dma_mode >= XFER_UDMA_0) { + /* Merge thge timing value */ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; - else + /* Merge the control bits */ + regU |= 1 << adev->devno; /* UDMA on */ + if (adev->dma_mode > 2) /* 15nS timing */ + regU |= 4 << adev->devno; + } else regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; regD |= 0x20 << adev->devno; @@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 dma_intr; - int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - int dma_mask = ap->port_no ? ARTTIM2 : CFR; + int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; + int dma_reg = ap->port_no ? ARTTIM2 : CFR; ata_bmdma_stop(qc); -- cgit v1.2.3 From a52865c239b1bc4f62e387509b1ad3415e476ee5 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:51:38 +0000 Subject: libata hpt3xn: Hopefully sort out the DPLL logic versus the vendor code Rather than ending up with two layers of negation jut rename the variable and lose one. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt3x2n.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index f6817b4093a4..886fab9aa62c 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.3.2" enum { HPT_PCI_FAST = (1 << 31), @@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap) return 0; } -static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) +static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) { long flags = (long)ap->host->private_data; /* See if we should use the DPLL */ - if (reading == 0) + if (writing) return USE_DPLL; /* Needed for write */ if (flags & PCI66) return USE_DPLL; /* Needed at 66Mhz */ -- cgit v1.2.3 From b229a7b0aed808f2ef6a5e9dbf78b0f17cefb4d0 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:47:07 +0000 Subject: libata: set_mode, Fix the FIXME When set_mode() changed ->set_mode didn't adapt. This makes the needed changes and removes the relevant FIXME case. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 6 ++++-- drivers/ata/libata-core.c | 14 ++------------ drivers/ata/pata_it821x.c | 4 +++- drivers/ata/pata_ixp4xx_cf.c | 5 +++-- drivers/ata/pata_legacy.c | 4 +++- drivers/ata/pata_rz1000.c | 6 ++++-- include/linux/libata.h | 4 ++-- 7 files changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 908751d27e76..24af56081b5d 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap) /** * generic_set_mode - mode setting * @ap: interface to set up + * @unused: returned device on error * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -71,7 +72,7 @@ static void generic_error_handler(struct ata_port *ap) * and respect them. */ -static void generic_set_mode(struct ata_port *ap) +static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -82,7 +83,7 @@ static void generic_set_mode(struct ata_port *ap) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; @@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap) } } } + return 0; } static struct scsi_host_template generic_sht = { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0d51d13b16bf..a388a8df0043 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2431,18 +2431,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) int i, rc = 0, used_dma = 0, found = 0; /* has private set_mode? */ - if (ap->ops->set_mode) { - /* FIXME: make ->set_mode handle no device case and - * return error code and failing device on failure. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (ata_dev_ready(&ap->device[i])) { - ap->ops->set_mode(ap); - break; - } - } - return 0; - } + if (ap->ops->set_mode) + return ap->ops->set_mode(ap, r_failed_dev); /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 0b56ff3d1cfe..e8afd486434a 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) /** * it821x_smart_set_mode - mode setting * @ap: interface to set up + * @unused: device that failed (error only) * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) * and respect them. */ -static void it821x_smart_set_mode(struct ata_port *ap) +static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap) } } } + return 0; } /** diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index cb8924109f59..23b8aab3ebd8 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -23,9 +23,9 @@ #include #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.1ac1" -static void ixp4xx_set_mode(struct ata_port *ap) +static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) { int i; @@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void ixp4xx_phy_reset(struct ata_port *ap) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index e7bf9d89c8ee..581cb33c6f45 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ /** * legacy_set_mode - mode setting * @ap: IDE interface + * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned. * @@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ * expand on this as per hdparm in the base kernel. */ -static void legacy_set_mode(struct ata_port *ap) +static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static struct scsi_host_template legacy_sht = { diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index adf4cc134f25..cec0729225e1 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap) /** * rz1000_set_mode - mode setting function * @ap: ATA interface + * @unused: returned device on set_mode failure * * Use a non standard set_mode function. We don't want to be tuned. We * would prefer to be BIOS generic but for the fact our hardware is * whacked out. */ -static void rz1000_set_mode(struct ata_port *ap) +static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; @@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } diff --git a/include/linux/libata.h b/include/linux/libata.h index f7f268e38749..df76fc467816 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -612,11 +612,11 @@ struct ata_port_operations { void (*dev_select)(struct ata_port *ap, unsigned int device); void (*phy_reset) (struct ata_port *ap); /* obsolete */ - void (*set_mode) (struct ata_port *ap); + int (*set_mode) (struct ata_port *ap, struct ata_device **r_failed_dev); void (*post_set_mode) (struct ata_port *ap); - int (*check_atapi_dma) (struct ata_queued_cmd *qc); + int (*check_atapi_dma) (struct ata_queued_cmd *qc); void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); -- cgit v1.2.3 From 767fe7877c2928b5633992ee60a49ad4516dc2af Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 24 Jan 2007 23:05:07 +0100 Subject: HID: fix memleaking of collection hid_free_device() doesn't free device->collection (but it does free device->rdesc and device itself). This imposes memory leak. Fix it. Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8cf50fcd64d..49f18f5b2514 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -543,6 +543,7 @@ void hid_free_device(struct hid_device *device) } kfree(device->rdesc); + kfree(device->collection); kfree(device); } EXPORT_SYMBOL_GPL(hid_free_device); -- cgit v1.2.3 From ad2905f06512c70c44a7efd178536ad197c48528 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 23 Jan 2007 14:02:53 +0100 Subject: USB HID: fix hid_blacklist clash for 0x08ca/0x0010 commit d8c8a393166d6283003fb111d0b4a40931c0eda4 introduced a clash in hid_blacklist for 0x08ca/0x0010 (GTCO vs. AIPTEK). As the vendor of GTCO device doesn't seem to be interested in supporting their legacy HW with this conflicting ids, it is OK to remove it. Signed-off-by: Jiri Kosina --- drivers/usb/input/hid-core.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index ea3636d96e1b..b86480457a2c 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -582,7 +582,6 @@ void usbhid_init_reports(struct hid_device *hid) } #define USB_VENDOR_ID_GTCO 0x078c -#define USB_VENDOR_ID_GTCO_IPANEL_1 0x08ca #define USB_VENDOR_ID_GTCO_IPANEL_2 0x5543 #define USB_DEVICE_ID_GTCO_90 0x0090 #define USB_DEVICE_ID_GTCO_100 0x0100 @@ -629,7 +628,6 @@ void usbhid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_GTCO_1004 0x1004 #define USB_DEVICE_ID_GTCO_1005 0x1005 #define USB_DEVICE_ID_GTCO_1006 0x1006 -#define USB_DEVICE_ID_GTCO_10 0x0010 #define USB_DEVICE_ID_GTCO_8 0x0008 #define USB_DEVICE_ID_GTCO_d 0x000d @@ -883,7 +881,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO_IPANEL_1, USB_DEVICE_ID_GTCO_10, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, -- cgit v1.2.3 From 8eda232e226b97c8f2fcbc5f672135247c1ee348 Mon Sep 17 00:00:00 2001 From: Simon Bennett Date: Wed, 24 Jan 2007 10:27:20 +0100 Subject: HID: fix hid-input mapping for Firefly Mini Remote Control Patch adds entries to the HID consumer page for the Firefly Mini IR remote control Signed-off-by: Simon Bennett Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9cf591a1bda3..981fcf01d41b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -431,6 +431,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x040: map_key_clear(KEY_MENU); break; case 0x045: map_key_clear(KEY_RADIO); break; + case 0x083: map_key_clear(KEY_LAST); break; case 0x088: map_key_clear(KEY_PC); break; case 0x089: map_key_clear(KEY_TV); break; case 0x08a: map_key_clear(KEY_WWW); break; @@ -448,6 +449,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x096: map_key_clear(KEY_TAPE); break; case 0x097: map_key_clear(KEY_TV2); break; case 0x098: map_key_clear(KEY_SAT); break; + case 0x09a: map_key_clear(KEY_PVR); break; case 0x09c: map_key_clear(KEY_CHANNELUP); break; case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; -- cgit v1.2.3 From 17234246eb82898cf98e3c29e81d941c738e0587 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 20:46:59 +0900 Subject: sata_via: don't diddle with ATA_NIEN in ->freeze vt6420 completely loses its ability to raise IRQ for ATAPI devices if ATA_NIEN is diddled with in ->freeze. Further investigation is necessary to determine whether this problem is shared on other controllers but it doesn't seem to be at this point. Make vt6420's ->freeze only clear IRQ to fix this problem. This makes vt6420 relatively more prone to IRQ storms but the controller is way too braindamaged to worry about that anyway. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 88f0565c8883..55b01236a6f0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -74,6 +74,7 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { @@ -128,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, + .freeze = svia_noop_freeze, .thaw = ata_bmdma_thaw, .error_handler = vt6420_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, @@ -204,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } +static void svia_noop_freeze(struct ata_port *ap) +{ + /* Some VIA controllers choke if ATA_NIEN is manipulated in + * certain way. Leave it alone and just clear pending IRQ. + */ + ata_chk_status(ap); + ap->ops->irq_clear(ap); +} + /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port -- cgit v1.2.3 From 0291f95fdb5fcd91cc077aafabea2c5b109fa8a8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 19:16:28 +0900 Subject: ahci: improve and limit spurious interrupt messages, take#3 We're still seeing a lot of issues with NCQ implementation in drive firmwares. Sprious FISes during NCQ command phase occur on many drives and some of them seem potentially dangerous (at least to me). Until we find the solution, spurious messages can give us more info. Improve and limit them such that more info can be reported while not disturbing users too much. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e3c7b312287a..2fe5a58195de 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -75,6 +75,7 @@ enum { AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ + RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ board_ahci = 0, @@ -202,6 +203,10 @@ struct ahci_port_priv { dma_addr_t cmd_tbl_dma; void *rx_fis; dma_addr_t rx_fis_dma; + /* for NCQ spurious interrupt analysis */ + int ncq_saw_spurious_sdb_cnt; + unsigned int ncq_saw_d2h:1; + unsigned int ncq_saw_dmas:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -1109,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap) void __iomem *mmio = ap->host->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); struct ata_eh_info *ehi = &ap->eh_info; + struct ahci_port_priv *pp = ap->private_data; u32 status, qc_active; - int rc; + int rc, known_irq = 0; status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); @@ -1137,17 +1143,52 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ - /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) + /* if !NCQ, ignore. No modern ATA device has broken HSM + * implementation for non-NCQ commands. + */ + if (!ap->sactive) return; - /* ignore interim PIO setup fis interrupts */ - if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) - return; + if (status & PORT_IRQ_D2H_REG_FIS) { + if (!pp->ncq_saw_d2h) + ata_port_printk(ap, KERN_INFO, + "D2H reg with I during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_d2h = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_DMAS_FIS) { + if (!pp->ncq_saw_dmas) + ata_port_printk(ap, KERN_INFO, + "DMAS FIS during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_dmas = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_SDB_FIS && + pp->ncq_saw_spurious_sdb_cnt < 10) { + /* SDB FIS containing spurious completions might be + * dangerous, we need to know more about them. Print + * more of it. + */ + const u32 *f = pp->rx_fis + RX_FIS_SDB; + + ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", + readl(port_mmio + PORT_CMD_ISSUE), + readl(port_mmio + PORT_SCR_ACT), f[0], f[1], + pp->ncq_saw_spurious_sdb_cnt < 10 ? + "" : ", shutting up"); + + pp->ncq_saw_spurious_sdb_cnt++; + known_irq = 1; + } - if (ata_ratelimit()) + if (!known_irq) ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", + "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n", status, ap->active_tag, ap->sactive); } -- cgit v1.2.3 From b2a8bbe67d73631c71492fd60b757fc50a87f182 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 19:40:05 +0900 Subject: libata: implement ATA_FLAG_IGN_SIMPLEX and use it in sata_uli Some uli controllers have stuck SIMPLEX bit which can't be cleared with ata_pci_clear_simplex(), but the controller is capable of doing DMAs on both channels simultaneously. Implement ATA_FLAG_IGN_SIMPLEX which makes libata ignore the simplex bit and use it in sata_uli. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 12 ++++++++---- drivers/ata/sata_uli.c | 3 ++- include/linux/libata.h | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 623cec914c9b..114fa81deb83 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -870,7 +870,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; bmdma = pci_resource_start(pdev, 4); if (bmdma) { - if (inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -886,7 +887,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int bmdma = pci_resource_start(pdev, 4); if (bmdma) { bmdma += 8; - if(inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -920,7 +922,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; if (bmdma) { probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) + if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[0]); @@ -937,7 +940,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; if (bmdma) { probe_ent->port[1].bmdma_addr = bmdma + 8; - if (inb(bmdma + 10) & 0x80) + if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 10) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[1]); diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 5c603ca3a50a..a43aec62d505 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = { static struct ata_port_info uli_port_info = { .sht = &uli_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &uli_ops, diff --git a/include/linux/libata.h b/include/linux/libata.h index df76fc467816..22aa69e20905 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -177,6 +177,7 @@ enum { * Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ + ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be -- cgit v1.2.3 From 61dd08c6c8d2b4ede530e43c01fa72f789ef65b1 Mon Sep 17 00:00:00 2001 From: Alan Date: Thu, 25 Jan 2007 15:09:05 +0000 Subject: libata-sff: Don't call bmdma_stop on non DMA capable controllers Fixes bogus accesses to ports 0-15 with a non DMA capable controller. This I think should go in for 2.6.20 Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 114fa81deb83..942aeba2940a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -827,7 +827,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) */ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) { - ata_bmdma_stop(qc); + if (qc->ap->ioaddr.bmdma_addr) + ata_bmdma_stop(qc); } #ifdef CONFIG_PCI -- cgit v1.2.3 From 24cb230b587cf3aad8794b150682d8d8303a2120 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 25 Jan 2007 15:49:56 -0800 Subject: [BNX2]: Fix 2nd port's MAC address. On the 5709, we need to add the proper offset to calculate the shared memory base address of the 2nd port correctly. Otherwise, the 2nd port's MAC address and other information will be the same as the 1st port. Update version to 1.5.4. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ca5acc4736df..953808efe551 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.3" -#define DRV_MODULE_RELDATE "January 8, 2007" +#define DRV_MODULE_VERSION "1.5.4" +#define DRV_MODULE_RELDATE "January 24, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -5845,9 +5845,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == - BNX2_SHM_HDR_SIGNATURE_SIG) - bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); - else + BNX2_SHM_HDR_SIGNATURE_SIG) { + u32 off = PCI_FUNC(pdev->devfn) << 2; + + bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0 + off); + } else bp->shmem_base = HOST_VIEW_SHMEM_BASE; /* Get the permanent MAC address. First we need to make sure the -- cgit v1.2.3 From bce66ca4a2f695509e1b021311eb4de1e4fdf3e4 Mon Sep 17 00:00:00 2001 From: Leonard Norrgard Date: Fri, 26 Jan 2007 00:56:38 -0800 Subject: [PATCH] KVM: SVM: Fix SVM idt confusion There's an obvious typo in svm_{get,set}_idt, causing it to access the ldt instead. Because these functions are only called for save/load on AMD, the bug does not impact normal operation. With the fix, save/load works as expected on AMD hosts. Signed-off-by: Uri Lublin Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/svm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 7397bfbbcb1c..717aabb012cc 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -680,14 +680,14 @@ static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - dt->limit = vcpu->svm->vmcb->save.ldtr.limit; - dt->base = vcpu->svm->vmcb->save.ldtr.base; + dt->limit = vcpu->svm->vmcb->save.idtr.limit; + dt->base = vcpu->svm->vmcb->save.idtr.base; } static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - vcpu->svm->vmcb->save.ldtr.limit = dt->limit; - vcpu->svm->vmcb->save.ldtr.base = dt->base ; + vcpu->svm->vmcb->save.idtr.limit = dt->limit; + vcpu->svm->vmcb->save.idtr.base = dt->base ; } static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) -- cgit v1.2.3 From 6f00e68f210c0407dd666743ce61ae543cfd509d Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 26 Jan 2007 00:56:40 -0800 Subject: [PATCH] KVM: Emulate IA32_MISC_ENABLE msr This allows netbsd 3.1 i386 to get further along installing. Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/kvm.h | 1 + drivers/kvm/kvm_main.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 91e0c75aca8f..2db1ca4c6800 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -242,6 +242,7 @@ struct kvm_vcpu { u64 pdptrs[4]; /* pae */ u64 shadow_efer; u64 apic_base; + u64 ia32_misc_enable_msr; int nmsrs; struct vmx_msr_entry *guest_msrs; struct vmx_msr_entry *host_msrs; diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index be4651abe72c..b10972ed0c9f 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -1226,6 +1226,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_APICBASE: data = vcpu->apic_base; break; + case MSR_IA32_MISC_ENABLE: + data = vcpu->ia32_misc_enable_msr; + break; #ifdef CONFIG_X86_64 case MSR_EFER: data = vcpu->shadow_efer; @@ -1297,6 +1300,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_APICBASE: vcpu->apic_base = data; break; + case MSR_IA32_MISC_ENABLE: + vcpu->ia32_misc_enable_msr = data; + break; default: printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); return 1; @@ -1600,6 +1606,10 @@ static u32 msrs_to_save[] = { static unsigned num_msrs_to_save; +static u32 emulated_msrs[] = { + MSR_IA32_MISC_ENABLE, +}; + static __init void kvm_init_msr_list(void) { u32 dummy[2]; @@ -1925,7 +1935,7 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) goto out; n = msr_list.nmsrs; - msr_list.nmsrs = num_msrs_to_save; + msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) goto out; r = -E2BIG; @@ -1935,6 +1945,11 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_to_user(user_msr_list->indices, &msrs_to_save, num_msrs_to_save * sizeof(u32))) goto out; + if (copy_to_user(user_msr_list->indices + + num_msrs_to_save * sizeof(u32), + &emulated_msrs, + ARRAY_SIZE(emulated_msrs) * sizeof(u32))) + goto out; r = 0; break; } -- cgit v1.2.3 From 7993ba43db1c07245ada067791f91dbf018095ac Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 26 Jan 2007 00:56:41 -0800 Subject: [PATCH] KVM: MMU: Perform access checks in walk_addr() Check pte permission bits in walk_addr(), instead of scattering the checks all over the code. This has the following benefits: 1. We no longer set the accessed bit for accessed which fail permission checks. 2. Setting the accessed bit is simplified. 3. Under some circumstances, we used to pretend a page fault was fixed when it would actually fail the access checks. This caused an unnecessary vmexit. 4. The error code for guest page faults is now correct. The fix helps netbsd further along booting, and allows kvm to pass the new mmu testsuite. Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/mmu.c | 10 ------- drivers/kvm/paging_tmpl.h | 68 ++++++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index c6f972914f08..a05d0609d918 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -992,16 +992,6 @@ static inline int fix_read_pf(u64 *shadow_ent) return 0; } -static int may_access(u64 pte, int write, int user) -{ - - if (user && !(pte & PT_USER_MASK)) - return 0; - if (write && !(pte & PT_WRITABLE_MASK)) - return 0; - return 1; -} - static void paging_free(struct kvm_vcpu *vcpu) { nonpaging_free(vcpu); diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 6bc41950fbb3..afcd2a8f45bb 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -63,13 +63,15 @@ struct guest_walker { pt_element_t *ptep; pt_element_t inherited_ar; gfn_t gfn; + u32 error_code; }; /* * Fetch a guest pte for a guest virtual address */ -static void FNAME(walk_addr)(struct guest_walker *walker, - struct kvm_vcpu *vcpu, gva_t addr) +static int FNAME(walk_addr)(struct guest_walker *walker, + struct kvm_vcpu *vcpu, gva_t addr, + int write_fault, int user_fault) { hpa_t hpa; struct kvm_memory_slot *slot; @@ -86,7 +88,7 @@ static void FNAME(walk_addr)(struct guest_walker *walker, walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; root = *walker->ptep; if (!(root & PT_PRESENT_MASK)) - return; + goto not_present; --walker->level; } #endif @@ -111,11 +113,18 @@ static void FNAME(walk_addr)(struct guest_walker *walker, ASSERT(((unsigned long)walker->table & PAGE_MASK) == ((unsigned long)ptep & PAGE_MASK)); - if (is_present_pte(*ptep) && !(*ptep & PT_ACCESSED_MASK)) - *ptep |= PT_ACCESSED_MASK; - if (!is_present_pte(*ptep)) - break; + goto not_present; + + if (write_fault && !is_writeble_pte(*ptep)) + if (user_fault || is_write_protection(vcpu)) + goto access_error; + + if (user_fault && !(*ptep & PT_USER_MASK)) + goto access_error; + + if (!(*ptep & PT_ACCESSED_MASK)) + *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ if (walker->level == PT_PAGE_TABLE_LEVEL) { walker->gfn = (*ptep & PT_BASE_ADDR_MASK) @@ -146,6 +155,21 @@ static void FNAME(walk_addr)(struct guest_walker *walker, } walker->ptep = ptep; pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); + return 1; + +not_present: + walker->error_code = 0; + goto err; + +access_error: + walker->error_code = PFERR_PRESENT_MASK; + +err: + if (write_fault) + walker->error_code |= PFERR_WRITE_MASK; + if (user_fault) + walker->error_code |= PFERR_USER_MASK; + return 0; } static void FNAME(release_walker)(struct guest_walker *walker) @@ -347,7 +371,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code) { int write_fault = error_code & PFERR_WRITE_MASK; - int pte_present = error_code & PFERR_PRESENT_MASK; int user_fault = error_code & PFERR_USER_MASK; struct guest_walker walker; u64 *shadow_pte; @@ -365,19 +388,19 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * Look up the shadow pte for the faulting address. */ - FNAME(walk_addr)(&walker, vcpu, addr); - shadow_pte = FNAME(fetch)(vcpu, addr, &walker); + r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault); /* * The page is not mapped by the guest. Let the guest handle it. */ - if (!shadow_pte) { - pgprintk("%s: not mapped\n", __FUNCTION__); - inject_page_fault(vcpu, addr, error_code); + if (!r) { + pgprintk("%s: guest page fault\n", __FUNCTION__); + inject_page_fault(vcpu, addr, walker.error_code); FNAME(release_walker)(&walker); return 0; } + shadow_pte = FNAME(fetch)(vcpu, addr, &walker); pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, shadow_pte, *shadow_pte); @@ -399,22 +422,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, * mmio: emulate if accessible, otherwise its a guest fault. */ if (is_io_pte(*shadow_pte)) { - if (may_access(*shadow_pte, write_fault, user_fault)) - return 1; - pgprintk("%s: io work, no access\n", __FUNCTION__); - inject_page_fault(vcpu, addr, - error_code | PFERR_PRESENT_MASK); - kvm_mmu_audit(vcpu, "post page fault (io)"); - return 0; - } - - /* - * pte not present, guest page fault. - */ - if (pte_present && !fixed && !write_pt) { - inject_page_fault(vcpu, addr, error_code); - kvm_mmu_audit(vcpu, "post page fault (guest)"); - return 0; + return 1; } ++kvm_stat.pf_fixed; @@ -429,7 +437,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) pt_element_t guest_pte; gpa_t gpa; - FNAME(walk_addr)(&walker, vcpu, vaddr); + FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0); guest_pte = *walker.ptep; FNAME(release_walker)(&walker); -- cgit v1.2.3 From 73b1087e6176a34c01eea3db269848f72fad72c1 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 26 Jan 2007 00:56:41 -0800 Subject: [PATCH] KVM: MMU: Report nx faults to the guest With the recent guest page fault change, we perform access checks on our own instead of relying on the cpu. This means we have to perform the nx checks as well. Software like the google toolbar on windows appears to rely on this somehow. Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/mmu.c | 6 ++++++ drivers/kvm/paging_tmpl.h | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index a05d0609d918..22c426cd8cb2 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -143,6 +143,7 @@ static int dbg = 1; #define PFERR_PRESENT_MASK (1U << 0) #define PFERR_WRITE_MASK (1U << 1) #define PFERR_USER_MASK (1U << 2) +#define PFERR_FETCH_MASK (1U << 4) #define PT64_ROOT_LEVEL 4 #define PT32_ROOT_LEVEL 2 @@ -168,6 +169,11 @@ static int is_cpuid_PSE36(void) return 1; } +static int is_nx(struct kvm_vcpu *vcpu) +{ + return vcpu->shadow_efer & EFER_NX; +} + static int is_present_pte(unsigned long pte) { return pte & PT_PRESENT_MASK; diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index afcd2a8f45bb..149fa45fd9a5 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -71,7 +71,7 @@ struct guest_walker { */ static int FNAME(walk_addr)(struct guest_walker *walker, struct kvm_vcpu *vcpu, gva_t addr, - int write_fault, int user_fault) + int write_fault, int user_fault, int fetch_fault) { hpa_t hpa; struct kvm_memory_slot *slot; @@ -123,6 +123,11 @@ static int FNAME(walk_addr)(struct guest_walker *walker, if (user_fault && !(*ptep & PT_USER_MASK)) goto access_error; +#if PTTYPE == 64 + if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK)) + goto access_error; +#endif + if (!(*ptep & PT_ACCESSED_MASK)) *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ @@ -169,6 +174,8 @@ err: walker->error_code |= PFERR_WRITE_MASK; if (user_fault) walker->error_code |= PFERR_USER_MASK; + if (fetch_fault) + walker->error_code |= PFERR_FETCH_MASK; return 0; } @@ -372,6 +379,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, { int write_fault = error_code & PFERR_WRITE_MASK; int user_fault = error_code & PFERR_USER_MASK; + int fetch_fault = error_code & PFERR_FETCH_MASK; struct guest_walker walker; u64 *shadow_pte; int fixed; @@ -388,7 +396,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * Look up the shadow pte for the faulting address. */ - r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault); + r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, + fetch_fault); /* * The page is not mapped by the guest. Let the guest handle it. @@ -437,7 +446,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) pt_element_t guest_pte; gpa_t gpa; - FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0); + FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); guest_pte = *walker.ptep; FNAME(release_walker)(&walker); -- cgit v1.2.3 From 46fe4ddd9dbb15305ab9b458e6cfa4dd47ac3e47 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 26 Jan 2007 00:56:42 -0800 Subject: [PATCH] KVM: SVM: Propagate cpu shutdown events to userspace This patch implements forwarding of SHUTDOWN intercepts from the guest on to userspace on AMD SVM. A SHUTDOWN event occurs when the guest produces a triple fault (e.g. on reboot). This also fixes the bug that a guest reboot actually causes a host reboot under some circumstances. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/svm.c | 15 +++++++++++++++ include/linux/kvm.h | 1 + 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 717aabb012cc..9c70ff65e6b7 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -502,6 +502,7 @@ static void init_vmcb(struct vmcb *vmcb) (1ULL << INTERCEPT_IOIO_PROT) | (1ULL << INTERCEPT_MSR_PROT) | (1ULL << INTERCEPT_TASK_SWITCH) | + (1ULL << INTERCEPT_SHUTDOWN) | (1ULL << INTERCEPT_VMRUN) | (1ULL << INTERCEPT_VMMCALL) | (1ULL << INTERCEPT_VMLOAD) | @@ -892,6 +893,19 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } +static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + /* + * VMCB is undefined after a SHUTDOWN intercept + * so reinitialize it. + */ + memset(vcpu->svm->vmcb, 0, PAGE_SIZE); + init_vmcb(vcpu->svm->vmcb); + + kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; + return 0; +} + static int io_get_override(struct kvm_vcpu *vcpu, struct vmcb_seg **seg, int *addr_override) @@ -1249,6 +1263,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_IOIO] = io_interception, [SVM_EXIT_MSR] = msr_interception, [SVM_EXIT_TASK_SWITCH] = task_switch_interception, + [SVM_EXIT_SHUTDOWN] = shutdown_interception, [SVM_EXIT_VMRUN] = invalid_op_interception, [SVM_EXIT_VMMCALL] = invalid_op_interception, [SVM_EXIT_VMLOAD] = invalid_op_interception, diff --git a/include/linux/kvm.h b/include/linux/kvm.h index bc8b4616bad7..1be148f0fce4 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -46,6 +46,7 @@ enum kvm_exit_reason { KVM_EXIT_HLT = 5, KVM_EXIT_MMIO = 6, KVM_EXIT_IRQ_WINDOW_OPEN = 7, + KVM_EXIT_SHUTDOWN = 8, }; /* for KVM_RUN */ -- cgit v1.2.3 From 8736b9270c2f8993ca44c30f64d4c6d25e379687 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 26 Jan 2007 00:56:43 -0800 Subject: [PATCH] S3C24XX: fix passing spi chipselect to select routine It turns out that the spi chipselect was not being passed to the set_cs routine if one was specified in the platform data. As part of the fix, change to using a set_cs field in the controller state, and put a default gpio routine in if the data passed does not specify it. Also remove the //#define DEBUG Signed-off-by: Ben Dooks Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi_s3c24xx.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 8ca08713528e..651379c51ae6 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -10,9 +10,6 @@ * */ - -//#define DEBUG - #include #include #include @@ -44,6 +41,9 @@ struct s3c24xx_spi { int len; int count; + int (*set_cs)(struct s3c2410_spi_info *spi, + int cs, int pol); + /* data buffers */ const unsigned char *tx; unsigned char *rx; @@ -64,6 +64,11 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) return spi_master_get_devdata(sdev->master); } +static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) +{ + s3c2410_gpio_setpin(spi->pin_cs, pol); +} + static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) { struct s3c24xx_spi *hw = to_hw(spi); @@ -72,10 +77,7 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) switch (value) { case BITBANG_CS_INACTIVE: - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); + hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol^1); break; case BITBANG_CS_ACTIVE: @@ -96,14 +98,9 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) /* write new configration */ writeb(spcon, hw->regs + S3C2410_SPCON); - - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); + hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol); break; - } } @@ -330,9 +327,12 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) /* setup any gpio we can */ if (!hw->pdata->set_cs) { + hw->set_cs = s3c24xx_spi_gpiocs; + s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); - } + } else + hw->set_cs = hw->pdata->set_cs; /* register our spi controller */ -- cgit v1.2.3 From 7f6ee1adc75bf31d1b76814338f76a88e653cb60 Mon Sep 17 00:00:00 2001 From: Justin Clacherty Date: Fri, 26 Jan 2007 00:56:44 -0800 Subject: [PATCH] spi: fix error setting the spi mode in pxa2xx_spi.c Currently the spi mode can be set to the wrong mode if you are switching from any mode other than mode 0. This is because the mode is set using a bitwise or on uncleared bits. The following patch clears the mode bits before setting the new mode. I've also modified it to use the appropriate defines from pxa-regs.h for readability. Signed-off-by: Justin Clacherty Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/pxa2xx_spi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 6ed3f1da9296..8b41f9cc2560 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1169,8 +1169,9 @@ static int setup(struct spi_device *spi) spi->bits_per_word - 16 : spi->bits_per_word) | SSCR0_SSE | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); - chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) - | (((spi->mode & SPI_CPOL) != 0) << 3); + chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); + chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) + | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) -- cgit v1.2.3 From 1e9a51dca19dc1d8807c63cb3bd4413d3f95aaf5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 26 Jan 2007 00:56:54 -0800 Subject: [PATCH] SPI: alternative fix for spi_busnum_to_master If a SPI master device exists, udev (udevtrigger) causes kernel crash, due to wrong kobj pointer in kobject_uevent_env(). This problem was not in 2.6.19. The backtrace (on MIPS) was: [<8024db6c>] kobject_uevent_env+0x54c/0x5e8 [<802a8264>] store_uevent+0x1c/0x3c (in drivers/class.c) [<801cb14c>] subsys_attr_store+0x2c/0x50 [<801cb80c>] flush_write_buffer+0x38/0x5c [<801cb900>] sysfs_write_file+0xd0/0x190 [<80181444>] vfs_write+0xc4/0x1a0 [<80181cdc>] sys_write+0x54/0xa0 [<8010dae4>] stack_done+0x20/0x3c flush_write_buffer() passes kobject of spi_master_class.subsys to subsys_addr_store(), then subsys_addr_store() passes a pointer to a struct subsystem to store_uevent() which expects a pointer to a struct class_device. The problem seems subsys_attr_store() called instead of class_device_attr_store(). This mismatch was caused by commit 3bd0f6943520e459659d10f3282285e43d3990f1, which overrides kset of master class. This made spi_master_class.subsys.kset.ktype NULL so subsys_sysfs_ops is used instead of class_dev_sysfs_ops. The commit was to fix spi_busnum_to_master(). Here is a patch fixes this function in other way, just searching children list of class_device. Signed-off-by: Atsushi Nemoto Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 270e6211c2e3..6307428d2c94 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -366,7 +366,6 @@ spi_alloc_master(struct device *dev, unsigned size) class_device_initialize(&master->cdev); master->cdev.class = &spi_master_class; - kobj_set_kset_s(&master->cdev, spi_master_class.subsys); master->cdev.dev = get_device(dev); spi_master_set_devdata(master, &master[1]); @@ -466,14 +465,20 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); */ struct spi_master *spi_busnum_to_master(u16 bus_num) { - char name[9]; - struct kobject *bus; - - snprintf(name, sizeof name, "spi%u", bus_num); - bus = kset_find_obj(&spi_master_class.subsys.kset, name); - if (bus) - return container_of(bus, struct spi_master, cdev.kobj); - return NULL; + struct class_device *cdev; + struct spi_master *master = NULL; + struct spi_master *m; + + down(&spi_master_class.sem); + list_for_each_entry(cdev, &spi_master_class.children, node) { + m = container_of(cdev, struct spi_master, cdev); + if (m->bus_num == bus_num) { + master = spi_master_get(m); + break; + } + } + up(&spi_master_class.sem); + return master; } EXPORT_SYMBOL_GPL(spi_busnum_to_master); -- cgit v1.2.3 From e4233dec749a3519069d9390561b5636a75c7579 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 26 Jan 2007 00:56:55 -0800 Subject: [PATCH] ACPI: fix cpufreq regression Recently cpufreq support on my laptop (Lenovo T60) broke completely: when it's plugged into AC it would never go higher than 1 GHz - neither 1.3 GHz nor 1.83 GHz is possible - no matter which governor (userspace, speed or ondemand) is used. After some cpufreq debugging i tracked the regression back to the following (totally correct) bug-fix commit: commit 0916bd3ebb7cefdd0f432e8491abe24f4b5a101e Author: Dave Jones Date: Wed Nov 22 20:42:01 2006 -0500 [PATCH] Correct bound checking from the value returned from _PPC method. This bugfix, which makes other laptops work, made a previously hidden (BIOS) bug visible on my laptop. The bug is the following: if the _PPC (Performance Present Capabilities) optional ACPI object is queried /after/ bootup then the BIOS reports an incorrect value of '2'. My laptop (Lenovo T60) has the following performance states supported: 0: 1833000 1: 1333000 2: 1000000 Per ACPI specification, a _PPC value of '0' means that all 3 performance states are usable. A _PPC value of '1' means states 1 .. 2 are usable, a value of '2' means only state '2' (slowest) is usable. now, the _PPC object is optional, and it also comes with notification. Furthermore, when a CPU object is initialized, the _PPC object is initialized as well. So the following evaluation of the _PPC object is superfluous: [] acpi_processor_get_platform_limit+0xa1/0xaf [] acpi_processor_register_performance+0x3b9/0x3ef [] acpi_cpufreq_cpu_init+0xb7/0x596 [] cpufreq_add_dev+0x160/0x4a8 [] sysdev_driver_register+0x5a/0xa0 [] cpufreq_register_driver+0xb4/0x176 [] acpi_cpufreq_init+0xe5/0xeb [] init+0x14f/0x3dd And this is the point where my laptop's BIOS returns the incorrect value of '2'. Note that it has not sent any notification event, so the value is probably not really intentional (possibly spurious), and Windows likely doesnt query it after bootup either. Maybe the value is kept at '2' normally, and is only set to the real value when a true asynchronous event (such as AC plug event, battery switch, etc.) occurs. So i /think/ this is a grey area of the ACPI spec: per the letter of the spec the _PPC value only changes when notified, so there's no reason to query it after the system has booted up. So in my opinion the best (and most compatible) strategy would be to do the change below, and to not evaluate the _PPC object in the acpi_processor_get_performance_info() call, but only evaluate it if _PPC is present during CPU object init, or if it's notified during an asynchronous event. This change is more permissive than the previous logic, so it definitely shouldnt break any existing system. This also happens to fix my laptop, which is merrily chugging along at 1.83 GHz now. Yay! Signed-off-by: Ingo Molnar Cc: Dave Jones Acked-by: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/processor_perflib.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 5207f9e4b443..cbb6f0814ce2 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -322,10 +322,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) if (result) return result; - result = acpi_processor_get_platform_limit(pr); - if (result) - return result; - return 0; } -- cgit v1.2.3 From e702ff0ba6f7b52021f26e0e14237eb6ca8a1b6f Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Fri, 26 Jan 2007 00:56:56 -0800 Subject: [PATCH] Gigaset ISDN driver error handling fixes Fix several flaws in the error handling of the Siemens Gigaset ISDN driver, including one that would cause an Oops when connecting more than one device of the same type. Signed-off-by: Tilman Schmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/gigaset/common.c | 61 +++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 95eff3b2917a..4f75cce6fdff 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -356,16 +356,17 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv) { unsigned long flags; unsigned i; - static struct cardstate *ret = NULL; + struct cardstate *ret = NULL; spin_lock_irqsave(&drv->lock, flags); for (i = 0; i < drv->minors; ++i) { if (!(drv->flags[i] & VALID_MINOR)) { - drv->flags[i] = VALID_MINOR; - ret = drv->cs + i; - } - if (ret) + if (try_module_get(drv->owner)) { + drv->flags[i] = VALID_MINOR; + ret = drv->cs + i; + } break; + } } spin_unlock_irqrestore(&drv->lock, flags); return ret; @@ -376,6 +377,8 @@ static void free_cs(struct cardstate *cs) unsigned long flags; struct gigaset_driver *drv = cs->driver; spin_lock_irqsave(&drv->lock, flags); + if (drv->flags[cs->minor_index] & VALID_MINOR) + module_put(drv->owner); drv->flags[cs->minor_index] = 0; spin_unlock_irqrestore(&drv->lock, flags); } @@ -579,7 +582,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - warn("could not allocate skb\n"); + warn("could not allocate skb"); bcs->inputstate |= INS_skip_frame; } @@ -632,17 +635,25 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, int i; gig_dbg(DEBUG_INIT, "allocating cs"); - cs = alloc_cs(drv); - if (!cs) - goto error; + if (!(cs = alloc_cs(drv))) { + err("maximum number of devices exceeded"); + return NULL; + } + mutex_init(&cs->mutex); + mutex_lock(&cs->mutex); + gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); - if (!cs->bcs) + if (!cs->bcs) { + err("out of memory"); goto error; + } gig_dbg(DEBUG_INIT, "allocating inbuf"); cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); - if (!cs->inbuf) + if (!cs->inbuf) { + err("out of memory"); goto error; + } cs->cs_init = 0; cs->channels = channels; @@ -654,8 +665,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, spin_lock_init(&cs->ev_lock); cs->ev_tail = 0; cs->ev_head = 0; - mutex_init(&cs->mutex); - mutex_lock(&cs->mutex); tasklet_init(&cs->event_tasklet, &gigaset_handle_event, (unsigned long) cs); @@ -684,8 +693,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, for (i = 0; i < channels; ++i) { gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); - if (!gigaset_initbcs(cs->bcs + i, cs, i)) + if (!gigaset_initbcs(cs->bcs + i, cs, i)) { + err("could not allocate channel %d data", i); goto error; + } } ++cs->cs_init; @@ -720,8 +731,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, make_valid(cs, VALID_ID); ++cs->cs_init; gig_dbg(DEBUG_INIT, "setting up hw"); - if (!cs->ops->initcshw(cs)) + if (!cs->ops->initcshw(cs)) { + err("could not allocate device specific data"); goto error; + } ++cs->cs_init; @@ -743,8 +756,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, mutex_unlock(&cs->mutex); return cs; -error: if (cs) - mutex_unlock(&cs->mutex); +error: + mutex_unlock(&cs->mutex); gig_dbg(DEBUG_INIT, "failed"); gigaset_freecs(cs); return NULL; @@ -1040,7 +1053,6 @@ void gigaset_freedriver(struct gigaset_driver *drv) spin_unlock_irqrestore(&driver_lock, flags); gigaset_if_freedriver(drv); - module_put(drv->owner); kfree(drv->cs); kfree(drv->flags); @@ -1072,10 +1084,6 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, if (!drv) return NULL; - if (!try_module_get(owner)) - goto out1; - - drv->cs = NULL; drv->have_tty = 0; drv->minor = minor; drv->minors = minors; @@ -1087,11 +1095,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); if (!drv->cs) - goto out2; + goto error; drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); if (!drv->flags) - goto out3; + goto error; for (i = 0; i < minors; ++i) { drv->flags[i] = 0; @@ -1108,11 +1116,8 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, return drv; -out3: +error: kfree(drv->cs); -out2: - module_put(owner); -out1: kfree(drv); return NULL; } -- cgit v1.2.3 From 3eda22d19b76b15ef3420b251bd47a0ba0127589 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 26 Jan 2007 00:57:01 -0800 Subject: [PATCH] md: make 'repair' actually work for raid1 When 'repair' finds a block that is different one the various parts of the mirror. it is meant to write a chosen good version to the others. However it currently writes out the original data to each. The memcpy to make all the data the same is missing. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 164b25dca101..ab74d40cac98 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1266,6 +1266,11 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) sbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; sbio->bi_bdev = conf->mirrors[i].rdev->bdev; + for (j = 0; j < vcnt ; j++) + memcpy(page_address(sbio->bi_io_vec[j].bv_page), + page_address(pbio->bi_io_vec[j].bv_page), + PAGE_SIZE); + } } } -- cgit v1.2.3 From 1031be7a5fafd3a858dfaabb74d98f9ca20744a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 26 Jan 2007 00:57:02 -0800 Subject: [PATCH] md: make sure the events count in an md array never returns to zero Now that we sometimes step the array events count backwards (when transitioning dirty->clean where nothing else interesting has happened - so that we don't need to write to spares all the time), it is possible for the event count to return to zero, which is potentially confusing and triggers and MD_BUG. We could possibly remove the MD_BUG, but is just as easy, and probably safer, to make sure we never return to zero. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index d1cb45f6d6a9..ec3d8e8a0bd3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1633,7 +1633,8 @@ repeat: * and 'events' is odd, we can roll back to the previous clean state */ if (nospares && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events & 1)) + && (mddev->events & 1) + && mddev->events != 1) mddev->events--; else { /* otherwise we have to go forward and ... */ -- cgit v1.2.3 From f49d5e62d9352d33b30c9befbaf0fd9c88265ec1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 26 Jan 2007 00:57:03 -0800 Subject: [PATCH] md: avoid reading past the end of a bitmap file In most cases we check the size of the bitmap file before reading data from it. However when reading the superblock, we always read the first PAGE_SIZE bytes, which might not always be appropriate. So limit that read to the size of the file if appropriate. Also, we get the count of available bytes wrong in one place, so that too can read past the end of the file. Cc: "yang yin" Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 5432d07c074d..11108165e264 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -479,9 +479,12 @@ static int bitmap_read_sb(struct bitmap *bitmap) int err = -EINVAL; /* page 0 is the superblock, read it... */ - if (bitmap->file) - bitmap->sb_page = read_page(bitmap->file, 0, bitmap, PAGE_SIZE); - else { + if (bitmap->file) { + loff_t isize = i_size_read(bitmap->file->f_mapping->host); + int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; + + bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); + } else { bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); } if (IS_ERR(bitmap->sb_page)) { @@ -877,7 +880,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) int count; /* unmap the old page, we're done with it */ if (index == num_pages-1) - count = bytes - index * PAGE_SIZE; + count = bytes + sizeof(bitmap_super_t) + - index * PAGE_SIZE; else count = PAGE_SIZE; if (index == 0) { -- cgit v1.2.3 From bfa152fa5e4d328fe3ebf15908ee8ec20a0ce6dc Mon Sep 17 00:00:00 2001 From: Jun'ichi Nomura Date: Fri, 26 Jan 2007 00:57:07 -0800 Subject: [PATCH] dm-multipath: fix stall on noflush suspend/resume Allow noflush suspend/resume of device-mapper device only for the case where the device size is unchanged. Otherwise, dm-multipath devices can stall when resumed if noflush was used when suspending them, all paths have failed and queue_if_no_path is set. Explanation: 1. Something is doing fsync() on the block dev, holding inode->i_sem 2. The fsync write is blocked by all-paths-down and queue_if_no_path 3. Someone requests to suspend the dm device with noflush. Pending writes are left in queue. 4. In the middle of dm_resume(), __bind() tries to get inode->i_sem to do __set_size() and waits forever. 'noflush suspend' is a new device-mapper feature introduced in early 2.6.20. So I hope the fix being included before 2.6.20 is released. Example of reproducer: 1. Create a multipath device by dmsetup 2. Fail all paths during mkfs 3. Do dmsetup suspend --noflush and load new map with healthy paths 4. Do dmsetup resume Signed-off-by: Jun'ichi Nomura Acked-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index fe7c56e10435..3668b170ea68 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1116,7 +1116,8 @@ static int __bind(struct mapped_device *md, struct dm_table *t) if (size != get_capacity(md->disk)) memset(&md->geometry, 0, sizeof(md->geometry)); - __set_size(md, size); + if (md->suspended_bdev) + __set_size(md, size); if (size == 0) return 0; @@ -1264,6 +1265,11 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) if (!dm_suspended(md)) goto out; + /* without bdev, the device size cannot be changed */ + if (!md->suspended_bdev) + if (get_capacity(md->disk) != dm_table_get_size(table)) + goto out; + __unbind(md); r = __bind(md, table); @@ -1341,11 +1347,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) /* This does not get reverted if there's an error later. */ dm_table_presuspend_targets(map); - md->suspended_bdev = bdget_disk(md->disk, 0); - if (!md->suspended_bdev) { - DMWARN("bdget failed in dm_suspend"); - r = -ENOMEM; - goto flush_and_out; + /* bdget() can stall if the pending I/Os are not flushed */ + if (!noflush) { + md->suspended_bdev = bdget_disk(md->disk, 0); + if (!md->suspended_bdev) { + DMWARN("bdget failed in dm_suspend"); + r = -ENOMEM; + goto flush_and_out; + } } /* @@ -1473,8 +1482,10 @@ int dm_resume(struct mapped_device *md) unlock_fs(md); - bdput(md->suspended_bdev); - md->suspended_bdev = NULL; + if (md->suspended_bdev) { + bdput(md->suspended_bdev); + md->suspended_bdev = NULL; + } clear_bit(DMF_SUSPENDED, &md->flags); -- cgit v1.2.3 From a8d814b5dd7a1bc5c19ae32d35b8bd4d8a510eae Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 26 Jan 2007 00:57:08 -0800 Subject: [PATCH] remove __devinit markings from rtc_sysfs_add_device() rtc_sysfs_add_device is needed even after dev initialization, so drop __devinit. Signed-off-by: Mike Frysinger Acked-by: Alessandro Zummo Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 9418a59fb368..2ddd0cf07140 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c @@ -78,7 +78,7 @@ static struct attribute_group rtc_attr_group = { .attrs = rtc_attrs, }; -static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, +static int rtc_sysfs_add_device(struct class_device *class_dev, struct class_interface *class_intf) { int err; -- cgit v1.2.3 From 2a2275d630b982e5f90206f9bc497f6695a3ec5d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 26 Jan 2007 00:57:11 -0800 Subject: [PATCH] md: fix potential memalloc deadlock in md If a GFP_KERNEL allocation is attempted in md while the mddev_lock is held, it is possible for a deadlock to eventuate. This happens if the array was marked 'clean', and the memalloc triggers a write-out to the md device. For the writeout to succeed, the array must be marked 'dirty', and that requires getting the mddev_lock. So, before attempting a GFP_KERNEL allocation while holding the lock, make sure the array is marked 'dirty' (unless it is currently read-only). Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 29 +++++++++++++++++++++++++++++ drivers/md/raid1.c | 2 ++ drivers/md/raid5.c | 3 +++ include/linux/raid/md.h | 2 +- 4 files changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index ec3d8e8a0bd3..e8807ea5377d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3564,6 +3564,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) char *ptr, *buf = NULL; int err = -ENOMEM; + md_allow_write(mddev); + file = kmalloc(sizeof(*file), GFP_KERNEL); if (!file) goto out; @@ -5032,6 +5034,33 @@ void md_write_end(mddev_t *mddev) } } +/* md_allow_write(mddev) + * Calling this ensures that the array is marked 'active' so that writes + * may proceed without blocking. It is important to call this before + * attempting a GFP_KERNEL allocation while holding the mddev lock. + * Must be called with mddev_lock held. + */ +void md_allow_write(mddev_t *mddev) +{ + if (!mddev->pers) + return; + if (mddev->ro) + return; + + spin_lock_irq(&mddev->write_lock); + if (mddev->in_sync) { + mddev->in_sync = 0; + set_bit(MD_CHANGE_CLEAN, &mddev->flags); + if (mddev->safemode_delay && + mddev->safemode == 0) + mddev->safemode = 1; + spin_unlock_irq(&mddev->write_lock); + md_update_sb(mddev, 0); + } else + spin_unlock_irq(&mddev->write_lock); +} +EXPORT_SYMBOL_GPL(md_allow_write); + static DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ab74d40cac98..97ee870b265d 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2104,6 +2104,8 @@ static int raid1_reshape(mddev_t *mddev) return -EINVAL; } + md_allow_write(mddev); + raid_disks = mddev->raid_disks + mddev->delta_disks; if (raid_disks < conf->raid_disks) { diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index be008f034ada..8a30b297ac3a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -405,6 +405,8 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) if (newsize <= conf->pool_size) return 0; /* never bother to shrink */ + md_allow_write(conf->mddev); + /* Step 1 */ sc = kmem_cache_create(conf->cache_name[1-conf->active_name], sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), @@ -3250,6 +3252,7 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) else break; } + md_allow_write(mddev); while (new > conf->max_nr_stripes) { if (grow_one_stripe(conf)) conf->max_nr_stripes++; diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 866a1e2b0ce0..fbaeda79b2e9 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -94,7 +94,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct page *page, int rw); extern void md_do_sync(mddev_t *mddev); extern void md_new_event(mddev_t *mddev); - +extern void md_allow_write(mddev_t *mddev); #endif /* CONFIG_MD */ #endif -- cgit v1.2.3 From c20086de9319ac406f1e96ad459763c9f9965b18 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 26 Jan 2007 00:57:14 -0800 Subject: [PATCH] md: remove unnecessary printk when raid5 gets an unaligned read. raid5_mergeable_bvec tries to ensure that raid5 never sees a read request that does not fit within just one chunk. However as we must always accept a single-page read, that is not always possible. So when "in_chunk_boundary" fails, it might be unusual, but it is not a problem and printing a message every time is a bad idea. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8a30b297ac3a..467c16982d02 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2680,7 +2680,7 @@ static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) mdk_rdev_t *rdev; if (!in_chunk_boundary(mddev, raid_bio)) { - printk("chunk_aligned_read : non aligned\n"); + PRINTK("chunk_aligned_read : non aligned\n"); return 0; } /* -- cgit v1.2.3 From 496a0fc8c5572a626de41d56d7c7ed005a2c1b48 Mon Sep 17 00:00:00 2001 From: Matt Domsch Date: Fri, 26 Jan 2007 00:57:18 -0800 Subject: [PATCH] Fix race in efi variable delete code Fix race when deleting an EFI variable and issuing another EFI command on the same variable. The removal of the variable from the efivars_list should be done in efivar_delete and not delayed until the kobject release. Furthermore, remove the item from the list at module unload time, and use list_for_each_entry_safe() rather than list_for_each_safe() for readability. Tested on ia64. Signed-off-by: Prarit Bhargava Signed-off-by: Matt Domsch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/efivars.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5ab5e393b882..c6281ccd4fe7 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -122,8 +122,6 @@ struct efivar_entry { struct kobject kobj; }; -#define get_efivar_entry(n) list_entry(n, struct efivar_entry, list) - struct efivar_attribute { struct attribute attr; ssize_t (*show) (struct efivar_entry *entry, char *buf); @@ -386,9 +384,6 @@ static struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); - spin_lock(&efivars_lock); - list_del(&var->list); - spin_unlock(&efivars_lock); kfree(var); } @@ -430,9 +425,8 @@ static ssize_t efivar_create(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar = NULL; + struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; - struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -444,8 +438,7 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_safe(pos, n, &efivar_list) { - search_efivar = get_efivar_entry(pos); + list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -490,9 +483,8 @@ static ssize_t efivar_delete(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar = NULL; + struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; - struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -504,8 +496,7 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_safe(pos, n, &efivar_list) { - search_efivar = get_efivar_entry(pos); + list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -537,9 +528,9 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) spin_unlock(&efivars_lock); return -EIO; } + list_del(&search_efivar->list); /* We need to release this lock before unregistering. */ spin_unlock(&efivars_lock); - efivar_unregister(search_efivar); /* It's dead Jim.... */ @@ -768,10 +759,14 @@ out_free: static void __exit efivars_exit(void) { - struct list_head *pos, *n; + struct efivar_entry *entry, *n; - list_for_each_safe(pos, n, &efivar_list) - efivar_unregister(get_efivar_entry(pos)); + list_for_each_entry_safe(entry, n, &efivar_list, list) { + spin_lock(&efivars_lock); + list_del(&entry->list); + spin_unlock(&efivars_lock); + efivar_unregister(entry); + } subsystem_unregister(&vars_subsys); firmware_unregister(&efi_subsys); -- cgit v1.2.3 From 6096b63e2584796341baf7e7735f98d387f489f2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 14:47:38 +0900 Subject: ahci: fix endianness in spurious interrupt message Fix endianness in spurious interrupt message. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2fe5a58195de..d8f0ce970d54 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1178,7 +1178,8 @@ static void ahci_host_intr(struct ata_port *ap) ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", readl(port_mmio + PORT_CMD_ISSUE), - readl(port_mmio + PORT_SCR_ACT), f[0], f[1], + readl(port_mmio + PORT_SCR_ACT), + le32_to_cpu(f[0]), le32_to_cpu(f[1]), pp->ncq_saw_spurious_sdb_cnt < 10 ? "" : ", shutting up"); -- cgit v1.2.3 From d02598721706ab62a574823479b1f6c26c8980d2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 14:57:31 +0900 Subject: sata_via: style clean up, no indirect method call in LLD Call ata_bmdma_irq_clear() directly instead of through ap->ops->irq_clear() according to libata style guideline. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 55b01236a6f0..d3d5c0d57032 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -211,7 +211,7 @@ static void svia_noop_freeze(struct ata_port *ap) * certain way. Leave it alone and just clear pending IRQ. */ ata_chk_status(ap); - ap->ops->irq_clear(ap); + ata_bmdma_irq_clear(ap); } /** -- cgit v1.2.3 From dfd7a3db3898e299bdc25f0c77081a8632b3a73c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 15:37:20 +0900 Subject: ahci: use 0x80 as wait stat value instead of 0xff Before hardreset, ahci initialized stat part of received FIS area to 0xff to wait for the first D2H Reg FIS which would change the value to device ready state. This used to work but now libata considers status value of 0xff as device not present making this wait prone to failure. This patch makes ahci use 0x80 for the wait stat value instead of 0xff to fix the above problem. Signed-off-by: Tejun Heo drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index d8f0ce970d54..28a82e3403f1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -903,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); - tf.command = 0xff; + tf.command = 0x80; ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class); -- cgit v1.2.3 From 8cdf92a98fa0f91068615443f2a8597b7f2c34ca Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 1 Jan 2007 19:31:15 +0000 Subject: Fix Maple PATA IRQ assignment. On the Maple board, the AMD8111 IDE is in legacy mode... except that it appears on IRQ 20 instead of IRQ 15. For drivers/ide this was handled by the architecture's "pci_get_legacy_ide_irq()" function, but in libata we just hard-code the numbers 14 and 15. This patch provides asm-powerpc/libata-portmap.h which maps the IRQ as appropriate, having added a pci_dev argument to the ATA_{PRIM,SECOND}ARY_IRQ macros. There's probably a better way to do this -- especially if we observe that the _only_ case in which this seemingly-generic "pci_get_legacy_ide_irq()" function returns anything other than 14 and 15 for primary and secondary respectively is the case of the AMD8111 on the Maple board -- couldn't we handle that with a special case in the pata_amd driver, or perhaps with a PCI quirk for Maple to switch it into native mode during early boot and assign resources properly? Signed-off-by: David Woodhouse Signed-off-by: Jeff Garzik --- arch/powerpc/Kconfig | 1 + drivers/ata/Kconfig | 4 ++++ drivers/ata/libata-sff.c | 6 +++--- include/asm-generic/libata-portmap.h | 4 ++-- include/asm-powerpc/libata-portmap.h | 12 ++++++++++++ 5 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 include/asm-powerpc/libata-portmap.h (limited to 'drivers') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0855d55c194d..b268c417c0bf 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -484,6 +484,7 @@ config PPC_MAPLE select PPC_970_NAP select PPC_NATIVE select PPC_RTAS + select ATA_NONSTANDARD if ATA default n help This option enables support for the Maple 970FX Evaluation Board. diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index da21552d2b1c..1c94b43d2c9b 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -19,6 +19,10 @@ config ATA if ATA +config ATA_NONSTANDARD + bool + default n + config SATA_AHCI tristate "AHCI SATA support" depends on PCI diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 942aeba2940a..12c88c588039 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -917,7 +917,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->irq_flags = IRQF_SHARED; if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ; + probe_ent->irq = ATA_PRIMARY_IRQ(pdev); probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; @@ -933,9 +933,9 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, if (port_mask & ATA_PORT_SECONDARY) { if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ; + probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); else - probe_ent->irq = ATA_SECONDARY_IRQ; + probe_ent->irq = ATA_SECONDARY_IRQ(pdev); probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h index 9202fd02d5be..62fb3618293d 100644 --- a/include/asm-generic/libata-portmap.h +++ b/include/asm-generic/libata-portmap.h @@ -3,10 +3,10 @@ #define ATA_PRIMARY_CMD 0x1F0 #define ATA_PRIMARY_CTL 0x3F6 -#define ATA_PRIMARY_IRQ 14 +#define ATA_PRIMARY_IRQ(dev) 14 #define ATA_SECONDARY_CMD 0x170 #define ATA_SECONDARY_CTL 0x376 -#define ATA_SECONDARY_IRQ 15 +#define ATA_SECONDARY_IRQ(dev) 15 #endif diff --git a/include/asm-powerpc/libata-portmap.h b/include/asm-powerpc/libata-portmap.h new file mode 100644 index 000000000000..4d8518049f4d --- /dev/null +++ b/include/asm-powerpc/libata-portmap.h @@ -0,0 +1,12 @@ +#ifndef __ASM_POWERPC_LIBATA_PORTMAP_H +#define __ASM_POWERPC_LIBATA_PORTMAP_H + +#define ATA_PRIMARY_CMD 0x1F0 +#define ATA_PRIMARY_CTL 0x3F6 +#define ATA_PRIMARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 0) + +#define ATA_SECONDARY_CMD 0x170 +#define ATA_SECONDARY_CTL 0x376 +#define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1) + +#endif -- cgit v1.2.3 From a718728f9e40ec79c0879ec6509a54fee214f5b2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 27 Jan 2007 11:04:26 +0900 Subject: ahci: port_no should be used when clearing IRQ in ahci_thaw() ap->id is logcial port ID which is unique among all ATA ports and doesn't have anything to do with hardware port index. ap->port_no is the hardware port index and thus should be used when clearing IRQ mask in ahci_thaw(). This problem has been spotted by Jeff Garzik . Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 28a82e3403f1..48616c6fee9d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1282,7 +1282,7 @@ static void ahci_thaw(struct ata_port *ap) /* clear IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); writel(tmp, port_mmio + PORT_IRQ_STAT); - writel(1 << ap->id, mmio + HOST_IRQ_STAT); + writel(1 << ap->port_no, mmio + HOST_IRQ_STAT); /* turn IRQ back on */ writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); -- cgit v1.2.3 From 03ee5b1cdd09ed1ee2e75d0bc647fc5db66b9d07 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 20:10:25 +0900 Subject: libata: fix ata_eh_suspend() return value ata_eh_suspend() was returning 0 regardless of failure. This bug has potential to lose data on suspend. Fix it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 56cf59b60ec4..748435807d68 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1796,7 +1796,7 @@ static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) *r_failed_dev = dev; DPRINTK("EXIT\n"); - return 0; + return rc; } /** -- cgit v1.2.3 From a51545ab2523b9cfd426737495f877821006371a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 27 Jan 2007 13:46:21 +0100 Subject: jmicron: fix warning Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/jmicron.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index c1cec236ecf0..35dda8fcd0ac 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -93,8 +93,9 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif) return 0; return 1; case PORT_SATA: - return 1; + break; } + return 1; /* Avoid bogus "control reaches end of non-void function" */ } static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) -- cgit v1.2.3 From 737153298023342073ccaa006144dd254b298e2b Mon Sep 17 00:00:00 2001 From: Conke Hu Date: Sat, 27 Jan 2007 13:46:28 +0100 Subject: atiixp.c: remove unused code A previous patch to atiixp.c was removed but some code has not been cleaned. Now we remove these code sine they are no use any longer. Signed-off-by: Conke Hu Cc: Alan Cox Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/atiixp.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 524e65de4398..148af8ab518f 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -320,19 +320,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->drives[0].autodma = hwif->autodma; } -static void __devinit init_hwif_sb600_legacy(ide_hwif_t *hwif) -{ - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ @@ -342,13 +329,7 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .bootable = ON_BOARD, - },{ /* 1 */ - .name = "ATI SB600 SATA Legacy IDE", - .init_hwif = init_hwif_sb600_legacy, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } + }, }; /** -- cgit v1.2.3 From b25168dfdc162b4198fa6395cd191a20dddc6d34 Mon Sep 17 00:00:00 2001 From: Conke Hu Date: Sat, 27 Jan 2007 13:46:30 +0100 Subject: atiixp.c: sb600 ide only has one channel AMD/ATI SB600 IDE/PATA controller only has one channel. Signed-off-by: Conke Hu Cc: Alan Cox Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/atiixp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 148af8ab518f..5b7e000ac2f5 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -329,7 +329,14 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .bootable = ON_BOARD, - }, + },{ /* 1 */ + .name = "SB600_PATA", + .init_hwif = init_hwif_atiixp, + .channels = 1, + .autodma = AUTODMA, + .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, + .bootable = ON_BOARD, + }, }; /** @@ -350,7 +357,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); -- cgit v1.2.3 From e5c073ff24604d4dbb2fbcedb17da6df768468d3 Mon Sep 17 00:00:00 2001 From: Conke Hu Date: Sat, 27 Jan 2007 13:46:40 +0100 Subject: atiixp.c: add cable detection support for ATI IDE IDE HDD does not work if it uses a 40-pin PATA cable on ATI chipset. This patch fixes the bug. Signed-off-by: Conke Hu Cc: Alan Cox Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/atiixp.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 5b7e000ac2f5..7e1d07031d32 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -291,8 +291,12 @@ fast_ata_pio: static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) { + u8 udma_mode = 0; + u8 ch = hwif->channel; + struct pci_dev *pdev = hwif->pci_dev; + if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; + hwif->irq = ch ? 15 : 14; hwif->autodma = 0; hwif->tuneproc = &atiixp_tuneproc; @@ -308,8 +312,12 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->mwdma_mask = 0x06; hwif->swdma_mask = 0x04; - /* FIXME: proper cable detection needed */ - hwif->udma_four = 1; + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode); + if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40) + hwif->udma_four = 1; + else + hwif->udma_four = 0; + hwif->ide_dma_host_on = &atiixp_ide_dma_host_on; hwif->ide_dma_host_off = &atiixp_ide_dma_host_off; hwif->ide_dma_check = &atiixp_dma_check; -- cgit v1.2.3 From 3e9e4c8606127592cda22159cc2440ea48963ae4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 27 Jan 2007 13:46:45 +0100 Subject: ide/generic: Jmicron has its own drivers now Drop ide-generic support for Jmicron identifiers as we now trust Jmicron.c for this with drivers/ide. The code check remains for the all-generic-ide case. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/generic.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 9f306880491a..3143cb03fe3c 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -185,36 +185,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, - },{ /* 15 */ - .name = "JMB361", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 16 */ - .name = "JMB363", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 17 */ - .name = "JMB365", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 18 */ - .name = "JMB366", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 19 */ - .name = "JMB368", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, } }; @@ -281,11 +251,6 @@ static struct pci_device_id generic_pci_tbl[] = { { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, { PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, /* Must come last. If you add entries adjust this table appropriately and the init_one code */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0}, { 0, }, -- cgit v1.2.3 From 82ab1eeceba6705cd5a8815c48eb03af1dada744 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 27 Jan 2007 13:46:56 +0100 Subject: ide: add missing __init tags to IDE PCI host drivers also change __devinit tag for sgiioc4.c:ioc4_ide_init() to __init Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/aec62xx.c | 2 +- drivers/ide/pci/alim15x3.c | 2 +- drivers/ide/pci/amd74xx.c | 2 +- drivers/ide/pci/atiixp.c | 2 +- drivers/ide/pci/cmd64x.c | 2 +- drivers/ide/pci/cs5520.c | 2 +- drivers/ide/pci/cs5530.c | 2 +- drivers/ide/pci/cy82c693.c | 2 +- drivers/ide/pci/generic.c | 2 +- drivers/ide/pci/hpt34x.c | 2 +- drivers/ide/pci/hpt366.c | 2 +- drivers/ide/pci/ns87415.c | 2 +- drivers/ide/pci/opti621.c | 2 +- drivers/ide/pci/pdc202xx_new.c | 2 +- drivers/ide/pci/pdc202xx_old.c | 2 +- drivers/ide/pci/rz1000.c | 2 +- drivers/ide/pci/sc1200.c | 2 +- drivers/ide/pci/serverworks.c | 2 +- drivers/ide/pci/sgiioc4.c | 3 +-- drivers/ide/pci/siimage.c | 2 +- drivers/ide/pci/sis5513.c | 2 +- drivers/ide/pci/sl82c105.c | 2 +- drivers/ide/pci/slc90e66.c | 2 +- drivers/ide/pci/triflex.c | 2 +- drivers/ide/pci/trm290.c | 2 +- drivers/ide/pci/via82cxxx.c | 2 +- 26 files changed, 26 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index f286079d233f..d261bfbad222 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -441,7 +441,7 @@ static struct pci_driver driver = { .probe = aec62xx_init_one, }; -static int aec62xx_ide_init(void) +static int __init aec62xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 89109be5162c..68df77ec502b 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -907,7 +907,7 @@ static struct pci_driver driver = { .probe = alim15x3_init_one, }; -static int ali15x3_ide_init(void) +static int __init ali15x3_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 753fe0e21456..a4336995a410 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -544,7 +544,7 @@ static struct pci_driver driver = { .probe = amd74xx_probe, }; -static int amd74xx_ide_init(void) +static int __init amd74xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 7e1d07031d32..982ac31fa995 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -376,7 +376,7 @@ static struct pci_driver driver = { .probe = atiixp_init_one, }; -static int atiixp_ide_init(void) +static int __init atiixp_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 20c32716bbc4..aee947e8fc38 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -793,7 +793,7 @@ static struct pci_driver driver = { .probe = cmd64x_init_one, }; -static int cmd64x_ide_init(void) +static int __init cmd64x_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 079f7c86726b..ba6786aabf3b 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -260,7 +260,7 @@ static struct pci_driver driver = { .probe = cs5520_init_one, }; -static int cs5520_ide_init(void) +static int __init cs5520_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index ae405fa32236..9bf5fdfc5b1f 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -374,7 +374,7 @@ static struct pci_driver driver = { .probe = cs5530_init_one, }; -static int cs5530_ide_init(void) +static int __init cs5530_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 64330c459bd4..9eafcbf444f4 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -519,7 +519,7 @@ static struct pci_driver driver = { .probe = cy82c693_init_one, }; -static int cy82c693_ide_init(void) +static int __init cy82c693_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 3143cb03fe3c..b408c6c517ea 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -263,7 +263,7 @@ static struct pci_driver driver = { .probe = generic_init_one, }; -static int generic_ide_init(void) +static int __init generic_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index b46cb042290a..ce7b08f08a09 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -265,7 +265,7 @@ static struct pci_driver driver = { .probe = hpt34x_init_one, }; -static int hpt34x_ide_init(void) +static int __init hpt34x_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 08119da06d54..b486442dd5d7 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1613,7 +1613,7 @@ static struct pci_driver driver = { .probe = hpt366_init_one, }; -static int hpt366_ide_init(void) +static int __init hpt366_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index d95714bcee4e..8aaea4ea5549 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -302,7 +302,7 @@ static struct pci_driver driver = { .probe = ns87415_init_one, }; -static int ns87415_ide_init(void) +static int __init ns87415_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 7a7c2ef78ac2..22bbf613f948 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -382,7 +382,7 @@ static struct pci_driver driver = { .probe = opti621_init_one, }; -static int opti621_ide_init(void) +static int __init opti621_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 7cb48576e479..77a9aaa7dab9 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -756,7 +756,7 @@ static struct pci_driver driver = { .probe = pdc202new_init_one, }; -static int pdc202new_ide_init(void) +static int __init pdc202new_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 184cdacddeb6..143239c093d5 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -719,7 +719,7 @@ static struct pci_driver driver = { .probe = pdc202xx_init_one, }; -static int pdc202xx_ide_init(void) +static int __init pdc202xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index 5f6950c2d1d1..c1855311052b 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c @@ -77,7 +77,7 @@ static struct pci_driver driver = { .probe = rz1000_init_one, }; -static int rz1000_ide_init(void) +static int __init rz1000_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index ff80937d94dd..8d762d323f8b 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -507,7 +507,7 @@ static struct pci_driver driver = { #endif }; -static int sc1200_ide_init(void) +static int __init sc1200_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 057548d07205..ea9a28a45853 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -666,7 +666,7 @@ static struct pci_driver driver = { .probe = svwks_init_one, }; -static int svwks_ide_init(void) +static int __init svwks_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index cfad09accf52..b0bf01809279 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -762,8 +762,7 @@ static struct ioc4_submodule ioc4_ide_submodule = { /* .is_remove = ioc4_ide_remove_one, */ }; -static int __devinit -ioc4_ide_init(void) +static int __init ioc4_ide_init(void) { return ioc4_register_submodule(&ioc4_ide_submodule); } diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 697f566fb90a..4ff89c7d990a 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -1096,7 +1096,7 @@ static struct pci_driver driver = { .probe = siimage_init_one, }; -static int siimage_ide_init(void) +static int __init siimage_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 6b313139b5e4..1afff659ab55 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -968,7 +968,7 @@ static struct pci_driver driver = { .probe = sis5513_init_one, }; -static int sis5513_ide_init(void) +static int __init sis5513_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 5afefe8692fe..170a26199050 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -492,7 +492,7 @@ static struct pci_driver driver = { .probe = sl82c105_init_one, }; -static int sl82c105_ide_init(void) +static int __init sl82c105_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 9be7e49cba0e..90e79c0844d2 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -253,7 +253,7 @@ static struct pci_driver driver = { .probe = slc90e66_init_one, }; -static int slc90e66_ide_init(void) +static int __init slc90e66_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 56d84931d6de..b13cce1fd1a6 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -173,7 +173,7 @@ static struct pci_driver driver = { .probe = triflex_init_one, }; -static int triflex_ide_init(void) +static int __init triflex_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 2a282529bfc1..174b88c4780e 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -355,7 +355,7 @@ static struct pci_driver driver = { .probe = trm290_init_one, }; -static int trm290_ide_init(void) +static int __init trm290_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 381cc6f101ce..6414a545be00 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -514,7 +514,7 @@ static struct pci_driver driver = { .probe = via_init_one, }; -static int via_ide_init(void) +static int __init via_ide_init(void) { return ide_pci_register_driver(&driver); } -- cgit v1.2.3 From 6855036aa035913bc2bfb31c41576a49f42ecd5f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 27 Jan 2007 13:47:02 +0100 Subject: ide: unregister idepnp driver on unload idepnp driver is registered as a pnp driver on ide init but doesn't get unregistered on ide unload causing driver list corruption and eventually oops. Fix it. Signed-off-by: Tejun Heo Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-pnp.c | 5 +++++ drivers/ide/ide.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index df7d1504f84e..98410ca044cf 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -73,3 +73,8 @@ void __init pnpide_init(void) { pnp_register_driver(&idepnp_driver); } + +void __exit pnpide_exit(void) +{ + pnp_unregister_driver(&idepnp_driver); +} diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 16890769dca6..3b334af0c7b9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1782,6 +1782,7 @@ done: } extern void pnpide_init(void); +extern void pnpide_exit(void); extern void h8300_ide_init(void); /* @@ -2094,6 +2095,10 @@ void cleanup_module (void) for (index = 0; index < MAX_HWIFS; ++index) ide_unregister(index); +#ifdef CONFIG_BLK_DEV_IDEPNP + pnpide_exit(); +#endif + #ifdef CONFIG_PROC_FS proc_ide_destroy(); #endif -- cgit v1.2.3 From e0b874df14052489e6408125903dba96b4dd7baa Mon Sep 17 00:00:00 2001 From: Josepch Chan Date: Sat, 27 Jan 2007 13:47:08 +0100 Subject: via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S This patch: * Corrects the wrong device ID of PCI_DEVICE_ID_VIA_SATA_EIDE from 0x0581 to 0x5324. * Adds VIA CX700 and VT8237S support in drivers/ide/pci/via82cxxx.c * Adds VIA VT8237S support in drivers/ata/pata_via.c Signed-off-by: Josepch Chan Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ata/pata_via.c | 1 + drivers/ide/pci/via82cxxx.c | 3 +++ include/linux/pci_ids.h | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index f0d4f7e9ed31..0219419cae97 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -95,6 +95,7 @@ static const struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 6414a545be00..a98b4d38b9dd 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -78,6 +78,8 @@ static struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "cx7000", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -504,6 +506,7 @@ static struct pci_device_id via_pci_tbl[] = { { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f7a416c52edc..e642b99f9a92 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1283,7 +1283,6 @@ #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_SATA_EIDE 0x0581 #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 #define PCI_DEVICE_ID_VIA_82C596 0x0596 #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 @@ -1326,6 +1325,8 @@ #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8251 0x3287 #define PCI_DEVICE_ID_VIA_8237A 0x3337 +#define PCI_DEVICE_ID_VIA_8237S 0x3372 +#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 -- cgit v1.2.3 From 938e2ac0b7ac72d264783b0b548eb6078c295294 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 15 Jan 2007 18:07:09 -0700 Subject: [SCSI] Fix scsi_add_device() for async scanning I had thought that all drivers which didn't call scsi_scan_host() called scsi_scan_target(). Some, such as sbp2, mptsas and libata-scsi, call scsi_add_device() or __scsi_add_device(). We just need to wait for the currently executing async scans to complete first. This is the same code that's in scsi_scan_target(), except that we have to return an error instead of void when we're declining to scan at all. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index b83d03c4deef..96b7cbd746a8 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1453,6 +1453,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, struct device *parent = &shost->shost_gendev; struct scsi_target *starget; + if (strncmp(scsi_scan_type, "none", 4) == 0) + return ERR_PTR(-ENODEV); + + if (!shost->async_scan) + scsi_complete_async_scans(); + starget = scsi_alloc_target(parent, channel, id); if (!starget) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 477ffb9d8732f30e7ab2d20f6ed0c22bad37a4a5 Mon Sep 17 00:00:00 2001 From: David C Somayajulu Date: Mon, 22 Jan 2007 12:26:11 -0800 Subject: [SCSI] qla4xxx: bug fixes The included patch fixes the following issues: 1. qla3xxx/qla4xxx co-existence issue which can result in a lockup when qla3xxx driver is unloaded, or when ifdown; ifup is performed on one of the interfaces correponding to qla3xxx. This is because qla4xxx HBA supports one ethernet and iscsi interfaces per port. Both iscsi and ethernet interfaces share the same state machine. The problem has to do with synchronizing access to the state machine in the event of a reset 2. mutex_lock() is sometimes not followed by mutex_unlock() prior to invoking a msleep() in qla4xxx_mailbox_command() Signed-off-by: James Bottomley --- drivers/scsi/qla4xxx/ql4_def.h | 1 - drivers/scsi/qla4xxx/ql4_glbl.h | 1 + drivers/scsi/qla4xxx/ql4_init.c | 18 +++++------ drivers/scsi/qla4xxx/ql4_isr.c | 4 +-- drivers/scsi/qla4xxx/ql4_mbx.c | 35 ++++++++++++--------- drivers/scsi/qla4xxx/ql4_os.c | 64 +++++++++++++++++++++++--------------- drivers/scsi/qla4xxx/ql4_version.h | 2 +- 7 files changed, 73 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 4249e52a5592..6f4cf2dd2f4a 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -418,7 +418,6 @@ struct scsi_qla_host { * concurrently. */ struct mutex mbox_sem; - wait_queue_head_t mailbox_wait_queue; /* temporary mailbox status registers */ volatile uint8_t mbox_status_count; diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2122967bbf0b..e021eb5db2b2 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -76,4 +76,5 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, extern int ql4xextended_error_logging; extern int ql4xdiscoverywait; extern int ql4xdontresethba; +extern int ql4_mod_unload; #endif /* _QLA4x_GBL_H */ diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index cc210f297a78..b907b06d72ab 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -958,25 +958,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) return status; } -int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) +int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha) { -#define QL4_LOCK_DRVR_WAIT 300 -#define QL4_LOCK_DRVR_SLEEP 100 +#define QL4_LOCK_DRVR_WAIT 30 +#define QL4_LOCK_DRVR_SLEEP 1 int drvr_wait = QL4_LOCK_DRVR_WAIT; while (drvr_wait) { - if (ql4xxx_lock_drvr(a) == 0) { - msleep(QL4_LOCK_DRVR_SLEEP); + if (ql4xxx_lock_drvr(ha) == 0) { + ssleep(QL4_LOCK_DRVR_SLEEP); if (drvr_wait) { DEBUG2(printk("scsi%ld: %s: Waiting for " - "Global Init Semaphore...n", - a->host_no, - __func__)); + "Global Init Semaphore(%d)...n", + ha->host_no, + __func__, drvr_wait)); } drvr_wait -= QL4_LOCK_DRVR_SLEEP; } else { DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " - "acquired.n", a->host_no, __func__)); + "acquired.n", ha->host_no, __func__)); return QLA_SUCCESS; } } diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index ef975e0dc87f..35b9e36a0e8d 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -433,7 +433,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, readl(&ha->reg->mailbox[i]); set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); - wake_up(&ha->mailbox_wait_queue); } } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { /* Immediately process the AENs that don't require much work. @@ -686,7 +685,8 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) &ha->reg->ctrl_status); readl(&ha->reg->ctrl_status); - set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); + if (!ql4_mod_unload) + set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); break; } else if (intr_status & INTR_PENDING) { diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index b721dc5dd711..7f28657eef3f 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -29,18 +29,30 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, u_long wait_count; uint32_t intr_status; unsigned long flags = 0; - DECLARE_WAITQUEUE(wait, current); - - mutex_lock(&ha->mbox_sem); - - /* Mailbox code active */ - set_bit(AF_MBOX_COMMAND, &ha->flags); /* Make sure that pointers are valid */ if (!mbx_cmd || !mbx_sts) { DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " "pointer\n", ha->host_no, __func__)); - goto mbox_exit; + return status; + } + /* Mailbox code active */ + wait_count = MBOX_TOV * 100; + + while (wait_count--) { + mutex_lock(&ha->mbox_sem); + if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { + set_bit(AF_MBOX_COMMAND, &ha->flags); + mutex_unlock(&ha->mbox_sem); + break; + } + mutex_unlock(&ha->mbox_sem); + if (!wait_count) { + DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", + ha->host_no, __func__)); + return status; + } + msleep(10); } /* To prevent overwriting mailbox registers for a command that has @@ -73,8 +85,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for completion */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&ha->mailbox_wait_queue, &wait); /* * If we don't want status, don't wait for the mailbox command to @@ -83,8 +93,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, */ if (outCount == 0) { status = QLA_SUCCESS; - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); goto mbox_exit; } /* Wait for command to complete */ @@ -108,8 +116,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); msleep(10); } - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); /* Check for mailbox timeout. */ if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { @@ -155,9 +161,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); mbox_exit: + mutex_lock(&ha->mbox_sem); clear_bit(AF_MBOX_COMMAND, &ha->flags); - clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); mutex_unlock(&ha->mbox_sem); + clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); return status; } diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 9ef693c8809a..81fb7bd44f01 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -40,6 +40,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging, 1 - debug logging"); +int ql4_mod_unload = 0; + /* * SCSI host template entry points */ @@ -422,6 +424,9 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, goto qc_host_busy; } + if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) + goto qc_host_busy; + spin_unlock_irq(ha->host->host_lock); srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); @@ -707,16 +712,12 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) return stat; } -/** - * qla4xxx_soft_reset - performs soft reset. - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_soft_reset(struct scsi_qla_host *ha) +static void qla4xxx_hw_reset(struct scsi_qla_host *ha) { - uint32_t max_wait_time; - unsigned long flags = 0; - int status = QLA_ERROR; uint32_t ctrl_status; + unsigned long flags = 0; + + DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__)); spin_lock_irqsave(&ha->hardware_lock, flags); @@ -733,6 +734,20 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha) readl(&ha->reg->ctrl_status); spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + +/** + * qla4xxx_soft_reset - performs soft reset. + * @ha: Pointer to host adapter structure. + **/ +int qla4xxx_soft_reset(struct scsi_qla_host *ha) +{ + uint32_t max_wait_time; + unsigned long flags = 0; + int status = QLA_ERROR; + uint32_t ctrl_status; + + qla4xxx_hw_reset(ha); /* Wait until the Network Reset Intr bit is cleared */ max_wait_time = RESET_INTR_TOV; @@ -966,10 +981,12 @@ static void qla4xxx_do_dpc(struct work_struct *work) struct scsi_qla_host *ha = container_of(work, struct scsi_qla_host, dpc_work); struct ddb_entry *ddb_entry, *dtemp; + int status = QLA_ERROR; DEBUG2(printk("scsi%ld: %s: DPC handler waking up." - "flags = 0x%08lx, dpc_flags = 0x%08lx\n", - ha->host_no, __func__, ha->flags, ha->dpc_flags)); + "flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n", + ha->host_no, __func__, ha->flags, ha->dpc_flags, + readw(&ha->reg->ctrl_status))); /* Initialization not yet finished. Don't do anything yet. */ if (!test_bit(AF_INIT_DONE, &ha->flags)) @@ -983,31 +1000,28 @@ static void qla4xxx_do_dpc(struct work_struct *work) test_bit(DPC_RESET_HA, &ha->dpc_flags)) qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); - if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { + if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { uint8_t wait_time = RESET_INTR_TOV; - unsigned long flags = 0; - - qla4xxx_flush_active_srbs(ha); - spin_lock_irqsave(&ha->hardware_lock, flags); while ((readw(&ha->reg->ctrl_status) & (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) { if (--wait_time == 0) break; - - spin_unlock_irqrestore(&ha->hardware_lock, - flags); - msleep(1000); - - spin_lock_irqsave(&ha->hardware_lock, flags); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (wait_time == 0) DEBUG2(printk("scsi%ld: %s: SR|FSR " "bit not cleared-- resetting\n", ha->host_no, __func__)); + qla4xxx_flush_active_srbs(ha); + if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) { + qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); + status = qla4xxx_initialize_adapter(ha, + PRESERVE_DDB_LIST); + } + clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); + if (status == QLA_SUCCESS) + qla4xxx_enable_intrs(ha); } } @@ -1062,7 +1076,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) /* Issue Soft Reset to put firmware in unknown state */ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) - qla4xxx_soft_reset(ha); + qla4xxx_hw_reset(ha); /* Remove timer thread, if present */ if (ha->timer_active) @@ -1198,7 +1212,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, INIT_LIST_HEAD(&ha->free_srb_q); mutex_init(&ha->mbox_sem); - init_waitqueue_head(&ha->mailbox_wait_queue); spin_lock_init(&ha->hardware_lock); @@ -1665,6 +1678,7 @@ no_srp_cache: static void __exit qla4xxx_module_exit(void) { + ql4_mod_unload = 1; pci_unregister_driver(&qla4xxx_pci_driver); iscsi_unregister_transport(&qla4xxx_iscsi_transport); kmem_cache_destroy(srb_cachep); diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index 454e19c8ad68..e5183a697d1f 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.00.07-k" +#define QLA4XXX_DRIVER_VERSION "5.00.07-k1" -- cgit v1.2.3 From 91614c054c9ffc26b47a5cb3135113aa0f6e6ff0 Mon Sep 17 00:00:00 2001 From: Kai Makisara Date: Fri, 26 Jan 2007 00:38:39 +0200 Subject: [SCSI] st: A MTIOCTOP/MTWEOF within the early warning will cause the file number to be incorrect On Wed, 24 Jan 2007, Andrew Morton wrote: > On Mon, 22 Jan 2007 13:07:20 -0800 > bugme-daemon@bugzilla.kernel.org wrote: > > > http://bugzilla.kernel.org/show_bug.cgi?id=7864 > > > > Summary: A MTIOCTOP/MTWEOF within the early warning will cause > > the file number to be incorrect > > Kernel Version: 2.6.19.2 > > Status: NEW > > Severity: low > > Owner: io_scsi@kernel-bugs.osdl.org > > Submitter: ce_reisinger@yahoo.com > > > > > > Write records to a SCSI tape until a write fails with a ENOSPC (you have reached > > early warning. > > Now perform a: > > struct mtget before, after; > > ioctl(fd, MTIOCGET, &before); > > struct mtop mtop = { MTWEOF, 1 }; > > ioctl(fd, MTIOCTOP, &mtop); > > ioctl(fd, MTIOCGET, &after); > > > > Check the value of mt_fileno in the before and after structures. Notice the > > after is 2 greater then the before. > > > > The problem appears to be in the block of code starting at line 2817 in st.c. > > This block is entered because the drive did return a CHECK CONDITION with NO > > SENSE and the SENSE_EOM bit set. At lines 2824/5 the fileno is incremented. But > > it has already been increased by the number of filemarks requested by the > > MTIOCTOP. I believe that the residue count in the sense data should be > > subtracted from fileno, not a increment as is done. > > > > Thanks. Could you please send us a tested patch to fix these things, as > per http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt ? > The analysis is basically correct and explains the bug. According to the SCSI standards, the sense code is NO SENSE or RECOVERED ERROR in case writing filemark(s) succeeds. If it fails (partly or completely) the sense code is VOLUME OVERFLOW. The patch below is tested to fix the case when one filemark is successfully written after the EOM early warning. It should also fix the case at real EOM but this has not been tested. Carl, thanks for reporting the bug and providing the analysis for the fix. Signed-off-by: Kai Makisara Signed-off-by: James Bottomley --- drivers/scsi/st.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e016e0906e1a..488ec7948a57 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -2816,15 +2816,18 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon if (cmd_in == MTWEOF && cmdstatp->have_sense && - (cmdstatp->flags & SENSE_EOM) && - (cmdstatp->sense_hdr.sense_key == NO_SENSE || - cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) && - undone == 0) { - ioctl_result = 0; /* EOF written successfully at EOM */ - if (fileno >= 0) - fileno++; + (cmdstatp->flags & SENSE_EOM)) { + if (cmdstatp->sense_hdr.sense_key == NO_SENSE || + cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) { + ioctl_result = 0; /* EOF(s) written successfully at EOM */ + STps->eof = ST_NOEOF; + } else { /* Writing EOF(s) failed */ + if (fileno >= 0) + fileno -= undone; + if (undone < arg) + STps->eof = ST_NOEOF; + } STps->drv_file = fileno; - STps->eof = ST_NOEOF; } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) { if (fileno >= 0) STps->drv_file = fileno - undone; -- cgit v1.2.3 From c30efbaeaa9297fb1a35ef952350e0c2bb7a3d47 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sun, 28 Jan 2007 17:39:19 -0500 Subject: [AGPGART] Prevent (unlikely) memory leak in amd_create_gatt_pages() If we fail an alloc, unwind the previous allocs that succeeded. Spotted-by: Alan Grimes Signed-off-by: Dave Jones --- drivers/char/agp/amd-k7-agp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 51d0d562d01e..c85c8cadb6df 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -101,6 +101,11 @@ static int amd_create_gatt_pages(int nr_tables) for (i = 0; i < nr_tables; i++) { entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); if (entry == NULL) { + while (i > 0) { + kfree(tables[i-1]); + i--; + } + kfree(tables); retval = -ENOMEM; break; } -- cgit v1.2.3 From 87a17f31a3bc9bf0c7e7493add19ef200e741248 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sun, 28 Jan 2007 17:41:37 -0500 Subject: [AGPGART] Remove pointless typedef in ati-agp This seems to exist just to save people typing 'struct' a few times, and doesn't provide any additional value. Signed-off-by: Dave Jones --- drivers/char/agp/ati-agp.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index f244c6682738..0994d3534447 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -41,18 +41,18 @@ static struct gatt_mask ati_generic_masks[] = }; -typedef struct _ati_page_map { +struct ati_page_map { unsigned long *real; unsigned long __iomem *remapped; -} ati_page_map; +}; static struct _ati_generic_private { volatile u8 __iomem *registers; - ati_page_map **gatt_pages; + struct ati_page_map **gatt_pages; int num_tables; } ati_generic_private; -static int ati_create_page_map(ati_page_map *page_map) +static int ati_create_page_map(struct ati_page_map *page_map) { int i, err = 0; @@ -82,7 +82,7 @@ static int ati_create_page_map(ati_page_map *page_map) } -static void ati_free_page_map(ati_page_map *page_map) +static void ati_free_page_map(struct ati_page_map *page_map) { unmap_page_from_agp(virt_to_page(page_map->real)); iounmap(page_map->remapped); @@ -94,8 +94,8 @@ static void ati_free_page_map(ati_page_map *page_map) static void ati_free_gatt_pages(void) { int i; - ati_page_map **tables; - ati_page_map *entry; + struct ati_page_map **tables; + struct ati_page_map *entry; tables = ati_generic_private.gatt_pages; for (i = 0; i < ati_generic_private.num_tables; i++) { @@ -112,17 +112,17 @@ static void ati_free_gatt_pages(void) static int ati_create_gatt_pages(int nr_tables) { - ati_page_map **tables; - ati_page_map *entry; + struct ati_page_map **tables; + struct ati_page_map *entry; int retval = 0; int i; - tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL); + tables = kzalloc((nr_tables + 1) * sizeof(struct ati_page_map *),GFP_KERNEL); if (tables == NULL) return -ENOMEM; for (i = 0; i < nr_tables; i++) { - entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL); + entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); if (entry == NULL) { while (i>0) { kfree (tables[i-1]); @@ -340,7 +340,7 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, static int ati_create_gatt_table(struct agp_bridge_data *bridge) { struct aper_size_info_lvl2 *value; - ati_page_map page_dir; + struct ati_page_map page_dir; unsigned long addr; int retval; u32 temp; @@ -400,7 +400,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) static int ati_free_gatt_table(struct agp_bridge_data *bridge) { - ati_page_map page_dir; + struct ati_page_map page_dir; page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table; -- cgit v1.2.3 From 7707ea3b784195315366e6e4b5c73ca6933ff9b0 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sun, 28 Jan 2007 17:50:17 -0500 Subject: [AGPGART] Remove pointless assignment. No point in clearing local pointers then returning. Also fix up some CodingStyle nits. Signed-off-by: Dave Jones --- drivers/char/agp/ati-agp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 0994d3534447..9987dc2e0c3f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -124,18 +124,18 @@ static int ati_create_gatt_pages(int nr_tables) for (i = 0; i < nr_tables; i++) { entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); if (entry == NULL) { - while (i>0) { - kfree (tables[i-1]); + while (i > 0) { + kfree(tables[i-1]); i--; } - kfree (tables); - tables = NULL; + kfree(tables); retval = -ENOMEM; break; } tables[i] = entry; retval = ati_create_page_map(entry); - if (retval != 0) break; + if (retval != 0) + break; } ati_generic_private.num_tables = nr_tables; ati_generic_private.gatt_pages = tables; -- cgit v1.2.3 From 43ed41f648554c9fecaf7597d25e05da63ec7290 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sun, 28 Jan 2007 17:58:33 -0500 Subject: [AGPGART] Add new IDs to VIA AGP. Culled from the VIA codedrop. Also fixes up one ID used in amd64-agp to use the VIA part number instead of the board name in its ID. Signed-off-by: Dave Jones --- drivers/char/agp/amd64-agp.c | 2 +- drivers/char/agp/via-agp.c | 21 +++++++++++++++++++-- include/linux/pci_ids.h | 3 ++- 3 files changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 979300405c0e..93d2209fee4c 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -655,7 +655,7 @@ static struct pci_device_id agp_amd64_pci_table[] = { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_K8M890CE, + .device = PCI_DEVICE_ID_VIA_VT3336, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index c149ac9ce9a7..2ded7a280d7f 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -380,9 +380,23 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = /* P4M800CE */ { .device_id = PCI_DEVICE_ID_VIA_P4M800CE, - .chipset_name = "P4M800CE", + .chipset_name = "VT3314", + }, + /* CX700 */ + { + .device_id = PCI_DEVICE_ID_VIA_CX700, + .chipset_name = "CX700", + }, + /* VT3336 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3336, + .chipset_name = "VT3336", + }, + /* P4M890 */ + { + .device_id = PCI_DEVICE_ID_VIA_P4M890, + .chipset_name = "P4M890", }, - { }, /* dummy final entry, always present */ }; @@ -524,6 +538,9 @@ static const struct pci_device_id agp_via_pci_table[] = { ID(PCI_DEVICE_ID_VIA_83_87XX_1), ID(PCI_DEVICE_ID_VIA_3296_0), ID(PCI_DEVICE_ID_VIA_P4M800CE), + ID(PCI_DEVICE_ID_VIA_CX700), + ID(PCI_DEVICE_ID_VIA_VT3336), + ID(PCI_DEVICE_ID_VIA_P4M890), { } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5c87cd8a56fd..083ad66e6528 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1273,7 +1273,8 @@ #define PCI_DEVICE_ID_VIA_3296_0 0x0296 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 -#define PCI_DEVICE_ID_VIA_K8M890CE 0x0336 +#define PCI_DEVICE_ID_VIA_P4M890 0x0327 +#define PCI_DEVICE_ID_VIA_VT3336 0x0336 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C561 0x0561 -- cgit v1.2.3 From 0142f9dce8425da031d72dc3b70ee7161fcaaea2 Mon Sep 17 00:00:00 2001 From: Ahmed S. Darwish Date: Fri, 5 Jan 2007 05:44:54 +0200 Subject: [CPUFREQ] check sysfs_create_link return value Trivial patch to check sysfs_create_link return values. Fail gracefully if needed. Signed-off-by: Ahmed Darwish Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d91330432ba2..a45cc89e387a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -722,8 +722,13 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); - sysfs_create_link(&sys_dev->kobj, - &managed_policy->kobj, "cpufreq"); + ret = sysfs_create_link(&sys_dev->kobj, + &managed_policy->kobj, + "cpufreq"); + if (ret) { + mutex_unlock(&policy->lock); + goto err_out_driver_exit; + } cpufreq_debug_enable_ratelimit(); mutex_unlock(&policy->lock); @@ -770,8 +775,12 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) dprintk("CPU %u already managed, adding link\n", j); cpufreq_cpu_get(cpu); cpu_sys_dev = get_cpu_sysdev(j); - sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, - "cpufreq"); + ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, + "cpufreq"); + if (ret) { + mutex_unlock(&policy->lock); + goto err_out_unregister; + } } policy->governor = NULL; /* to assure that the starting sequence is -- cgit v1.2.3 From 4cbf2aa35e1c189db234190fefc6c83b139ef963 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 29 Jan 2007 16:38:07 -0800 Subject: [PATCH] sky2: revert IRQ dance on suspend/resume Let's just backout the IRQ hack, and for those crap machines (like some Sony VAIO's) can just disable MSI with the module parameter. This reverts 44ade178249fe53d055fd92113eaa271e06acddd. Signed-off-by: Stephen Hemminger Cc: Jeff Garzik Cc: Thomas Gleixner Cc: Frédéric Riss Signed-off-by: Linus Torvalds --- drivers/net/sky2.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a2e804ddca6c..822dd0b13133 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3639,29 +3639,6 @@ static int sky2_resume(struct pci_dev *pdev) out: return err; } - -/* BIOS resume runs after device (it's a bug in PM) - * as a temporary workaround on suspend/resume leave MSI disabled - */ -static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - - free_irq(pdev->irq, hw); - if (hw->msi) { - pci_disable_msi(pdev); - hw->msi = 0; - } - return 0; -} - -static int sky2_resume_early(struct pci_dev *pdev) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - struct net_device *dev = hw->dev[0]; - - return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw); -} #endif static struct pci_driver sky2_driver = { @@ -3672,8 +3649,6 @@ static struct pci_driver sky2_driver = { #ifdef CONFIG_PM .suspend = sky2_suspend, .resume = sky2_resume, - .suspend_late = sky2_suspend_late, - .resume_early = sky2_resume_early, #endif }; -- cgit v1.2.3 From 76398f9667e8369023ed5f4847fb59e9da8b6968 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 29 Jan 2007 12:44:41 +0100 Subject: HID: fix pb_fnmode and move it to generic HID The apple powerbook people are used to switch the pb_fnmode setting at runtime through writing to sysfs, altering the module parameter value. This was broken for them in 2.6.20-rc1 when generic HID layer was introduced, as the pb_fnmode flag was made per-hiddevice, instead of global variable. This patch moves the pb_fnmode module parameter from usbhid module to hid module, but apart from that retains backward compatibility with respect to changing the mode through sysfs. Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 11 ++++++++--- drivers/usb/input/hid-core.c | 9 --------- include/linux/hid.h | 1 - 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 981fcf01d41b..c7a6833f6821 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -35,6 +35,11 @@ #include +static int hid_pb_fnmode = 1; +module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); +MODULE_PARM_DESC(pb_fnmode, + "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); + #define unk KEY_UNKNOWN static const unsigned char hid_keyboard[256] = { @@ -154,7 +159,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, return 1; } - if (hid->pb_fnmode) { + if (hid_pb_fnmode) { int do_translate; trans = find_translation(powerbook_fn_keys, usage->code); @@ -163,8 +168,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, do_translate = 1; else if (trans->flags & POWERBOOK_FLAG_FKEY) do_translate = - (hid->pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || - (hid->pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); + (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || + (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); else do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index b86480457a2c..c6c9e72e5fd9 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -56,11 +56,6 @@ static unsigned int hid_mousepoll_interval; module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -static int usbhid_pb_fnmode = 1; -module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); -MODULE_PARM_DESC(pb_fnmode, - "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); - /* * Input submission and I/O error handler. */ @@ -1246,10 +1241,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->hiddev_hid_event = hiddev_hid_event; hid->hiddev_report_event = hiddev_report_event; #endif -#ifdef CONFIG_USB_HIDINPUT_POWERBOOK - hid->pb_fnmode = usbhid_pb_fnmode; -#endif - return hid; fail: diff --git a/include/linux/hid.h b/include/linux/hid.h index 770120add15a..342b4e639acb 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -438,7 +438,6 @@ struct hid_device { /* device report descriptor */ struct hid_usage *, __s32); void (*hiddev_report_event) (struct hid_device *, struct hid_report *); #ifdef CONFIG_USB_HIDINPUT_POWERBOOK - unsigned int pb_fnmode; unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; #endif -- cgit v1.2.3 From 5dcade90db19205b9ebb8241a22664560973f81a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 28 Jan 2007 21:33:44 +0300 Subject: pata_sil680: PIO1 taskfile transfers overclocking fix (repost) Fix PIO mode 1 overclocked taskfile transfers -- probably a typo carried over from drivers/ide/pci/siimage.c where I've found it by documentation check... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_sil680.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 32cf0bfa8921..e8dfd8fc3ff7 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -135,7 +135,7 @@ static void sil680_error_handler(struct ata_port *ap) static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) { static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; - static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 }; + static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 }; unsigned long tfaddr = sil680_selreg(ap, 0x02); unsigned long addr = sil680_seldev(ap, adev, 0x04); -- cgit v1.2.3 From 7a0f1c8a4b1052da7efc7715e2e557255b632712 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 29 Jan 2007 13:28:47 +0100 Subject: ata_if_xfermask() word 51 fix If word 53 bit 1 isn't set, the maximum PIO mode is indicated by the upper 8 bits of word 51, not the lower 8 bits. Fixes PIO mode detection on old Compact Flash cards. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a388a8df0043..cf707029352e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1037,7 +1037,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * the PIO timing number for the maximum. Turn it into * a mask. */ - u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; + u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; if (mode < 5) /* Valid PIO range */ pio_mask = (2 << mode) - 1; else -- cgit v1.2.3 From 2ca6611b1fc1f913f5370b3c50a0a35d817491b3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 30 Jan 2007 00:59:14 -0800 Subject: pata_platform: set_mode fix drivers/ata/pata_platform.c:85: warning: initialization from incompatible pointer type Cc: Jeff Garzik Cc: Tejun Heo Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 443b1d85c6c4..ca2999f9f048 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -30,7 +30,8 @@ static int pio_mask = 1; * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static void pata_platform_set_mode(struct ata_port *ap) +static int pata_platform_set_mode(struct ata_port *ap, + struct ata_device **r_failed_dev) { int i; @@ -44,6 +45,7 @@ static void pata_platform_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void pata_platform_host_stop(struct ata_host *host) -- cgit v1.2.3 From af068bd1debcc76c1bc265aa01401901bf0067ed Mon Sep 17 00:00:00 2001 From: David Milburn Date: Tue, 30 Jan 2007 00:59:15 -0800 Subject: libata-scsi: ata_task_ioctl should return ATA registers from sense data User applications using the HDIO_DRIVE_TASK ioctl through libata expect specific ATA registers to be returned to userspace. Verified that ata_task_ioctl correctly returns register values to the smartctl application. Signed-off-by: David Milburn Acked-by: Tejun Heo Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 51 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7cc5a4a910a4..d151cf057ef2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -273,8 +273,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) { int rc = 0; u8 scsi_cmd[MAX_COMMAND_SIZE]; - u8 args[7]; - struct scsi_sense_hdr sshdr; + u8 args[7], *sensebuf = NULL; + int cmd_result; if (arg == NULL) return -EINVAL; @@ -282,10 +282,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) if (copy_from_user(args, arg, sizeof(args))) return -EFAULT; + sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); + if (!sensebuf) + return -ENOMEM; + memset(scsi_cmd, 0, sizeof(scsi_cmd)); scsi_cmd[0] = ATA_16; scsi_cmd[1] = (3 << 1); /* Non-data */ - /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ + scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ scsi_cmd[4] = args[1]; scsi_cmd[6] = args[2]; scsi_cmd[8] = args[3]; @@ -295,11 +299,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ - if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, - (10*HZ), 5)) + cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0, + sensebuf, (10*HZ), 5, 0); + + if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ + u8 *desc = sensebuf + 8; + cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ + + /* If we set cc then ATA pass-through will cause a + * check condition even if no error. Filter that. */ + if (cmd_result & SAM_STAT_CHECK_CONDITION) { + struct scsi_sense_hdr sshdr; + scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, + &sshdr); + if (sshdr.sense_key==0 && + sshdr.asc==0 && sshdr.ascq==0) + cmd_result &= ~SAM_STAT_CHECK_CONDITION; + } + + /* Send userspace ATA registers */ + if (sensebuf[0] == 0x72 && /* format is "descriptor" */ + desc[0] == 0x09) {/* code is "ATA Descriptor" */ + args[0] = desc[13]; /* status */ + args[1] = desc[3]; /* error */ + args[2] = desc[5]; /* sector count (0:7) */ + args[3] = desc[7]; /* lbal */ + args[4] = desc[9]; /* lbam */ + args[5] = desc[11]; /* lbah */ + args[6] = desc[12]; /* select */ + if (copy_to_user(arg, args, sizeof(args))) + rc = -EFAULT; + } + } + + if (cmd_result) { rc = -EIO; + goto error; + } - /* Need code to retrieve data from check condition? */ + error: + kfree(sensebuf); return rc; } -- cgit v1.2.3 From 78981a7c6c34bddbb90da72cf6ce10953e84aad8 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 30 Jan 2007 00:59:18 -0800 Subject: libata: fix translation for START STOP UNIT libata's SCSI translation for the SCSI START STOP UNIT command with the START bit clear (i.e. stopping the drive) appears to be incorrect. It sends an ATA STANDBY command with the time period set to 0, which the code comment says means "now", but the ATA standard says this means disable the standby timer, which effectively does nothing. Change this to issue a STANDBY IMMEDIATE command which will actually spin the drive down. The SAT (SCSI/ATA Translation) standard revision 9 concurs with this choice. Signed-off-by: Robert Hancock Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d151cf057ef2..73902d335767 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1022,11 +1022,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) } tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ - } else { - tf->nsect = 0; /* time period value (0 implies now) */ - tf->command = ATA_CMD_STANDBY; - /* Consider: ATA STANDBY IMMEDIATE command */ - } + } else + /* Issue ATA STANDBY IMMEDIATE command */ + tf->command = ATA_CMD_STANDBYNOW1; + /* * Standby and Idle condition timers could be implemented but that * would require libata to implement the Power condition mode page -- cgit v1.2.3 From 5fc7d61aee1a7f7d3448f8fbccaa93371ebeecb0 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Jan 2007 23:59:57 -0800 Subject: b44: Fix frequent link changes This fixes the issue of frequent link changes under heavy traffic reported below: http://bugzilla.kernel.org/show_bug.cgi?id=7696 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=216338 The b44 chip occasionally needs to be reset when ISTAT_ERRORS are encountered. The reset sequence includes a PHY reset that will take many seconds to complete and cause the link to go down and up. By skipping the PHY reset, it will greatly reduce the interruption when ISTAT_ERRORS are encountered. Change the full_reset parameter to reset_kind parameter in b44_init_hw(). This will allow PHY reset to be skipped when ISTAT_ERRORS are encountered. Signed-off-by: Michael Chan Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5eb2ec68393f..1c8fb8e7df59 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -110,6 +110,11 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); static void b44_halt(struct b44 *); static void b44_init_rings(struct b44 *); + +#define B44_FULL_RESET 1 +#define B44_FULL_RESET_SKIP_PHY 2 +#define B44_PARTIAL_RESET 3 + static void b44_init_hw(struct b44 *, int); static int dma_desc_align_mask; @@ -884,7 +889,7 @@ static int b44_poll(struct net_device *netdev, int *budget) spin_lock_irqsave(&bp->lock, flags); b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); netif_wake_queue(bp->dev); spin_unlock_irqrestore(&bp->lock, flags); done = 1; @@ -954,7 +959,7 @@ static void b44_tx_timeout(struct net_device *dev) b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); spin_unlock_irq(&bp->lock); @@ -1071,7 +1076,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) b44_halt(bp); dev->mtu = new_mtu; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); spin_unlock_irq(&bp->lock); b44_enable_ints(bp); @@ -1368,12 +1373,12 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) * packet processing. Invoked with bp->lock held. */ static void __b44_set_rx_mode(struct net_device *); -static void b44_init_hw(struct b44 *bp, int full_reset) +static void b44_init_hw(struct b44 *bp, int reset_kind) { u32 val; b44_chip_reset(bp); - if (full_reset) { + if (reset_kind == B44_FULL_RESET) { b44_phy_reset(bp); b44_setup_phy(bp); } @@ -1390,7 +1395,10 @@ static void b44_init_hw(struct b44 *bp, int full_reset) bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ - if (full_reset) { + if (reset_kind == B44_PARTIAL_RESET) { + bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + } else { bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | @@ -1401,9 +1409,6 @@ static void b44_init_hw(struct b44 *bp, int full_reset) bp->rx_prod = bp->rx_pending; bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); - } else { - bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); } val = br32(bp, B44_ENET_CTRL); @@ -1420,7 +1425,7 @@ static int b44_open(struct net_device *dev) goto out; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); b44_check_phy(bp); @@ -1629,7 +1634,7 @@ static int b44_close(struct net_device *dev) netif_poll_enable(dev); if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); + b44_init_hw(bp, B44_PARTIAL_RESET); b44_setup_wol(bp); } @@ -1905,7 +1910,7 @@ static int b44_set_ringparam(struct net_device *dev, b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); @@ -1948,7 +1953,7 @@ static int b44_set_pauseparam(struct net_device *dev, if (bp->flags & B44_FLAG_PAUSE_AUTO) { b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); } else { __b44_set_flow_ctrl(bp, bp->flags); } @@ -2304,7 +2309,7 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) free_irq(dev->irq, dev); if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); + b44_init_hw(bp, B44_PARTIAL_RESET); b44_setup_wol(bp); } pci_disable_device(pdev); @@ -2329,7 +2334,7 @@ static int b44_resume(struct pci_dev *pdev) spin_lock_irq(&bp->lock); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); netif_device_attach(bp->dev); spin_unlock_irq(&bp->lock); -- cgit v1.2.3 From 0c0b3ae68ec93b1db5c637d294647d1cca0df763 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 27 Jan 2007 00:00:01 -0800 Subject: net: ifb error path loop fix On error we should start freeing resources at [i-1] not [i-2]. Signed-off-by: Mariusz Kozlowski Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/ifb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ca2b21f9d444..c4ca7c930a46 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -271,8 +271,7 @@ static int __init ifb_init_module(void) for (i = 0; i < numifbs && !err; i++) err = ifb_init_one(i); if (err) { - i--; - while (--i >= 0) + while (i--) ifb_free_one(i); } -- cgit v1.2.3 From b1f54ba34f9e036ab515bbac0c01d17300e1c79a Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Sat, 27 Jan 2007 00:00:04 -0800 Subject: FS_ENET: OF-related fixup for FEC and SCC MAC's Updated direct resource pass with ioremap call, make it grant proper IRQ mapping, stuff incompatible with the new approach were respectively put under #ifndef CONFIG_PPC_MERGE. It is required so that both ppc and powerpc could utilize fs_enet effectively. Signed-off-by: Vitaly Bordug Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/fs_enet/mac-fec.c | 13 +++++++++---- drivers/net/fs_enet/mac-scc.c | 6 ++++-- drivers/net/phy/fixed.c | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index c2c5fd419bd0..ff6839477306 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -104,9 +104,9 @@ static int do_pd_setup(struct fs_enet_private *fep) fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); if (fep->interrupt < 0) return -EINVAL; - + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - fep->fec.fecp =(void*)r->start; + fep->fec.fecp = ioremap(r->start, r->end - r->start + 1); if(fep->fec.fecp == NULL) return -EINVAL; @@ -319,11 +319,14 @@ static void restart(struct net_device *dev) * Clear any outstanding interrupt. */ FW(fecp, ievent, 0xffc0); +#ifndef CONFIG_PPC_MERGE FW(fecp, ivec, (fep->interrupt / 2) << 29); - +#else + FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); +#endif /* - * adjust to speed (only for DUET & RMII) + * adjust to speed (only for DUET & RMII) */ #ifdef CONFIG_DUET if (fpi->use_rmii) { @@ -418,6 +421,7 @@ static void stop(struct net_device *dev) static void pre_request_irq(struct net_device *dev, int irq) { +#ifndef CONFIG_PPC_MERGE immap_t *immap = fs_enet_immap; u32 siel; @@ -431,6 +435,7 @@ static void pre_request_irq(struct net_device *dev, int irq) siel &= ~(0x80000000 >> (irq & ~1)); out_be32(&immap->im_siu_conf.sc_siel, siel); } +#endif } static void post_free_irq(struct net_device *dev, int irq) diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 95ec5872c507..afd7fca7c6c4 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -121,13 +121,13 @@ static int do_pd_setup(struct fs_enet_private *fep) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - fep->scc.sccp = (void *)r->start; + fep->scc.sccp = ioremap(r->start, r->end - r->start + 1); if (fep->scc.sccp == NULL) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"); - fep->scc.ep = (void *)r->start; + fep->scc.ep = ioremap(r->start, r->end - r->start + 1); if (fep->scc.ep == NULL) return -EINVAL; @@ -397,6 +397,7 @@ static void stop(struct net_device *dev) static void pre_request_irq(struct net_device *dev, int irq) { +#ifndef CONFIG_PPC_MERGE immap_t *immap = fs_enet_immap; u32 siel; @@ -410,6 +411,7 @@ static void pre_request_irq(struct net_device *dev, int irq) siel &= ~(0x80000000 >> (irq & ~1)); out_be32(&immap->im_siu_conf.sc_siel, siel); } +#endif } static void post_free_irq(struct net_device *dev, int irq) diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 096d4a100bf2..86135397f430 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -349,7 +349,7 @@ static int __init fixed_init(void) fixed_mdio_register_device(0, 100, 1); #endif -#ifdef CONFIX_FIXED_MII_10_FDX +#ifdef CONFIG_FIXED_MII_10_FDX fixed_mdio_register_device(0, 10, 1); #endif return 0; -- cgit v1.2.3 From 9e8e83d1ba0b248de34062a61f4f5d378a5dbd53 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 27 Jan 2007 00:00:04 -0800 Subject: 82596 warning fixes drivers/net/82596.c: In function 'i596_start_xmit': drivers/net/82596.c:1069: warning: cast from pointer to integer of different size drivers/net/82596.c: In function 'i82596_probe': drivers/net/82596.c:1249: warning: format '%d' expects type 'int', but argument 4 has type 'long unsigned int' Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/82596.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 8236f26ffd46..640d7ca2ebcf 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1066,8 +1066,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) short length = skb->len; dev->trans_start = jiffies; - DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name, - skb->len, (unsigned int)skb->data)); + DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n", + dev->name, skb->len, skb->data)); if (skb->len < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) @@ -1246,7 +1246,8 @@ struct net_device * __init i82596_probe(int unit) dev->priv = (void *)(dev->mem_start); lp = dev->priv; - DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n", + DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%zd bytes), " + "lp->scb at 0x%08lx\n", dev->name, (unsigned long)lp, sizeof(struct i596_private), (unsigned long)&lp->scb)); memset((void *) lp, 0, sizeof(struct i596_private)); -- cgit v1.2.3 From 9c750b7d14301b710c13247f7cc28abd614d9f5c Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 29 Jan 2007 18:44:01 +0100 Subject: ehea: Fixed wrong jumbo frames status query This patch fixes the wrong query and logging of the per interface jumbo frames enabled/disabled status. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 2 +- drivers/net/ehea/ehea_main.c | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index be10a3a26b5b..272e1ec51aa2 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0044" +#define DRV_VERSION "EHEA_0045" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 1072e69ef85d..d4635bf3128c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2316,6 +2316,7 @@ static int ehea_setup_single_port(struct ehea_port *port, struct ehea_adapter *adapter = port->adapter; struct hcp_ehea_port_cb4 *cb4; u32 *dn_log_port_id; + int jumbo = 0; sema_init(&port->port_lock, 1); port->state = EHEA_PORT_DOWN; @@ -2357,13 +2358,25 @@ static int ehea_setup_single_port(struct ehea_port *port, if (!cb4) { ehea_error("no mem for cb4"); } else { - cb4->jumbo_frame = 1; - hret = ehea_h_modify_ehea_port(adapter->handle, - port->logical_port_id, - H_PORT_CB4, H_PORT_CB4_JUMBO, - cb4); - if (hret != H_SUCCESS) { - ehea_info("Jumbo frames not activated"); + hret = ehea_h_query_ehea_port(adapter->handle, + port->logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, cb4); + + if (hret == H_SUCCESS) { + if (cb4->jumbo_frame) + jumbo = 1; + else { + cb4->jumbo_frame = 1; + hret = ehea_h_modify_ehea_port(adapter->handle, + port-> + logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, + cb4); + if (hret == H_SUCCESS) + jumbo = 1; + } } kfree(cb4); } @@ -2402,6 +2415,9 @@ static int ehea_setup_single_port(struct ehea_port *port, goto out_free; } + ehea_info("%s: Jumbo frames are %sabled", dev->name, + jumbo == 1 ? "en" : "dis"); + port->netdev = dev; ret = 0; goto out; -- cgit v1.2.3 From d4150a2731615de5cd4527a23435aaa7396c63c6 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 29 Jan 2007 18:44:41 +0100 Subject: ehea: Fixed missing tasklet_kill() call NEQ-Tasklet wasn't killed when module is removed. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d4635bf3128c..9de2d38a5321 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2598,6 +2598,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) destroy_workqueue(adapter->ehea_wq); ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); + tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq); -- cgit v1.2.3 From f8a8ccd56d82bd4f4b5c7c2e7eb758c7764d98e1 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Mon, 29 Jan 2007 12:08:38 -0800 Subject: bonding: ARP monitoring broken on x86_64 While working with the latest bonding code I noticed a nasty problem that will prevent arp monitoring from always functioning correctly on x86_64 systems. Comparing ints to longs and expecting reliable results on x86_64 is a bad idea. With this patch, arp monitoring works correctly again. Signed-off-by: Andy Gospodarek Cc: "David S. Miller" Cc: Stephen Hemminger Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/bonding/bonding.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index dc434fb6da85..0978c9ac6d2b 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -151,8 +151,8 @@ struct slave { struct slave *next; struct slave *prev; int delay; - u32 jiffies; - u32 last_arp_rx; + unsigned long jiffies; + unsigned long last_arp_rx; s8 link; /* one of BOND_LINK_XXXX */ s8 state; /* one of BOND_STATE_XXXX */ u32 original_flags; @@ -242,7 +242,8 @@ extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slav return bond->params.arp_validate & (1 << slave->state); } -extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave) +extern inline unsigned long slave_last_rx(struct bonding *bond, + struct slave *slave) { if (slave_do_arp_validate(bond, slave)) return slave->last_arp_rx; -- cgit v1.2.3 From 518d83382568964ca9657511140398ebac925ecd Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 29 Jan 2007 14:31:16 -0800 Subject: e100: fix irq leak on suspend/resume e100: fix irq leak on suspend/resume From: Frederik Deweerdt The e100_resume() function should be calling netif_device_detach and free_irq. This fixes multiple irq's being allocated after resume. Signed-off-by: Frederik Deweerdt Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e100.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index c2ae2a24629b..3208dac29168 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2725,6 +2725,7 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); + netif_device_detach(netdev); pci_save_state(pdev); if ((nic->flags & wol_magic) | e100_asf(nic)) { @@ -2736,6 +2737,7 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) } pci_disable_device(pdev); + free_irq(pdev->irq, netdev); pci_set_power_state(pdev, PCI_D3hot); return 0; -- cgit v1.2.3 From 00576e93805bd4f2dd2649e354726dee872d1e8a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:50 +0000 Subject: b44: src_desc->addr is little-endian Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 1c8fb8e7df59..26b9295cb9b7 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -757,7 +757,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dest_idx * sizeof(dest_desc), DMA_BIDIRECTIONAL); - pci_dma_sync_single_for_device(bp->pdev, src_desc->addr, + pci_dma_sync_single_for_device(bp->pdev, le32_to_cpu(src_desc->addr), RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); } -- cgit v1.2.3 From 90afd0e574a1a739aeb62e30d556ebf0289389e5 Mon Sep 17 00:00:00 2001 From: Dmitriy Monakhov Date: Sat, 27 Jan 2007 00:00:03 -0800 Subject: Broadcom 4400 resume small fix Some issues in b44_resume(). - Return value of pci_enable_device() was ignored. - If request_irq() has failed we have to just disable device and exit. Signed-off-by: Dmitriy Monakhov Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 26b9295cb9b7..303a8d94ad4b 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2320,16 +2320,27 @@ static int b44_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct b44 *bp = netdev_priv(dev); + int rc = 0; pci_restore_state(pdev); - pci_enable_device(pdev); + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR PFX "%s: pci_enable_device failed\n", + dev->name); + return rc; + } + pci_set_master(pdev); if (!netif_running(dev)) return 0; - if (request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev)) + rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); + if (rc) { printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); + pci_disable_device(pdev); + return rc; + } spin_lock_irq(&bp->lock); -- cgit v1.2.3 From 49b14f24cc5aa962446515c9df501192eda99bd4 Mon Sep 17 00:00:00 2001 From: Robert P. J. Day Date: Mon, 29 Jan 2007 13:19:50 -0800 Subject: [PATCH] Fix "CONFIG_X86_64_" typo in drivers/kvm/svm.c Fix what looks like an obvious typo in the file drivers/kvm/svm.c. Signed-off-by: Robert P. J. Day Acked-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 9c70ff65e6b7..c79df79307ed 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -1163,7 +1163,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) case MSR_K6_STAR: vcpu->svm->vmcb->save.star = data; break; -#ifdef CONFIG_X86_64_ +#ifdef CONFIG_X86_64 case MSR_LSTAR: vcpu->svm->vmcb->save.lstar = data; break; -- cgit v1.2.3 From a12743026ceb34388b9b983801ba99240cb0a199 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:30 +0000 Subject: [PATCH] mtd/nand/cafe.c missing include of dma-mapping.h Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/mtd/nand/cafe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/cafe.c b/drivers/mtd/nand/cafe.c index b8d9b64cccc0..65f9bd3ceebf 100644 --- a/drivers/mtd/nand/cafe.c +++ b/drivers/mtd/nand/cafe.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #define CAFE_NAND_CTRL1 0x00 -- cgit v1.2.3 From 9a696b4f3c5664c2c4815cc8e37256e51a3425e1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:35 +0000 Subject: [PATCH] sym53c500_cs: remove bogus call fo free_dma() What DMA for 16bit pcmcia card, anyway? We never do request_dma() there and ->dma_channel never changes since initialization to -1. IOW, that call is dead code. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/scsi/pcmcia/sym53c500_cs.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 9fb0ea5c1fb9..5b458d2478f7 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -545,8 +545,6 @@ SYM53C500_release(struct pcmcia_device *link) */ if (shost->irq) free_irq(shost->irq, shost); - if (shost->dma_channel != 0xff) - free_dma(shost->dma_channel); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); -- cgit v1.2.3 From 161c888b0b4d28775dfe35274ee90c16a91b4365 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:45 +0000 Subject: [PATCH] pata_platform: fallout from set_mode() change Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/ata/pata_platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 443b1d85c6c4..40ae11cbfda4 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -30,7 +30,7 @@ static int pio_mask = 1; * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static void pata_platform_set_mode(struct ata_port *ap) +static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -44,6 +44,7 @@ static void pata_platform_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void pata_platform_host_stop(struct ata_host *host) -- cgit v1.2.3 From 774ba59c950926abd27421fa146f1916de89e6f6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:50 +0000 Subject: [PATCH] b44: src_desc->addr is little-endian Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/b44.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5eb2ec68393f..cfc89bc105b1 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -752,7 +752,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dest_idx * sizeof(dest_desc), DMA_BIDIRECTIONAL); - pci_dma_sync_single_for_device(bp->pdev, src_desc->addr, + pci_dma_sync_single_for_device(bp->pdev, le32_to_cpu(src_desc->addr), RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); } -- cgit v1.2.3 From bcdddfb66cc998252d34758ce4109cedc0d24a5c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 30 Jan 2007 14:11:12 -0800 Subject: Revert "net: ifb error path loop fix" This reverts commit 0c0b3ae68ec93b1db5c637d294647d1cca0df763. Quoth David: "Jeff, please revert It's wrong. We had a lengthy analysis of this piece of code several months ago, and it is correct. Consider, if we run the loop and we get an error the following happens: 1) attempt of ifb_init_one(i) fails, therefore we should not try to "ifb_free_one()" on "i" since it failed 2) the loop iteration first increments "i", then it check for error Therefore we must decrement "i" twice before the first free during the cleanup. One to "undo" the for() loop increment, and one to "skip" the ifb_init_one() case which failed." Reported-by: David Miller Acked-by: Jeff Garzik Cc: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/ifb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index c4ca7c930a46..ca2b21f9d444 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -271,7 +271,8 @@ static int __init ifb_init_module(void) for (i = 0; i < numifbs && !err; i++) err = ifb_init_one(i); if (err) { - while (i--) + i--; + while (--i >= 0) ifb_free_one(i); } -- cgit v1.2.3 From c06bb5d49d8b240876c7c5019197e6a7bd33bcf7 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 30 Jan 2007 14:36:09 -0800 Subject: [PATCH] Fix VIA quirks Fix VIA quirks that were recently broken by Alan Cox in the upstream kernel (commit 1597cacbe39802d86656d1f2e6329895bd2ef531). My understanding is that pci_find_present() doesn't work yet at the time the quirks are run. So I used a two-step quirk as is done for some other quirks already. First we detect the VIA south bridges and set the right low and high device limits, then we are ready to actually run the quirks on the affected devices. Signed-off-by: Jean Delvare Acked-by: Alan Cox Acked-by: Nick Piggin Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 78 ++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ef882a8a094e..16945c2ba2ca 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -654,19 +654,40 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi * VIA bridges which have VLink */ -static const struct pci_device_id via_vlink_fixup_tbl[] = { - /* Internal devices need IRQ line routing, pre VLink */ - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, - /* Devices with VLink */ - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, - { 0, }, -}; +static int via_vlink_dev_lo = -1, via_vlink_dev_hi = 18; + +static void quirk_via_bridge(struct pci_dev *dev) +{ + /* See what bridge we have and find the device ranges */ + switch (dev->device) { + case PCI_DEVICE_ID_VIA_82C686: + /* 82C686 is special */ + via_vlink_dev_lo = 7; + via_vlink_dev_hi = 7; + break; + case PCI_DEVICE_ID_VIA_8237: + case PCI_DEVICE_ID_VIA_8237A: + via_vlink_dev_lo = 15; + break; + case PCI_DEVICE_ID_VIA_8235: + via_vlink_dev_lo = 16; + break; + case PCI_DEVICE_ID_VIA_8231: + case PCI_DEVICE_ID_VIA_8233_0: + case PCI_DEVICE_ID_VIA_8233A: + case PCI_DEVICE_ID_VIA_8233C_0: + via_vlink_dev_lo = 17; + break; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A, quirk_via_bridge); /** * quirk_via_vlink - VIA VLink IRQ number update @@ -675,35 +696,20 @@ static const struct pci_device_id via_vlink_fixup_tbl[] = { * If the device we are dealing with is on a PIC IRQ we need to * ensure that the IRQ line register which usually is not relevant * for PCI cards, is actually written so that interrupts get sent - * to the right place + * to the right place. + * We only do this on systems where a VIA south bridge was detected, + * and only for VIA devices on the motherboard (see quirk_via_bridge + * above). */ static void quirk_via_vlink(struct pci_dev *dev) { - const struct pci_device_id *via_vlink_fixup; - static int dev_lo = -1, dev_hi = 18; u8 irq, new_irq; - /* Check if we have VLink and cache the result */ - - /* Checked already - no */ - if (dev_lo == -2) + /* Check if we have VLink at all */ + if (via_vlink_dev_lo == -1) return; - /* Not checked - see what bridge we have and find the device - ranges */ - - if (dev_lo == -1) { - via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); - if (via_vlink_fixup == NULL) { - dev_lo = -2; - return; - } - dev_lo = via_vlink_fixup->driver_data; - /* 82C686 is special - 0/0 */ - if (dev_lo == 0) - dev_hi = 0; - } new_irq = dev->irq; /* Don't quirk interrupts outside the legacy IRQ range */ @@ -711,8 +717,8 @@ static void quirk_via_vlink(struct pci_dev *dev) return; /* Internal device ? */ - if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || - PCI_SLOT(dev->devfn) < dev_lo) + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > via_vlink_dev_hi || + PCI_SLOT(dev->devfn) < via_vlink_dev_lo) return; /* This is an internal VLink device on a PIC interrupt. The BIOS -- cgit v1.2.3 From 99abaf51e25f7d4ac2081e5cdc1f01baa0543514 Mon Sep 17 00:00:00 2001 From: ethanhsiao@jmicron.com Date: Tue, 30 Jan 2007 14:36:13 -0800 Subject: [PATCH] jmicron: 40/80pin primary detection jmicron module detects all JMB36x as JMB361 and PATA0 has wrong pin status of XICBLID. Cc: Jeff Garzik Cc: Alan Cox Cc: Bartlomiej Zolnierkiewicz Cc: Sergei Shtylyov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/jmicron.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index 35dda8fcd0ac..f07bbbed1778 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -86,8 +86,8 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif) { case PORT_PATA0: if (control & (1 << 3)) /* 40/80 pin primary */ - return 1; - return 0; + return 0; + return 1; case PORT_PATA1: if (control5 & (1 << 19)) /* 40/80 pin secondary */ return 0; @@ -241,11 +241,11 @@ static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_devi } static struct pci_device_id jmicron_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, { 0, }, }; -- cgit v1.2.3 From 41c57a87183a7c458d86f78966d69d4bf18ea0b7 Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Tue, 30 Jan 2007 14:36:25 -0800 Subject: [PATCH] IPMI: fix timeout list handling Fix a dangling pointer bug in ipmi_timeout_handler. A list of timedout messages is not re-initialized before reuse, causing the head of the list to point to freed memory. Signed-off-by: David Barksdale Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4e4691a53890..53582b53da95 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -3649,8 +3649,6 @@ static void ipmi_timeout_handler(long timeout_period) unsigned long flags; int i; - INIT_LIST_HEAD(&timeouts); - rcu_read_lock(); list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { /* See if any waiting messages need to be processed. */ @@ -3671,6 +3669,7 @@ static void ipmi_timeout_handler(long timeout_period) /* Go through the seq table and find any messages that have timed out, putting them in the timeouts list. */ + INIT_LIST_HEAD(&timeouts); spin_lock_irqsave(&intf->seq_lock, flags); for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) check_msg_timeout(intf, &(intf->seq_table[i]), -- cgit v1.2.3 From a608ab9cb6a5050394498b2520c6e7c162f4e2cf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Jan 2007 10:39:10 +0000 Subject: netxen patches Have fun. >From 24f4a1a77431575a9cdfaae25adda85842099f70 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 1 Jan 2007 15:22:56 -0500 Subject: [PATCH] netxen trivial annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 136 +++++++++++++++----------------- drivers/net/netxen/netxen_nic_ethtool.c | 22 +++--- drivers/net/netxen/netxen_nic_hw.c | 43 +++++----- drivers/net/netxen/netxen_nic_hw.h | 74 ++++++++--------- drivers/net/netxen/netxen_nic_init.c | 15 ++-- drivers/net/netxen/netxen_nic_isr.c | 4 +- drivers/net/netxen/netxen_nic_main.c | 8 +- drivers/net/netxen/netxen_nic_niu.c | 106 ++++++++++++------------- 8 files changed, 196 insertions(+), 212 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 59324b1693d6..e8598b809228 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -239,49 +239,39 @@ extern unsigned long long netxen_dma_mask; typedef u32 netxen_ctx_msg; -#define _netxen_set_bits(config_word, start, bits, val) {\ - unsigned long long mask = (((1ULL << (bits)) - 1) << (start)); \ - unsigned long long value = (val); \ - (config_word) &= ~mask; \ - (config_word) |= (((value) << (start)) & mask); \ -} - #define netxen_set_msg_peg_id(config_word, val) \ - _netxen_set_bits(config_word, 0, 2, val) + ((config_word) &= ~3, (config_word) |= val & 3) #define netxen_set_msg_privid(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_set_msg_count(config_word, val) \ - _netxen_set_bits(config_word, 3, 15, val) + ((config_word) &= ~(0x7fff<<3), (config_word) |= (val & 0x7fff) << 3) #define netxen_set_msg_ctxid(config_word, val) \ - _netxen_set_bits(config_word, 18, 10, val) + ((config_word) &= ~(0x3ff<<18), (config_word) |= (val & 0x3ff) << 18) #define netxen_set_msg_opcode(config_word, val) \ - _netxen_set_bits(config_word, 28, 4, val) + ((config_word) &= ~(0xf<<24), (config_word) |= (val & 0xf) << 24) struct netxen_rcv_context { - u32 rcv_ring_addr_lo; - u32 rcv_ring_addr_hi; - u32 rcv_ring_size; - u32 rsrvd; + __le64 rcv_ring_addr; + __le32 rcv_ring_size; + __le32 rsrvd; }; struct netxen_ring_ctx { /* one command ring */ - u64 cmd_consumer_offset; - u32 cmd_ring_addr_lo; - u32 cmd_ring_addr_hi; - u32 cmd_ring_size; - u32 rsrvd; + __le64 cmd_consumer_offset; + __le64 cmd_ring_addr; + __le32 cmd_ring_size; + __le32 rsrvd; /* three receive rings */ struct netxen_rcv_context rcv_ctx[3]; /* one status ring */ - u32 sts_ring_addr_lo; - u32 sts_ring_addr_hi; - u32 sts_ring_size; + __le64 sts_ring_addr; + __le32 sts_ring_size; - u32 ctx_id; + __le32 ctx_id; } __attribute__ ((aligned(64))); /* @@ -305,81 +295,85 @@ struct netxen_ring_ctx { ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) #define netxen_set_cmd_desc_flags(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val) + ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ + (cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f)) #define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val) + ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \ + (cmd_desc)->flags_opcode |= cpu_to_le16((val) & (0x3f<<7))) #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val); + ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \ + (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff)) #define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val); + ((cmd_desc)->num_of_buffers_total_length &= cpu_to_le32(0xff), \ + (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 24)) #define netxen_get_cmd_desc_opcode(cmd_desc) \ - (((cmd_desc)->flags_opcode >> 7) & 0x003F) + ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F) #define netxen_get_cmd_desc_totallength(cmd_desc) \ - (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF) + (le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ u8 ip_hdr_offset; /* For LSO only */ /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */ - u16 flags_opcode; + __le16 flags_opcode; /* Bit pattern: 0-7 total number of segments, 8-31 Total size of the packet */ - u32 num_of_buffers_total_length; + __le32 num_of_buffers_total_length; union { struct { - u32 addr_low_part2; - u32 addr_high_part2; + __le32 addr_low_part2; + __le32 addr_high_part2; }; - u64 addr_buffer2; + __le64 addr_buffer2; }; - u16 reference_handle; /* changed to u16 to add mss */ - u16 mss; /* passed by NDIS_PACKET for LSO */ + __le16 reference_handle; /* changed to u16 to add mss */ + __le16 mss; /* passed by NDIS_PACKET for LSO */ /* Bit pattern 0-3 port, 0-3 ctx id */ u8 port_ctxid; u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */ - u16 conn_id; /* IPSec offoad only */ + __le16 conn_id; /* IPSec offoad only */ union { struct { - u32 addr_low_part3; - u32 addr_high_part3; + __le32 addr_low_part3; + __le32 addr_high_part3; }; - u64 addr_buffer3; + __le64 addr_buffer3; }; union { struct { - u32 addr_low_part1; - u32 addr_high_part1; + __le32 addr_low_part1; + __le32 addr_high_part1; }; - u64 addr_buffer1; + __le64 addr_buffer1; }; - u16 buffer1_length; - u16 buffer2_length; - u16 buffer3_length; - u16 buffer4_length; + __le16 buffer1_length; + __le16 buffer2_length; + __le16 buffer3_length; + __le16 buffer4_length; union { struct { - u32 addr_low_part4; - u32 addr_high_part4; + __le32 addr_low_part4; + __le32 addr_high_part4; }; - u64 addr_buffer4; + __le64 addr_buffer4; }; - u64 unused; + __le64 unused; } __attribute__ ((aligned(64))); /* Note: sizeof(rcv_desc) should always be a mutliple of 2 */ struct rcv_desc { - u16 reference_handle; - u16 reserved; - u32 buffer_length; /* allocated buffer length (usually 2K) */ - u64 addr_buffer; + __le16 reference_handle; + __le16 reserved; + __le32 buffer_length; /* allocated buffer length (usually 2K) */ + __le64 addr_buffer; }; /* opcode field in status_desc */ @@ -405,36 +399,36 @@ struct rcv_desc { (((status_desc)->lro & 0x80) >> 7) #define netxen_get_sts_port(status_desc) \ - ((status_desc)->status_desc_data & 0x0F) + (le64_to_cpu((status_desc)->status_desc_data) & 0x0F) #define netxen_get_sts_status(status_desc) \ - (((status_desc)->status_desc_data >> 4) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 4) & 0x0F) #define netxen_get_sts_type(status_desc) \ - (((status_desc)->status_desc_data >> 8) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 8) & 0x0F) #define netxen_get_sts_totallength(status_desc) \ - (((status_desc)->status_desc_data >> 12) & 0xFFFF) + ((le64_to_cpu((status_desc)->status_desc_data) >> 12) & 0xFFFF) #define netxen_get_sts_refhandle(status_desc) \ - (((status_desc)->status_desc_data >> 28) & 0xFFFF) + ((le64_to_cpu((status_desc)->status_desc_data) >> 28) & 0xFFFF) #define netxen_get_sts_prot(status_desc) \ - (((status_desc)->status_desc_data >> 44) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 44) & 0x0F) #define netxen_get_sts_owner(status_desc) \ - (((status_desc)->status_desc_data >> 56) & 0x03) + ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03) #define netxen_get_sts_opcode(status_desc) \ - (((status_desc)->status_desc_data >> 58) & 0x03F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 58) & 0x03F) #define netxen_clear_sts_owner(status_desc) \ ((status_desc)->status_desc_data &= \ - ~(((unsigned long long)3) << 56 )) + ~cpu_to_le64(((unsigned long long)3) << 56 )) #define netxen_set_sts_owner(status_desc, val) \ ((status_desc)->status_desc_data |= \ - (((unsigned long long)((val) & 0x3)) << 56 )) + cpu_to_le64(((unsigned long long)((val) & 0x3)) << 56 )) struct status_desc { /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length 28-43 reference_handle, 44-47 protocol, 48-52 unused 53-55 desc_cnt, 56-57 owner, 58-63 opcode */ - u64 status_desc_data; - u32 hash_value; + __le64 status_desc_data; + __le32 hash_value; u8 hash_type; u8 msg_type; u8 unused; @@ -1005,9 +999,9 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, long enable); int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg, - __le32 * readval); + __u32 * readval); int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, - long reg, __le32 val); + long reg, __u32 val); /* Functions available from netxen_nic_hw.c */ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 34044616b3c8..c381d77a7336 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -218,7 +218,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 status; + __u32 status; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -226,7 +226,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (adapter->phy_write && adapter->phy_write(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) ecmd->autoneg) != 0) + ecmd->autoneg) != 0) return -EIO; else port->link_autoneg = ecmd->autoneg; @@ -279,7 +279,7 @@ static int netxen_nic_get_regs_len(struct net_device *dev) } struct netxen_niu_regs { - __le32 reg[NETXEN_NIC_REGS_COUNT]; + __u32 reg[NETXEN_NIC_REGS_COUNT]; }; static struct netxen_niu_regs niu_registers[] = { @@ -372,7 +372,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 mode, *regs_buff = p; + __u32 mode, *regs_buff = p; void __iomem *addr; int i, window; @@ -415,7 +415,7 @@ static u32 netxen_nic_get_link(struct net_device *dev) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 status; + __u32 status; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -482,13 +482,13 @@ netxen_nic_get_pauseparam(struct net_device *dev, { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 val; + __u32 val; if (adapter->ahw.board_type == NETXEN_NIC_GBE) { /* get flow control settings */ netxen_nic_read_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), - (u32 *) & val); + &val); pause->rx_pause = netxen_gb_get_rx_flowctl(val); pause->tx_pause = netxen_gb_get_tx_flowctl(val); /* get autoneg settings */ @@ -502,7 +502,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 val; + __u32 val; unsigned int autoneg; /* read mode */ @@ -522,13 +522,13 @@ netxen_nic_set_pauseparam(struct net_device *dev, netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), - *(u32 *) (&val)); + *&val); /* set autoneg */ autoneg = pause->autoneg; if (adapter->phy_write && adapter->phy_write(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) autoneg) != 0) + autoneg) != 0) return -EIO; else { port->link_autoneg = pause->autoneg; @@ -543,7 +543,7 @@ static int netxen_nic_reg_test(struct net_device *dev) struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; u32 data_read, data_written, save; - __le32 mode; + __u32 mode; /* * first test the "Read Only" registers by writing which mode diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 191e2336e323..f263232f499f 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -95,7 +95,7 @@ void netxen_nic_set_multi(struct net_device *netdev) struct netxen_port *port = netdev_priv(netdev); struct netxen_adapter *adapter = port->adapter; struct dev_mc_list *mc_ptr; - __le32 netxen_mac_addr_cntl_data = 0; + __u32 netxen_mac_addr_cntl_data = 0; mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { @@ -236,8 +236,9 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } memset(addr, 0, sizeof(struct netxen_ring_ctx)); adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr - + sizeof(struct netxen_ring_ctx); + adapter->ctx_desc->cmd_consumer_offset = + cpu_to_le64(adapter->ctx_desc_phys_addr + + sizeof(struct netxen_ring_ctx)); adapter->cmd_consumer = (uint32_t *) (((char *)addr) + sizeof(struct netxen_ring_ctx)); @@ -253,11 +254,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return -ENOMEM; } - adapter->ctx_desc->cmd_ring_addr_lo = - hw->cmd_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->cmd_ring_addr_hi = - ((u64) hw->cmd_desc_phys_addr >> 32); - adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count; + adapter->ctx_desc->cmd_ring_addr = + cpu_to_le64(hw->cmd_desc_phys_addr); + adapter->ctx_desc->cmd_ring_size = + cpu_to_le32(adapter->max_tx_desc_count); hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; @@ -278,12 +278,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } rcv_desc->desc_head = (struct rcv_desc *)addr; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo = - rcv_desc->phys_addr & 0xffffffffUL; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi = - ((u64) rcv_desc->phys_addr >> 32); + adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = + cpu_to_le64(rcv_desc->phys_addr); adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = - rcv_desc->max_rx_desc_count; + cpu_to_le32(rcv_desc->max_rx_desc_count); } addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, @@ -297,11 +295,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; - adapter->ctx_desc->sts_ring_addr_lo = - recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->sts_ring_addr_hi = - ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32); - adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count; + adapter->ctx_desc->sts_ring_addr = + cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); + adapter->ctx_desc->sts_ring_size = + cpu_to_le32(adapter->max_rx_desc_count); } /* Window = 1 */ @@ -387,10 +384,6 @@ void netxen_tso_check(struct netxen_adapter *adapter, } adapter->stats.xmitcsummed++; desc->tcp_hdr_offset = skb->h.raw - skb->data; - netxen_set_cmd_desc_totallength(desc, - cpu_to_le32 - (netxen_get_cmd_desc_totallength - (desc))); desc->ip_hdr_offset = skb->nh.raw - skb->data; } @@ -867,9 +860,9 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, void netxen_nic_set_link_parameters(struct netxen_port *port) { struct netxen_adapter *adapter = port->adapter; - __le32 status; - __le32 autoneg; - __le32 mode; + __u32 status; + __u32 autoneg; + __u32 mode; netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 0685633a9c1e..ab1112eb1b0d 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -124,28 +124,28 @@ typedef enum { */ #define netxen_gb_enable_tx(config_word) \ - set_bit(0, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 0) #define netxen_gb_enable_rx(config_word) \ - set_bit(2, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 2) #define netxen_gb_tx_flowctl(config_word) \ - set_bit(4, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 4) #define netxen_gb_rx_flowctl(config_word) \ - set_bit(5, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 5) #define netxen_gb_tx_reset_pb(config_word) \ - set_bit(16, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 16) #define netxen_gb_rx_reset_pb(config_word) \ - set_bit(17, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 17) #define netxen_gb_tx_reset_mac(config_word) \ - set_bit(18, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 18) #define netxen_gb_rx_reset_mac(config_word) \ - set_bit(19, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 19) #define netxen_gb_soft_reset(config_word) \ - set_bit(31, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 31) #define netxen_gb_unset_tx_flowctl(config_word) \ - clear_bit(4, (unsigned long *)(&config_word)) + ((config_word) &= ~(1 << 4)) #define netxen_gb_unset_rx_flowctl(config_word) \ - clear_bit(5, (unsigned long*)(&config_word)) + ((config_word) &= ~(1 << 5)) #define netxen_gb_get_tx_synced(config_word) \ _netxen_crb_get_bit((config_word), 1) @@ -171,15 +171,15 @@ typedef enum { */ #define netxen_gb_set_duplex(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_gb_set_crc_enable(config_word) \ - set_bit(1, (unsigned long*)&config_word) + ((config_word) |= 1 << 1) #define netxen_gb_set_padshort(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_gb_set_checklength(config_word) \ - set_bit(4, (unsigned long*)&config_word) + ((config_word) |= 1 << 4) #define netxen_gb_set_hugeframes(config_word) \ - set_bit(5, (unsigned long*)&config_word) + ((config_word) |= 1 << 5) #define netxen_gb_set_preamblelen(config_word, val) \ ((config_word) |= ((val) << 12) & 0xF000) #define netxen_gb_set_intfmode(config_word, val) \ @@ -190,9 +190,9 @@ typedef enum { #define netxen_gb_set_mii_mgmt_clockselect(config_word, val) \ ((config_word) |= ((val) & 0x07)) #define netxen_gb_mii_mgmt_reset(config_word) \ - set_bit(31, (unsigned long*)&config_word) + ((config_word) |= 1 << 31) #define netxen_gb_mii_mgmt_unset(config_word) \ - clear_bit(31, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 31)) /* * NIU GB MII Mgmt Command Register (applies to GB0, GB1, GB2, GB3) @@ -201,7 +201,7 @@ typedef enum { */ #define netxen_gb_mii_mgmt_set_read_cycle(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_gb_mii_mgmt_reg_addr(config_word, val) \ ((config_word) |= ((val) & 0x1F)) #define netxen_gb_mii_mgmt_phy_addr(config_word, val) \ @@ -274,9 +274,9 @@ typedef enum { #define netxen_set_phy_speed(config_word, val) \ ((config_word) |= ((val & 0x03) << 14)) #define netxen_set_phy_duplex(config_word) \ - set_bit(13, (unsigned long*)&config_word) + ((config_word) |= 1 << 13) #define netxen_clear_phy_duplex(config_word) \ - clear_bit(13, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 13)) #define netxen_get_phy_jabber(config_word) \ _netxen_crb_get_bit(config_word, 0) @@ -350,11 +350,11 @@ typedef enum { _netxen_crb_get_bit(config_word, 15) #define netxen_set_phy_int_link_status_changed(config_word) \ - set_bit(10, (unsigned long*)&config_word) + ((config_word) |= 1 << 10) #define netxen_set_phy_int_autoneg_completed(config_word) \ - set_bit(11, (unsigned long*)&config_word) + ((config_word) |= 1 << 11) #define netxen_set_phy_int_speed_changed(config_word) \ - set_bit(14, (unsigned long*)&config_word) + ((config_word) |= 1 << 14) /* * NIU Mode Register. @@ -382,22 +382,22 @@ typedef enum { */ #define netxen_set_gb_drop_gb0(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_set_gb_drop_gb1(config_word) \ - set_bit(1, (unsigned long*)&config_word) + ((config_word) |= 1 << 1) #define netxen_set_gb_drop_gb2(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_set_gb_drop_gb3(config_word) \ - set_bit(3, (unsigned long*)&config_word) + ((config_word) |= 1 << 3) #define netxen_clear_gb_drop_gb0(config_word) \ - clear_bit(0, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 0)) #define netxen_clear_gb_drop_gb1(config_word) \ - clear_bit(1, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 1)) #define netxen_clear_gb_drop_gb2(config_word) \ - clear_bit(2, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 2)) #define netxen_clear_gb_drop_gb3(config_word) \ - clear_bit(3, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 3)) /* * NIU XG MAC Config Register @@ -413,7 +413,7 @@ typedef enum { */ #define netxen_xg_soft_reset(config_word) \ - set_bit(4, (unsigned long*)&config_word) + ((config_word) |= 1 << 4) /* * MAC Control Register @@ -433,19 +433,19 @@ typedef enum { #define netxen_nic_mcr_set_id_pool0(config, val) \ ((config) |= ((val) &0x03)) #define netxen_nic_mcr_set_enable_xtnd0(config) \ - (set_bit(3, (unsigned long *)&(config))) + ((config) |= 1 << 3) #define netxen_nic_mcr_set_id_pool1(config, val) \ ((config) |= (((val) & 0x03) << 4)) #define netxen_nic_mcr_set_enable_xtnd1(config) \ - (set_bit(6, (unsigned long *)&(config))) + ((config) |= 1 << 6) #define netxen_nic_mcr_set_id_pool2(config, val) \ ((config) |= (((val) & 0x03) << 8)) #define netxen_nic_mcr_set_enable_xtnd2(config) \ - (set_bit(10, (unsigned long *)&(config))) + ((config) |= 1 << 10) #define netxen_nic_mcr_set_id_pool3(config, val) \ ((config) |= (((val) & 0x03) << 12)) #define netxen_nic_mcr_set_enable_xtnd3(config) \ - (set_bit(14, (unsigned long *)&(config))) + ((config) |= 1 << 14) #define netxen_nic_mcr_set_mode_select(config, val) \ ((config) |= (((val) & 0x03) << 24)) #define netxen_nic_mcr_set_enable_pool(config, val) \ diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c3e41f368554..973af96337a9 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -690,8 +690,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) desc_head = recv_ctx->rcv_status_desc_head; desc = &desc_head[consumer]; - if (((le16_to_cpu(netxen_get_sts_owner(desc))) - & STATUS_OWNER_HOST)) + if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) return 1; } @@ -787,11 +786,11 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)]; struct pci_dev *pdev = port->pdev; struct net_device *netdev = port->netdev; - int index = le16_to_cpu(netxen_get_sts_refhandle(desc)); + int index = netxen_get_sts_refhandle(desc); struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); struct netxen_rx_buffer *buffer; struct sk_buff *skb; - u32 length = le16_to_cpu(netxen_get_sts_totallength(desc)); + u32 length = netxen_get_sts_totallength(desc); u32 desc_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int ret; @@ -918,16 +917,14 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) */ while (count < max) { desc = &desc_head[consumer]; - if (! - (le16_to_cpu(netxen_get_sts_owner(desc)) & - STATUS_OWNER_HOST)) { + if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { DPRINTK(ERR, "desc %p ownedby %x\n", desc, netxen_get_sts_owner(desc)); break; } netxen_process_rcv(adapter, ctxid, desc); netxen_clear_sts_owner(desc); - netxen_set_sts_owner(desc, cpu_to_le16(STATUS_OWNER_PHANTOM)); + netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } @@ -1232,7 +1229,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, /* make a rcv descriptor */ pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); - pdesc->buffer_length = cpu_to_le16(rcv_desc->dma_size); + pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); DPRINTK(INFO, "done writing descripter\n"); producer = diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 06847d4252c3..be366e48007c 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -79,7 +79,7 @@ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, u32 enable) { - __le32 int_src; + __u32 int_src; struct netxen_port *port; /* This should clear the interrupt source */ @@ -110,7 +110,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, /* write it down later.. */ if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { - __le32 status; + __u32 status; DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 96e1bee19ba0..69c1b9d23a1a 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -117,7 +117,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *mem_ptr1 = NULL; void __iomem *mem_ptr2 = NULL; - u8 *db_ptr = NULL; + u8 __iomem *db_ptr = NULL; unsigned long mem_base, mem_len, db_base, db_len; int pci_using_dac, i, err; int ring; @@ -191,7 +191,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) db_len); db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); - if (db_ptr == 0UL) { + if (!db_ptr) { printk(KERN_ERR "%s: Failed to allocate doorbell map.", netxen_nic_driver_name); err = -EIO; @@ -818,7 +818,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbuf->mss = skb_shinfo(skb)->gso_size; hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); } else { pbuf->mss = 0; @@ -882,7 +882,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) hwdesc->addr_buffer3 = cpu_to_le64(temp_dma); break; case 3: - hwdesc->buffer4_length = temp_len; + hwdesc->buffer4_length = cpu_to_le16(temp_len); hwdesc->addr_buffer4 = cpu_to_le64(temp_dma); break; } diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 4987dc765d99..40d7003a371c 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -89,15 +89,15 @@ static inline int phy_unlock(struct netxen_adapter *adapter) * */ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, - long reg, __le32 * readval) + long reg, __u32 * readval) { long timeout = 0; long result = 0; long restore = 0; - __le32 address; - __le32 command; - __le32 status; - __le32 mac_cfg0; + __u32 address; + __u32 command; + __u32 status; + __u32 mac_cfg0; if (phy_lock(adapter) != 0) { return -1; @@ -112,7 +112,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { - __le32 temp; + __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); @@ -184,15 +184,15 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, * */ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, - long phy, long reg, __le32 val) + long phy, long reg, __u32 val) { long timeout = 0; long result = 0; long restore = 0; - __le32 address; - __le32 command; - __le32 status; - __le32 mac_cfg0; + __u32 address; + __u32 command; + __u32 status; + __u32 mac_cfg0; /* * MII mgmt all goes through port 0 MAC interface, so it @@ -203,7 +203,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { - __le32 temp; + __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); @@ -269,7 +269,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, int port) { int result = 0; - __le32 enable = 0; + __u32 enable = 0; netxen_set_phy_int_link_status_changed(enable); netxen_set_phy_int_autoneg_completed(enable); netxen_set_phy_int_speed_changed(enable); @@ -402,7 +402,7 @@ void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) { int result = 0; - __le32 status; + __u32 status; if (adapter->disable_phy_interrupts) adapter->disable_phy_interrupts(adapter, port); mdelay(2); @@ -410,7 +410,7 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) if (0 == netxen_niu_gbe_phy_read(adapter, port, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - (__le32 *) & status)) { + &status)) { if (netxen_get_phy_link(status)) { if (netxen_get_phy_speed(status) == 2) { netxen_niu_gbe_set_gmii_mode(adapter, port, 1); @@ -489,7 +489,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int port, long enable) { int result = 0; - __le32 int_src; + __u32 int_src; printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" " (device enable = %d)\n", (int)port, (int)enable); @@ -530,7 +530,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, printk(KERN_INFO PFX "autoneg_error "); if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { - __le32 status; + __u32 status; printk(KERN_INFO PFX "speed_changed or link status changed"); @@ -583,9 +583,9 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int phy, netxen_ethernet_macaddr_t * addr) { - u64 result = 0; - __le32 stationhigh; - __le32 stationlow; + u32 stationhigh; + u32 stationlow; + u8 val[8]; if (addr == NULL) return -EINVAL; @@ -598,10 +598,10 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter, if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &stationlow, 4)) return -EIO; + ((__le32 *)val)[1] = cpu_to_le32(stationhigh); + ((__le32 *)val)[0] = cpu_to_le32(stationlow); - result = (u64) netxen_gb_get_stationaddress_low(stationlow); - result |= (u64) stationhigh << 16; - memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t)); + memcpy(addr, val + 2, 6); return 0; } @@ -613,24 +613,25 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int netxen_niu_macaddr_set(struct netxen_port *port, netxen_ethernet_macaddr_t addr) { - __le32 temp = 0; + u8 temp[4]; + u32 val; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; unsigned char mac_addr[6]; int i; for (i = 0; i < 10; i++) { - memcpy(&temp, addr, 2); - temp <<= 16; + temp[0] = temp[1] = 0; + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx - (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &temp, 4)) + (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) return -EIO; - temp = 0; - - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); + memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx - (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &temp, 4)) + (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) return -2; netxen_niu_macaddr_get(adapter, phy, @@ -659,9 +660,9 @@ int netxen_niu_macaddr_set(struct netxen_port *port, int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, int port, netxen_niu_gbe_ifmode_t mode) { - __le32 mac_cfg0; - __le32 mac_cfg1; - __le32 mii_cfg; + __u32 mac_cfg0; + __u32 mac_cfg1; + __u32 mii_cfg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -736,7 +737,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, /* Disable a GbE interface */ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) { - __le32 mac_cfg0; + __u32 mac_cfg0; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -752,7 +753,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) /* Disable an XG interface */ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) { - __le32 mac_cfg; + __u32 mac_cfg; if (port != 0) return -EINVAL; @@ -769,7 +770,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, netxen_niu_prom_mode_t mode) { - __le32 reg; + __u32 reg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -826,22 +827,21 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, int netxen_niu_xg_macaddr_set(struct netxen_port *port, netxen_ethernet_macaddr_t addr) { - __le32 temp = 0; + u8 temp[4]; + u32 val; struct netxen_adapter *adapter = port->adapter; - memcpy(&temp, addr, 2); - temp = cpu_to_le32(temp); - temp <<= 16; + temp[0] = temp[1] = 0; + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, - &temp, 4)) + &val, 4)) return -EIO; - temp = 0; - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); - temp = cpu_to_le32(temp); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, - &temp, 4)) + &val, 4)) return -EIO; return 0; @@ -854,9 +854,9 @@ int netxen_niu_xg_macaddr_set(struct netxen_port *port, int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, netxen_ethernet_macaddr_t * addr) { - __le32 stationhigh; - __le32 stationlow; - u64 result; + u32 stationhigh; + u32 stationlow; + u8 val[8]; if (addr == NULL) return -EINVAL; @@ -869,10 +869,10 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, &stationlow, 4)) return -EIO; + ((__le32 *)val)[1] = cpu_to_le32(stationhigh); + ((__le32 *)val)[0] = cpu_to_le32(stationlow); - result = ((u64) stationlow) >> 16; - result |= (u64) stationhigh << 16; - memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t)); + memcpy(addr, val + 2, 6); return 0; } @@ -880,7 +880,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, int port, netxen_niu_prom_mode_t mode) { - __le32 reg; + __u32 reg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; -- cgit v1.2.3 From eb7972271720bfc64dc8bacc5b15f874c0bcc859 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 1 Feb 2007 13:52:38 +0000 Subject: [PATCH] ide section fixes a) cleanup_module() should be __exit b) externs should match reality Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/ide/ide.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 3b334af0c7b9..6c9bd5165bdb 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1781,9 +1781,9 @@ done: return 1; } -extern void pnpide_init(void); -extern void pnpide_exit(void); -extern void h8300_ide_init(void); +extern void __init pnpide_init(void); +extern void __exit pnpide_exit(void); +extern void __init h8300_ide_init(void); /* * probe_for_hwifs() finds/initializes "known" IDE interfaces @@ -2088,7 +2088,7 @@ int __init init_module (void) return ide_init(); } -void cleanup_module (void) +void __exit cleanup_module (void) { int index; -- cgit v1.2.3 From 9d6ed92196f7acdd1052b0828bb1e2f1a7241815 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 1 Feb 2007 13:52:59 +0000 Subject: [PATCH] radio modems sitting on serial port are not for s390 Won't build (request_irq()/free_irq()), even if you manage to find an s390 box with 8250-compatible UART they are expecting. Signed-off-by: Al Viro Acked-by: Martin Schwidefsky Signed-off-by: Linus Torvalds --- drivers/net/hamradio/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 896aa02000d7..feb0ada7a025 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig @@ -113,7 +113,7 @@ config SCC_TRXECHO config BAYCOM_SER_FDX tristate "BAYCOM ser12 fullduplex driver for AX.25" - depends on AX25 + depends on AX25 && !S390 select CRC_CCITT ---help--- This is one of two drivers for Baycom style simple amateur radio @@ -133,7 +133,7 @@ config BAYCOM_SER_FDX config BAYCOM_SER_HDX tristate "BAYCOM ser12 halfduplex driver for AX.25" - depends on AX25 + depends on AX25 && !S390 select CRC_CCITT ---help--- This is one of two drivers for Baycom style simple amateur radio @@ -181,7 +181,7 @@ config BAYCOM_EPP config YAM tristate "YAM driver for AX.25" - depends on AX25 + depends on AX25 && !S390 help The YAM is a modem for packet radio which connects to the serial port and includes some of the functions of a Terminal Node -- cgit v1.2.3 From cb7468ef4cce8f240604b80b82ac157fa9930e94 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 31 Jan 2007 23:48:12 -0800 Subject: [PATCH] via quirk update Add special handling for the VT82C686. Signed-off-by: Jean Delvare Cc: Alan Cox Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 16945c2ba2ca..dcc0c1ab95ed 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -661,9 +661,11 @@ static void quirk_via_bridge(struct pci_dev *dev) /* See what bridge we have and find the device ranges */ switch (dev->device) { case PCI_DEVICE_ID_VIA_82C686: - /* 82C686 is special */ - via_vlink_dev_lo = 7; - via_vlink_dev_hi = 7; + /* The VT82C686 is special, it attaches to PCI and can have + any device number. All its subdevices are functions of + that single device. */ + via_vlink_dev_lo = PCI_SLOT(dev->devfn); + via_vlink_dev_hi = PCI_SLOT(dev->devfn); break; case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237A: -- cgit v1.2.3 From 6a4c24ec52128c1f57b7d2d24cf4dd13fc23f474 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 31 Jan 2007 23:48:13 -0800 Subject: [PATCH] pci: remove warning messages Remove these recently-added warnings. They don't tell us anythng very interesting and Kumar says "On an embedded PPC reference system I see this message 6 times when I've got no cards in the PCI slots." Acked-by: Kumar Gala Acked-by: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/search.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/search.c b/drivers/pci/search.c index fab381ed853c..b2653c4afe9e 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -200,11 +200,8 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor, * can cause some machines to crash. So here we detect and flag that * situation and bail out early. */ - if (unlikely(list_empty(&pci_devices))) { - printk(KERN_INFO "pci_find_subsys() called while pci_devices " - "is still empty\n"); + if (unlikely(list_empty(&pci_devices))) return NULL; - } down_read(&pci_bus_sem); n = from ? from->global_list.next : pci_devices.next; @@ -278,11 +275,8 @@ pci_get_subsys(unsigned int vendor, unsigned int device, * can cause some machines to crash. So here we detect and flag that * situation and bail out early. */ - if (unlikely(list_empty(&pci_devices))) { - printk(KERN_NOTICE "pci_get_subsys() called while pci_devices " - "is still empty\n"); + if (unlikely(list_empty(&pci_devices))) return NULL; - } down_read(&pci_bus_sem); n = from ? from->global_list.next : pci_devices.next; -- cgit v1.2.3 From 432bd6cbf9f016f5480153b1cdfbd046f8d4fb1e Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 31 Jan 2007 23:48:13 -0800 Subject: [PATCH] KVM: fix lockup on 32-bit intel hosts with nx disabled in the bios Intel hosts, without long mode, and with nx support disabled in the bios have an efer that is readable but not writable. This causes a lockup on switch to guest mode (even though it should exit with reason 34 according to the documentation). Signed-off-by: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/kvm/vmx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 27f2751c3baa..54c35c0b3181 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1116,6 +1116,8 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) if (rdmsr_safe(index, &data_low, &data_high) < 0) continue; + if (wrmsr_safe(index, data_low, data_high) < 0) + continue; data = data_low | ((u64)data_high << 32); vcpu->host_msrs[j].index = index; vcpu->host_msrs[j].reserved = 0; -- cgit v1.2.3 From d346cce308f7fc99c7ffdb62060ed404fa340a1c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 31 Jan 2007 23:48:17 -0800 Subject: [PATCH] sysrq: showBlockedTasks is sysrq-W Change SysRq showBlockedTasks from sysrq-X to sysrq-W and show that in the Help message. It was previously done via X, but X is already used for Xmon on ppc & powerpc platforms and this collision needs to be avoided. All callers of register_sysrq_key() are now marked in the sysrq op/key table. I didn't mark 'h' as Help because Help is just printed for any unknown key, such as '?'. Added some omitted sysrq key entries in the sysrq.txt file. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysrq.txt | 66 ++++++++++++++++++++++++++----------------------- drivers/char/sysrq.c | 20 ++++++++------- 2 files changed, 46 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index e0188a23fd5e..61613166981b 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt @@ -1,6 +1,6 @@ Linux Magic System Request Key Hacks -Documentation for sysrq.c version 1.15 -Last update: $Date: 2001/01/28 10:15:59 $ +Documentation for sysrq.c +Last update: 2007-JAN-06 * What is the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -35,7 +35,7 @@ You can set the value in the file by the following command: Note that the value of /proc/sys/kernel/sysrq influences only the invocation via a keyboard. Invocation of any operation via /proc/sysrq-trigger is always -allowed. +allowed (by a user with admin privileges). * How do I use the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -58,7 +58,7 @@ On PowerPC - Press 'ALT - Print Screen (or F13) - , On other - If you know of the key combos for other architectures, please let me know so I can add them to this section. -On all - write a character to /proc/sysrq-trigger. eg: +On all - write a character to /proc/sysrq-trigger. e.g.: echo t > /proc/sysrq-trigger @@ -74,6 +74,8 @@ On all - write a character to /proc/sysrq-trigger. eg: 'c' - Will perform a kexec reboot in order to take a crashdump. +'d' - Shows all locks that are held. + 'o' - Will shut your system off (if configured and supported). 's' - Will attempt to sync all mounted filesystems. @@ -87,38 +89,43 @@ On all - write a character to /proc/sysrq-trigger. eg: 'm' - Will dump current memory info to your console. +'n' - Used to make RT tasks nice-able + 'v' - Dumps Voyager SMP processor info to your console. +'w' - Dumps tasks that are in uninterruptable (blocked) state. + +'x' - Used by xmon interface on ppc/powerpc platforms. + '0'-'9' - Sets the console log level, controlling which kernel messages will be printed to your console. ('0', for example would make it so that only emergency messages like PANICs or OOPSes would make it to your console.) -'f' - Will call oom_kill to kill a memory hog process +'f' - Will call oom_kill to kill a memory hog process. 'e' - Send a SIGTERM to all processes, except for init. -'i' - Send a SIGKILL to all processes, except for init. +'g' - Used by kgdb on ppc platforms. -'l' - Send a SIGKILL to all processes, INCLUDING init. (Your system - will be non-functional after this.) +'i' - Send a SIGKILL to all processes, except for init. -'h' - Will display help ( actually any other key than those listed +'h' - Will display help (actually any other key than those listed above will display help. but 'h' is easy to remember :-) * Okay, so what can I use them for? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Well, un'R'aw is very handy when your X server or a svgalib program crashes. -sa'K' (Secure Access Key) is useful when you want to be sure there are no -trojan program is running at console and which could grab your password -when you would try to login. It will kill all programs on given console -and thus letting you make sure that the login prompt you see is actually +sa'K' (Secure Access Key) is useful when you want to be sure there is no +trojan program running at console which could grab your password +when you would try to login. It will kill all programs on given console, +thus letting you make sure that the login prompt you see is actually the one from init, not some trojan program. IMPORTANT: In its true form it is not a true SAK like the one in a :IMPORTANT IMPORTANT: c2 compliant system, and it should not be mistaken as :IMPORTANT IMPORTANT: such. :IMPORTANT - It seems other find it useful as (System Attention Key) which is + It seems others find it useful as (System Attention Key) which is useful when you want to exit a program that will not let you switch consoles. (For example, X or a svgalib program.) @@ -139,8 +146,8 @@ OK or Done message...) Again, the unmount (remount read-only) hasn't taken place until you see the "OK" and "Done" message appear on the screen. -The loglevel'0'-'9' is useful when your console is being flooded with -kernel messages you do not want to see. Setting '0' will prevent all but +The loglevels '0'-'9' are useful when your console is being flooded with +kernel messages you do not want to see. Selecting '0' will prevent all but the most urgent kernel messages from reaching your console. (They will still be logged if syslogd/klogd are alive, though.) @@ -152,7 +159,7 @@ processes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ That happens to me, also. I've found that tapping shift, alt, and control on both sides of the keyboard, and hitting an invalid sysrq sequence again -will fix the problem. (ie, something like alt-sysrq-z). Switching to another +will fix the problem. (i.e., something like alt-sysrq-z). Switching to another virtual console (ALT+Fn) and then back again should also help. * I hit SysRq, but nothing seems to happen, what's wrong? @@ -174,11 +181,11 @@ handler function you will use, B) a help_msg string, that will print when SysRQ prints help, and C) an action_msg string, that will print right before your handler is called. Your handler must conform to the prototype in 'sysrq.h'. -After the sysrq_key_op is created, you can call the macro -register_sysrq_key(int key, struct sysrq_key_op *op_p) that is defined in -sysrq.h, this will register the operation pointed to by 'op_p' at table -key 'key', if that slot in the table is blank. At module unload time, you must -call the macro unregister_sysrq_key(int key, struct sysrq_key_op *op_p), which +After the sysrq_key_op is created, you can call the kernel function +register_sysrq_key(int key, struct sysrq_key_op *op_p); this will +register the operation pointed to by 'op_p' at table key 'key', +if that slot in the table is blank. At module unload time, you must call +the function unregister_sysrq_key(int key, struct sysrq_key_op *op_p), which will remove the key op pointed to by 'op_p' from the key 'key', if and only if it is currently registered in that slot. This is in case the slot has been overwritten since you registered it. @@ -186,15 +193,12 @@ overwritten since you registered it. The Magic SysRQ system works by registering key operations against a key op lookup table, which is defined in 'drivers/char/sysrq.c'. This key table has a number of operations registered into it at compile time, but is mutable, -and 4 functions are exported for interface to it: __sysrq_lock_table, -__sysrq_unlock_table, __sysrq_get_key_op, and __sysrq_put_key_op. The -functions __sysrq_swap_key_ops and __sysrq_swap_key_ops_nolock are defined -in the header itself, and the REGISTER and UNREGISTER macros are built from -these. More complex (and dangerous!) manipulations of the table are possible -using these functions, but you must be careful to always lock the table before -you read or write from it, and to unlock it again when you are done. (And of -course, to never ever leave an invalid pointer in the table). Null pointers in -the table are always safe :) +and 2 functions are exported for interface to it: + register_sysrq_key and unregister_sysrq_key. +Of course, never ever leave an invalid pointer in the table. I.e., when +your module that called register_sysrq_key() exits, it must call +unregister_sysrq_key() to clean up the sysrq key table entry that it used. +Null pointers in the table are always safe. :) If for some reason you feel the need to call the handle_sysrq function from within a function called by handle_sysrq, you must be aware that you are in diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 13935235e066..7fd3cd5ddf21 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -215,7 +215,7 @@ static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) } static struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, - .help_msg = "showBlockedTasks", + .help_msg = "shoW-blocked-tasks", .action_msg = "Show Blocked State", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -315,15 +315,16 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_loglevel_op, /* 9 */ /* - * Don't use for system provided sysrqs, it is handled specially on - * sparc and will never arrive + * a: Don't use for system provided sysrqs, it is handled specially on + * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ - &sysrq_crashdump_op, /* c */ + &sysrq_crashdump_op, /* c & ibm_emac driver debug */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ + /* g: May be registered by ppc for kgdb */ NULL, /* g */ NULL, /* h */ &sysrq_kill_op, /* i */ @@ -332,18 +333,19 @@ static struct sysrq_key_op *sysrq_key_table[36] = { NULL, /* l */ &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ - /* This will often be registered as 'Off' at init time */ + /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */ NULL, /* q */ - &sysrq_unraw_op, /* r */ + &sysrq_unraw_op, /* r */ &sysrq_sync_op, /* s */ &sysrq_showstate_op, /* t */ &sysrq_mountro_op, /* u */ - /* May be assigned at init time by SMP VOYAGER */ + /* v: May be registered at init time by SMP VOYAGER */ NULL, /* v */ - NULL, /* w */ - &sysrq_showstate_blocked_op, /* x */ + &sysrq_showstate_blocked_op, /* w */ + /* x: May be registered on ppc/powerpc for xmon */ + NULL, /* x */ NULL, /* y */ NULL /* z */ }; -- cgit v1.2.3 From fb594d31aa2d133ea89d4ead964c51262b331407 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 1 Feb 2007 14:12:27 +0100 Subject: [PATCH] via82cxxx: fix typo ("cx7000" should be corrected to "cx700") Noticed by JosephChan@via.com.tw. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Linus Torvalds --- drivers/ide/pci/via82cxxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index a98b4d38b9dd..6fb6e50b8231 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -78,7 +78,7 @@ static struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { - { "cx7000", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -- cgit v1.2.3 From b659f44e4e144bae02c5beaba78a37db60783ba2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 2 Feb 2007 00:46:35 -0800 Subject: [BNX2]: PHY workaround for 5709 A0. 5709 A0 copper devices will not link up with some link partners without this workaround. Update driver to 1.5.5. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 14 ++++++++++++-- drivers/net/bnx2.h | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 953808efe551..ee7b75b976b5 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.4" -#define DRV_MODULE_RELDATE "January 24, 2007" +#define DRV_MODULE_VERSION "1.5.5" +#define DRV_MODULE_RELDATE "February 1, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -1356,6 +1356,14 @@ bnx2_init_copper_phy(struct bnx2 *bp) bnx2_write_phy(bp, 0x18, 0x0400); } + if (bp->phy_flags & PHY_DIS_EARLY_DAC_FLAG) { + bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, + MII_BNX2_DSP_EXPAND_REG | 0x8); + bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val); + val &= ~(1 << 8); + bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val); + } + if (bp->dev->mtu > 1500) { /* Set extended packet length bit */ bnx2_write_phy(bp, 0x18, 0x7); @@ -5918,6 +5926,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || CHIP_NUM(bp) == CHIP_NUM_5708) bp->phy_flags |= PHY_CRC_FIX_FLAG; + else if (CHIP_ID(bp) == CHIP_ID_5709_A0) + bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG; if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || (CHIP_ID(bp) == CHIP_ID_5708_B0) || diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 13b6f9b11e01..ccbdf81c6599 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6288,6 +6288,10 @@ struct l2_fhdr { #define BCM5708S_TX_ACTL3 0x17 +#define MII_BNX2_DSP_RW_PORT 0x15 +#define MII_BNX2_DSP_ADDRESS 0x17 +#define MII_BNX2_DSP_EXPAND_REG 0x0f00 + #define MIN_ETHERNET_PACKET_SIZE 60 #define MAX_ETHERNET_PACKET_SIZE 1514 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 @@ -6489,6 +6493,7 @@ struct bnx2 { #define PHY_INT_MODE_MASK_FLAG 0x300 #define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 #define PHY_INT_MODE_LINK_READY_FLAG 0x200 +#define PHY_DIS_EARLY_DAC_FLAG 0x400 u32 chip_id; /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ @@ -6512,6 +6517,7 @@ struct bnx2 { #define CHIP_ID_5708_A0 0x57080000 #define CHIP_ID_5708_B0 0x57081000 #define CHIP_ID_5708_B1 0x57081010 +#define CHIP_ID_5709_A0 0x57090000 #define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) -- cgit v1.2.3 From a53a33da864a81a238ee84055c8ced775ee25350 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 31 Jan 2007 11:02:46 -0800 Subject: e100: fix napi ifdefs removing needed code e100: fix napi ifdefs removing needed code From: Auke Kok The e100 driver is NAPI mode only. We need to netif_poll_disable during suspend and shutdown. The non-NAPI driver code was removed and is only avaiable in the out-of-tree e100 kernel driver. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e100.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3208dac29168..0cefef5e3f06 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2718,14 +2718,12 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); -#ifdef CONFIG_E100_NAPI if (netif_running(netdev)) netif_poll_disable(nic->netdev); -#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); - netif_device_detach(netdev); + pci_save_state(pdev); if ((nic->flags & wol_magic) | e100_asf(nic)) { @@ -2761,16 +2759,13 @@ static int e100_resume(struct pci_dev *pdev) } #endif /* CONFIG_PM */ - static void e100_shutdown(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); -#ifdef CONFIG_E100_NAPI if (netif_running(netdev)) netif_poll_disable(nic->netdev); -#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); -- cgit v1.2.3 From a55eb05a57a981f16325d035ee3a3ad10485ea0d Mon Sep 17 00:00:00 2001 From: Jens Osterkamp Date: Thu, 1 Feb 2007 12:07:47 +0100 Subject: spidernet : fix memory leak in spider_net_stop We forget to call spider_net_free_rx_chain_contents which does the actual dev_kfree_skb. New skbs are allocated from skbuff_head_cache on each "ifconfig up" letting the cache grow infinitely. This patch fixes it. Signed-off-by: Jens Osterkamp Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index ebb6aa39f9c7..8ea2fc1b96cb 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1925,6 +1925,8 @@ spider_net_stop(struct net_device *netdev) /* release chains */ spider_net_release_tx_chain(card, 1); + spider_net_free_rx_chain_contents(card); + spider_net_free_chain(card, &card->tx_chain); spider_net_free_chain(card, &card->rx_chain); -- cgit v1.2.3 From 77280989673ee1ef736a92617f52e2be45651833 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 2 Feb 2007 14:51:09 +0900 Subject: ahci/pata_jmicron: fix JMicron quirk For all JMicrons except for 361 and 368, AHCI mode enable bits in the Control(1) should be set. This used to be done in both ahci and pata_jmicron but while moving programming to PCI quirk, it was removed from ahci part while still left in pata_jmicron. The implemented JMicron PCI quirk was incorrect in that it didn't program AHCI mode enable bits. If pata_jmicron is loaded first and programs those bits, the ahci ports work; otherwise, ahci device detection fails miserably. This patch makes JMicron PCI quirk clear SATA IDE mode bits and set AHCI mode bits and remove the respective part from pata_jmicron. Tested on JMB361, 363 and 368. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/pata_jmicron.c | 18 +++++------------- drivers/pci/quirks.c | 4 ++-- 2 files changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 2d661cb4df3c..d50264af2848 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -204,20 +204,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i u32 reg; - if (id->driver_data != 368) { - /* Put the controller into AHCI mode in case the AHCI driver - has not yet been loaded. This can be done with either - function present */ + /* PATA controller is fn 1, AHCI is fn 0 */ + if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1) + return -ENODEV; - /* FIXME: We may want a way to override this in future */ - pci_write_config_byte(pdev, 0x41, 0xa1); - - /* PATA controller is fn 1, AHCI is fn 0 */ - if (PCI_FUNC(pdev->devfn) != 1) - return -ENODEV; - } - if ( id->driver_data == 365 || id->driver_data == 366) { - /* The 365/66 have two PATA channels, redirect the second */ + /* The 365/66 have two PATA channels, redirect the second */ + if (id->driver_data == 365 || id->driver_data == 366) { pci_read_config_dword(pdev, 0x80, ®); reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ pci_write_config_dword(pdev, 0x80, reg); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index dcc0c1ab95ed..c913ea4e545c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1262,8 +1262,8 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev) pci_read_config_dword(pdev, 0x40, &conf); /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ /* Set the class codes correctly and then direct IDE 0 */ - conf &= ~0x000F0200; /* Clear bit 9 and 16-19 */ - conf |= 0x00C20002; /* Set bit 1, 17, 22, 23 */ + conf &= ~0x000FF200; /* Clear bit 9 and 12-19 */ + conf |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ pci_write_config_dword(pdev, 0x40, conf); /* Reconfigure so that the PCI scanner discovers the -- cgit v1.2.3 From 54494f3a8339baad5e8f9d9b87d3ea6a3aa4f540 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 31 Jan 2007 17:10:46 +0000 Subject: pata_atiixp: propogate cable detection hack from drivers/ide to the new driver Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 6f6672c55131..504e1dbfffd7 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -36,15 +36,22 @@ enum { static int atiixp_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - static struct pci_bits atiixp_enable_bits[] = { + static const struct pci_bits atiixp_enable_bits[] = { { 0x48, 1, 0x01, 0x00 }, { 0x48, 1, 0x08, 0x00 } }; + u8 udma; if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA80; + /* Hack from drivers/ide/pci. Really we want to know how to do the + raw detection not play follow the bios mode guess */ + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); + if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40) + ap->cbl = ATA_CBL_PATA80; + else + ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } -- cgit v1.2.3 From 05c39e502e964ae66336ca8e6960b200cff26f94 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 31 Jan 2007 17:14:38 +0000 Subject: pata_via: Correct missing comments The 8237S was added to the chipsets but not to the comments. Fix this Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_via.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 0219419cae97..f0b6c3b71429 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -23,6 +23,7 @@ * VIA VT8233c - UDMA100 * VIA VT8235 - UDMA133 * VIA VT8237 - UDMA133 + * VIA VT8237S - UDMA133 * VIA VT8251 - UDMA133 * * Most registers remain compatible across chips. Others start reserved @@ -61,7 +62,7 @@ #include #define DRV_NAME "pata_via" -#define DRV_VERSION "0.2.0" +#define DRV_VERSION "0.2.1" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx -- cgit v1.2.3 From 49c8042996c84f0df6c49ea2e28a7ef38cd7d773 Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 30 Jan 2007 11:32:26 -0600 Subject: libata: Initialize nbytes for internal sg commands Some LLDDs, like ipr, use nbytes and pad_len to determine the total data transfer length of a command. Make sure nbytes gets initialized for internally generated commands. Signed-off-by: Brian King Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cf707029352e..667acd283364 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1250,6 +1250,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ata_sg_init(qc, sg, n_elem); qc->nsect = buflen / ATA_SECT_SIZE; + qc->nbytes = buflen; } qc->private_data = &wait; -- cgit v1.2.3 From 017f2e37ae19ccd28e5edd965741fc374194c5dd Mon Sep 17 00:00:00 2001 From: Nagendra Singh Tomar Date: Fri, 2 Feb 2007 17:34:56 +0530 Subject: [SCSI] sd: udev accessing an uninitialized scsi_disk field results in a crash sd_probe() calls class_device_add() even before initializing the sdkp->device variable. class_device_add() eventually results in the user mode udev program to be called. udev program can read the the allow_restart attribute of the newly created scsi device. This is resulting in a crash as the show function for allow_restart (i.e sd_show_allow_restart) returns the attribute value by reading the sdkp->device->allow_restart variable. As the sdkp->device is not initialized before calling the user mode hotplug helper, this results in a crash. The patch below solves it by calling class_device_add() only after the necessary fields in the scsi_disk structure are initialized properly. Signed-off-by: Nagendra Singh Tomar Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 978bfc1e0c6a..b781a90d6699 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1647,16 +1647,6 @@ static int sd_probe(struct device *dev) if (error) goto out_put; - class_device_initialize(&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; - strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); - - if (class_device_add(&sdkp->cdev)) - goto out_put; - - get_device(&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; @@ -1670,6 +1660,16 @@ static int sd_probe(struct device *dev) sdp->timeout = SD_MOD_TIMEOUT; } + class_device_initialize(&sdkp->cdev); + sdkp->cdev.dev = &sdp->sdev_gendev; + sdkp->cdev.class = &sd_disk_class; + strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); + + if (class_device_add(&sdkp->cdev)) + goto out_put; + + get_device(&sdp->sdev_gendev); + gd->major = sd_major((index & 0xf0) >> 4); gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); gd->minors = 16; -- cgit v1.2.3 From 24d8f6aded45aca87dec6d9c037b75b189e3d731 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Sat, 3 Feb 2007 01:13:50 -0800 Subject: [PATCH] net/smc911x: match up spin lock/unlock smc911x_phy_configure's error handling unconditionally unlocks the spinlock even if it wasn't locked. Patch fixes it. Signed-off-by: Peter Korsgaard Cc: Jeff Garzik Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/smc911x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 880d9fdd7c67..43af61438449 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -968,11 +968,11 @@ static void smc911x_phy_configure(struct work_struct *work) * We should not be called if phy_type is zero. */ if (lp->phy_type == 0) - goto smc911x_phy_configure_exit; + goto smc911x_phy_configure_exit_nolock; if (smc911x_phy_reset(dev, phyaddr)) { printk("%s: PHY reset timed out\n", dev->name); - goto smc911x_phy_configure_exit; + goto smc911x_phy_configure_exit_nolock; } spin_lock_irqsave(&lp->lock, flags); @@ -1041,6 +1041,7 @@ static void smc911x_phy_configure(struct work_struct *work) smc911x_phy_configure_exit: spin_unlock_irqrestore(&lp->lock, flags); +smc911x_phy_configure_exit_nolock: lp->work_pending = 0; } -- cgit v1.2.3 From 886ae1fa1380309d91cdb7e67bd4bf71e053c1d5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 4 Feb 2007 03:02:17 +0000 Subject: [PATCH] fix rtl8150 That code doesn't do what its author apparently thought it would do... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/net/rtl8150.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index e0eecda78ec1..670262a38a0f 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -284,7 +284,8 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) u8 data[3], tmp; data[0] = phy; - *(data + 1) = cpu_to_le16p(®); + data[1] = reg & 0xff; + data[2] = (reg >> 8) & 0xff; tmp = indx | PHY_WRITE | PHY_GO; i = 0; -- cgit v1.2.3