* Re: question about softirqs
From: Ingo Molnar @ 2009-05-12 9:23 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linuxppc-dev, netdev, Steven Rostedt, paulus, Thomas Gleixner,
David Miller
In-Reply-To: <1242119578.11251.321.camel@twins>
* Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Tue, 2009-05-12 at 10:12 +0200, Ingo Molnar wrote:
> > * Chris Friesen <cfriesen@nortel.com> wrote:
> >
> > > This started out as a thread on the ppc list, but on the
> > > suggestion of DaveM and Paul Mackerras I'm expanding the receiver
> > > list a bit.
> > >
> > > Currently, if a softirq is raised in process context the
> > > TIF_RESCHED_PENDING flag gets set and on return to userspace we
> > > run the scheduler, expecting it to switch to ksoftirqd to handle
> > > the softirqd processing.
> > >
> > > I think I see a possible problem with this. Suppose I have a
> > > SCHED_FIFO task spinning on recvmsg() with MSG_DONTWAIT set. Under
> > > the scenario above, schedule() would re-run the spinning task
> > > rather than ksoftirqd, thus preventing any incoming packets from
> > > being sent up the stack until we get a real hardware
> > > interrupt--which could be a whole jiffy if interrupt mitigation is
> > > enabled in the net device.
> >
> > TIF_RESCHED_PENDING will not be set if a SCHED_FIFO task wakes up a
> > SCHED_OTHER ksoftirqd task. But starvation of ksoftirqd processing
> > will occur.
> >
> > > DaveM pointed out that if we're doing transmits we're likely to
> > > hit local_bh_enable(), which would process the softirq work.
> > > However, I think we may still have a problem in the above rx-only
> > > scenario--or is it too contrived to matter?
> >
> > This could occur, and the problem is really that task priorities do
> > not extend across softirq work processing.
> >
> > This could occur in ordinary SCHED_OTHER tasks as well, if the
> > softirq is bounced to ksoftirqd - which it only should be if there's
> > serious softirq overload - or, as you describe it above, if the
> > softirq is raised in process context:
> >
> > if (!in_interrupt())
> > wakeup_softirqd();
> >
> > that's not really clean. We look into eliminating process context
> > use of raise_softirq_irqsoff(). Such code sequence:
> >
> > local_irq_save(flags);
> > ...
> > raise_softirq_irqsoff(nr);
> > ...
> > local_irq_restore(flags);
> >
> > should be converted to something like:
> >
> > local_irq_save(flags);
> > ...
> > raise_softirq_irqsoff(nr);
> > ...
> > local_irq_restore(flags);
> > recheck_softirqs();
> >
> > If someone does not do proper local_bh_disable()/enable() sequences
> > for micro-optimization reasons, then push the check to after the
> > critcal section - and dont cause extra reschedules by waking up
> > ksoftirqd. raise_softirq_irqsoff() will also be faster.
>
>
> Wouldn't the even better solution be to get rid of softirqs
> all-together?
>
> I see the recent work by Thomas to get threaded interrupts
> upstream as a good first step towards that goal, once the RX
> processing is moved to a thread (or multiple threads) one can
> priorize them in the regular sys_sched_setscheduler() way and its
> obvious that a FIFO task above the priority of the network tasks
> will have network starvation issues.
Yeah, that would be "nice". A single IRQ thread plus the process
context(s) doing networking might perform well.
Multiple IRQ threads (softirq and hardirq threads mixed) i'm not so
sure about - it's extra context-switching cost.
Btw, i noticed that using scheduling for work (packet, etc.) flow
distribution standardizes and evens out the behavior of workloads.
Softirq scheduling is really quite random currently. We have a
random processing loop-limit in the core code and various batching
and work-limit controls at individual usage sites. We sometimes
piggyback to ksoftirqd. It's far easier to keep performance in check
when things are more predictable.
But this is not an easy endevour, and performance regressions have
to be expected and addressed if they occur. There can be random
packet queuing details in networking drivers that just happen to
work fine now, and might work worse with a kernel thread in place.
So there has to be broad buy-in for the concept, and a concerted
effort to eliminate softirq processing and most of hardirq
processing by pushing those two elements into a single hardirq
thread (and the rest into process context).
Not for the faint hearted. Nor is it recommended to be done without
a good layer of asbestos.
Ingo
^ permalink raw reply
* RapidIO - general questions
From: Jan Neskudla @ 2009-05-12 9:17 UTC (permalink / raw)
To: linuxppc-dev
Hallo
we'd likes to use a RapidIO as a general communication bus on our new
product, and so I have some questions about general design of Linux RIO
subsystem. I did not find any better mailing list for RapidIO
discussion.
[1] - we'd like to implement following features
* Hot-plug (hot-insert/hot-remove) of devices
* Error handling (port-write packets - configuration, handling of
them)
* Static ID configuration based on port numbers
* Aux driver - basic driver, for sending messages over different
mboxes, handling ranges of doorbells
Is it here anyone who is working on any improvement, or anyone who
knows the development plans for RapidIO subsystem?
[2] - I have a following problem with a current implementation of
loading drivers. The driver probe-function call is based on comparison
of VendorID (VID) and DeviceID (DID) only. Thus if I have 3 devices with
same DID and VID connected to the same network (bus), the driver is
loaded 3times, instead only once for the actual device Master port.
Rionet driver solved this by enabling to call initialization function
just once, and it expect that this is the Master port.
Is it this correct behavior ? It looks to me that RapidIO is handled
like a local bus (like PCI)
Jan
^ permalink raw reply
* Re: [PATCH] Trivial spelling fix in ppc code comments
From: Jiri Kosina @ 2009-05-12 8:47 UTC (permalink / raw)
To: Sankar P; +Cc: linuxppc-dev, trivial@kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1242112273.736.6.camel@blr-psankar.blr.novell.com>
On Tue, 12 May 2009, Sankar P wrote:
> Fixes a trivial spelling error in powerpc code comments.
>
> Signed-off-by: Sankar P <sankar.curiosity@gmail.com>
Applied to trivial tree, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH 1/6] rapidio: add common mapping APIs for RapidIO memory access
From: Li Yang @ 2009-05-12 8:35 UTC (permalink / raw)
To: akpm, galak, davem, mporter
Cc: linuxppc-dev, Zhang Wei, Li Yang, linux-kernel, netdev
Add the mapping functions used to support direct IO memory access of
rapidIO.
Signed-off-by: Zhang Wei <zw@zh-kernel.org>
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/rapidio/rio.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/rio.h | 25 ++++++++++++
include/linux/rio_drv.h | 24 +++++++++---
3 files changed, 138 insertions(+), 6 deletions(-)
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 6395c78..224a076 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -2,6 +2,8 @@
* RapidIO interconnect services
* (RapidIO Interconnect Specification, http://www.rapidio.org)
*
+ * Copyright (C) 2007-2009 Freescale Semiconductor, Inc.
+ *
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
@@ -24,11 +26,23 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/hardirq.h>
#include "rio.h"
static LIST_HEAD(rio_mports);
+static DEFINE_SPINLOCK(rio_config_lock);
+
+struct resource rio_resource = {
+ .name = "RapidIO GSM",
+ .start = 0,
+ .end = -1,
+ .flags = IORESOURCE_MEM,
+};
+EXPORT_SYMBOL(rio_resource);
+
/**
* rio_local_get_device_id - Get the base/extended device id for a port
* @port: RIO master port from which to get the deviceid
@@ -333,6 +347,87 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
}
/**
+ * rio_map_inb_region -- Mapping inbound memory region.
+ * @mport: Master port.
+ * @mem: Memory struction for mapping.
+ * @rflags: Flags for mapping.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the mapping from rio space to local mem.
+ */
+int rio_map_inb_region(struct rio_mport *mport, struct resource *rio_res,
+ dma_addr_t local, u32 rflags)
+{
+ int rc = 0;
+ unsigned long flags;
+
+ if (!mport->mops)
+ return -1;
+ spin_lock_irqsave(&rio_config_lock, flags);
+ rc = mport->mops->map_inb(mport, local, rio_res->start,
+ resource_size(rio_res), rflags);
+ spin_unlock_irqrestore(&rio_config_lock, flags);
+ return rc;
+}
+
+/**
+ * rio_map_outb_region -- Mapping outbound memory region.
+ * @mport: Master port.
+ * @tid: Target RapidIO device id.
+ * @mem: Memory struction for mapping.
+ * @rflags: Flags for mapping.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the mapping from local iomem to rio space.
+ */
+int rio_map_outb_region(struct rio_mport *mport, u16 tid,
+ struct resource *rio_res, phys_addr_t lstart, u32 rflags)
+{
+ int rc = 0;
+ unsigned long flags;
+
+ if (!mport->mops)
+ return -1;
+ spin_lock_irqsave(&rio_config_lock, flags);
+ rc = mport->mops->map_outb(mport, lstart, rio_res->start,
+ resource_size(rio_res), tid, rflags);
+ spin_unlock_irqrestore(&rio_config_lock, flags);
+ return rc;
+}
+
+/**
+ * rio_unmap_inb_region -- Unmap the inbound memory region
+ * @mport: Master port
+ * @mem: Memory struction for unmapping.
+ */
+void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart)
+{
+ unsigned long flags;
+ if (!mport->mops)
+ return;
+ spin_lock_irqsave(&rio_config_lock, flags);
+ mport->mops->unmap_inb(mport, lstart);
+ spin_unlock_irqrestore(&rio_config_lock, flags);
+}
+
+/**
+ * rio_unmap_outb_region -- Unmap the outbound memory region
+ * @mport: Master port
+ * @mem: Memory struction for unmapping.
+ */
+void rio_unmap_outb_region(struct rio_mport *mport, phys_addr_t lstart)
+{
+ unsigned long flags;
+ if (!mport->mops)
+ return;
+ spin_lock_irqsave(&rio_config_lock, flags);
+ mport->mops->unmap_outb(mport, lstart);
+ spin_unlock_irqrestore(&rio_config_lock, flags);
+}
+
+/**
* rio_mport_get_feature - query for devices' extended features
* @port: Master port to issue transaction
* @local: Indicate a local master port or remote device access
diff --git a/include/linux/rio.h b/include/linux/rio.h
index dc0c755..dd61538 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -176,6 +176,7 @@ struct rio_mport {
struct rio_msg outb_msg[RIO_MAX_MBOX];
int host_deviceid; /* Host device ID */
struct rio_ops *ops; /* maintenance transaction functions */
+ struct rio_mem_ops *mops; /* Memory functions */
unsigned char id; /* port ID, unique among all ports */
unsigned char index; /* port index, unique among all port
interfaces of the same type */
@@ -185,6 +186,7 @@ struct rio_mport {
*/
enum rio_phy_type phy_type; /* RapidIO phy type */
unsigned char name[40];
+ struct device *dev;
void *priv; /* Master port private data */
};
@@ -319,6 +321,29 @@ struct rio_route_ops {
u16 table, u16 route_destid, u8 * route_port);
};
+extern struct resource rio_resource;
+#define request_rio_region(start, n, name, flag) \
+ __request_region(&rio_resource, (start), (n), (name), (flag))
+#define release_rio_region(start, n) __release_region(&rio_resource, (start), (n))
+
+/**
+ * Struct for RIO memory definition.
+ * @map_inb: The function for mapping inbound memory window.
+ * @map_outb: The function for mapping outbound memory window.
+ * @unmap_inb: The function for unmapping inbound memory window.
+ * @unmap_outb: The function for unmapping outbound memory window.
+ */
+struct rio_mem_ops {
+ int (*map_inb) (struct rio_mport *, dma_addr_t lstart,
+ resource_size_t rstart,
+ resource_size_t size, u32 flags);
+ int (*map_outb) (struct rio_mport *, phys_addr_t lstart,
+ resource_size_t rstart,
+ resource_size_t size, u16 tid, u32 flags);
+ void (*unmap_inb) (struct rio_mport *, dma_addr_t lstart);
+ void (*unmap_outb) (struct rio_mport *, phys_addr_t lstart);
+};
+
/* Architecture and hardware-specific functions */
extern int rio_init_mports(void);
extern void rio_register_mport(struct rio_mport *);
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index c93a58a..685f2da 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -332,6 +332,16 @@ static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
res->flags = RIO_RESOURCE_DOORBELL;
}
+static inline void rio_init_io_res(struct resource *res, resource_size_t start,
+ resource_size_t size, const char *name, unsigned long flag)
+{
+ memset(res, 0, sizeof(struct resource));
+ res->start = start;
+ res->end = start + size - 1;
+ res->name = name;
+ res->flags = flag;
+}
+
/**
* RIO_DEVICE - macro used to describe a specific RIO device
* @dev: the 16 bit RIO device ID
@@ -406,12 +416,13 @@ extern int rio_release_inb_dbell(struct rio_mport *, u16, u16);
extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
-/* Memory region management */
-int rio_claim_resource(struct rio_dev *, int);
-int rio_request_regions(struct rio_dev *, char *);
-void rio_release_regions(struct rio_dev *);
-int rio_request_region(struct rio_dev *, int, char *);
-void rio_release_region(struct rio_dev *, int);
+/* Memory low-level mapping functions */
+extern int rio_map_inb_region(struct rio_mport *, struct resource *,
+ dma_addr_t, u32);
+extern int rio_map_outb_region(struct rio_mport *, u16, struct resource *,
+ phys_addr_t, u32);
+extern void rio_unmap_inb_region(struct rio_mport *, dma_addr_t);
+extern void rio_unmap_outb_region(struct rio_mport *, phys_addr_t);
/* LDM support */
int rio_register_driver(struct rio_driver *);
@@ -461,5 +472,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);
extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
struct rio_dev *from);
+extern u32 rio_get_mport_id(struct rio_mport *);
#endif /* LINUX_RIO_DRV_H */
--
1.5.4
^ permalink raw reply related
* [PATCH 5/6] rio: warn_unused_result warnings fix
From: Li Yang @ 2009-05-12 8:36 UTC (permalink / raw)
To: akpm, galak, davem, mporter; +Cc: linuxppc-dev, Li Yang, linux-kernel, netdev
In-Reply-To: <1242117363-14949-4-git-send-email-leoli@freescale.com>
Adding failure path for the following two cases.
warning: ignoring return value of 'device_add', declared with attribute warn_unused_result
warning: ignoring return value of 'sysfs_create_bin_file', declared with attribute warn_unused_result
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/rapidio/rio-scan.c | 44 ++++++++++++++++++++++++++----------------
drivers/rapidio/rio-sysfs.c | 6 +++-
2 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 74d0bfa..0838fb2 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -263,15 +263,21 @@ static void rio_route_set_ops(struct rio_dev *rdev)
* device to the RIO device list. Creates the generic sysfs nodes
* for an RIO device.
*/
-static void __devinit rio_add_device(struct rio_dev *rdev)
+static int __devinit rio_add_device(struct rio_dev *rdev)
{
- device_add(&rdev->dev);
+ int err;
+
+ err = device_add(&rdev->dev);
+ if (err)
+ return err;
spin_lock(&rio_global_list_lock);
list_add_tail(&rdev->global_list, &rio_devices);
spin_unlock(&rio_global_list_lock);
rio_create_sysfs_dev_files(rdev);
+
+ return 0;
}
/**
@@ -294,13 +300,14 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
struct rio_mport *port, u16 destid,
u8 hopcount, int do_enum)
{
+ int ret = 0;
struct rio_dev *rdev;
- struct rio_switch *rswitch;
+ struct rio_switch *rswitch = NULL;
int result, rdid;
rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL);
if (!rdev)
- goto out;
+ return NULL;
rdev->net = net;
rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
@@ -343,23 +350,16 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rio_mport_read_config_32(port, destid, hopcount,
RIO_SWP_INFO_CAR, &rdev->swpinfo);
rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
- if (!rswitch) {
- kfree(rdev);
- rdev = NULL;
- goto out;
- }
+ if (!rswitch)
+ goto cleanup;
rswitch->switchid = next_switchid;
rswitch->hopcount = hopcount;
rswitch->destid = destid;
rswitch->route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port->sys_size),
GFP_KERNEL);
- if (!rswitch->route_table) {
- kfree(rdev);
- rdev = NULL;
- kfree(rswitch);
- goto out;
- }
+ if (!rswitch->route_table)
+ goto cleanup;
/* Initialize switch route table */
for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
rdid++)
@@ -390,10 +390,20 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
0, 0xffff);
- rio_add_device(rdev);
+ ret = rio_add_device(rdev);
+ if (ret)
+ goto cleanup;
- out:
return rdev;
+
+cleanup:
+ if (rswitch) {
+ if (rswitch->route_table)
+ kfree(rswitch->route_table);
+ kfree(rswitch);
+ }
+ kfree(rdev);
+ return NULL;
}
/**
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 97a147f..ba742e8 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -214,9 +214,11 @@ static struct bin_attribute rio_config_attr = {
*/
int rio_create_sysfs_dev_files(struct rio_dev *rdev)
{
- sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+ int err = 0;
- return 0;
+ err = sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+
+ return err;
}
/**
--
1.5.4
^ permalink raw reply related
* [PATCH 4/6] rionet: add memory access to simulated Ethernet over rapidio
From: Li Yang @ 2009-05-12 8:36 UTC (permalink / raw)
To: akpm, galak, davem, mporter
Cc: linuxppc-dev, Zhang Wei, Li Yang, linux-kernel, netdev
In-Reply-To: <1242117363-14949-3-git-send-email-leoli@freescale.com>
Through the newly added IO memory access of RapidIO, sender can
write directly to recipient's rx buffer, either by cpu or DMA engine.
Signed-off-by: Zhang Wei <zw@zh-kernel.org>
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/net/Kconfig | 10 ++
drivers/net/rionet.c | 365 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 371 insertions(+), 4 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 214a92d..1e88e26 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2736,6 +2736,16 @@ config RIONET_RX_SIZE
depends on RIONET
default "128"
+config RIONET_MEMMAP
+ bool "Use memory map instead of message"
+ depends on RIONET
+ default n
+
+config RIONET_DMA
+ bool "Use DMA for memory mapping data transfer"
+ depends on RIONET_MEMMAP && FSL_DMA
+ default y
+
config FDDI
tristate "FDDI driver support"
depends on (PCI || EISA || TC)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index ec59e29..c38e51e 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -1,6 +1,8 @@
/*
* rionet - Ethernet driver over RapidIO messaging services
*
+ * Copyright (C) 2007-2009 Freescale Semiconductor, Inc.
+ *
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
@@ -23,6 +25,7 @@
#include <linux/skbuff.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
+#include <linux/dmaengine.h>
#define DRV_NAME "rionet"
#define DRV_VERSION "0.2"
@@ -40,13 +43,48 @@ MODULE_LICENSE("GPL");
NETIF_MSG_TX_ERR)
#define RIONET_DOORBELL_JOIN 0x1000
+#ifdef CONFIG_RIONET_MEMMAP
+#define RIONET_DOORBELL_SEND 0x1001
+#define RIONET_DOORBELL_LEAVE 0x1002
+#else
#define RIONET_DOORBELL_LEAVE 0x1001
+#endif
#define RIONET_MAILBOX 0
#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
+#define ERR(fmt, arg...) \
+ printk(KERN_ERR "ERROR %s - %s: " fmt, __FILE__, __func__, ## arg)
+
+#ifdef CONFIG_RIONET_MEMMAP
+/* Definitions for rionet memory map driver */
+#define RIONET_DRVID 0x101
+#define RIONET_MAX_SK_DATA_SIZE 0x1000
+#define RIONET_MEM_RIO_BASE 0x10000000
+#define RIONET_TX_RX_BUFF_SIZE (0x1000 * (128 + 128))
+#define RIONET_QUEUE_NEXT(x) (((x) < 127) ? ((x) + 1) : 0)
+#define RIONET_QUEUE_INC(x) (x = RIONET_QUEUE_NEXT(x))
+
+struct sk_data {
+ u8 data[0x1000];
+};
+
+#define RIONET_SKDATA_EN 0x80000000
+struct rionet_tx_rx_buff {
+ int enqueue; /* enqueue point */
+ int dequeue; /* dequeue point */
+ u32 size[128]; /* size[i] is skdata[i] size
+ * the most high bit [31] is
+ * enable bit. The
+ * max size is 4096.
+ */
+ u8 rev1[3576];
+ struct sk_data skdata[128]; /* all size are 0x1000 * 128 */
+};
+#endif /* CONFIG_RIONET_MEMMAP */
+
static LIST_HEAD(rionet_peers);
struct rionet_private {
@@ -60,6 +98,19 @@ struct rionet_private {
spinlock_t lock;
spinlock_t tx_lock;
u32 msg_enable;
+#ifdef CONFIG_RIONET_MEMMAP
+ struct rionet_tx_rx_buff *rxbuff;
+ struct rionet_tx_rx_buff __iomem *txbuff;
+ dma_addr_t rx_addr;
+ phys_addr_t tx_addr;
+ struct resource *riores;
+#ifdef CONFIG_RIONET_DMA
+ struct dma_chan *txdmachan;
+ struct dma_chan *rxdmachan;
+ struct dma_client rio_dma_client;
+ spinlock_t rio_dma_event_lock;
+#endif
+#endif
};
struct rionet_peer {
@@ -90,6 +141,7 @@ static struct rio_dev **rionet_active;
#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001)
#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4))
+#ifndef CONFIG_RIONET_MEMMAP
static int rionet_rx_clean(struct net_device *ndev)
{
int i;
@@ -108,9 +160,11 @@ static int rionet_rx_clean(struct net_device *ndev)
rnet->rx_skb[i]->data = data;
skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
+ rnet->rx_skb[i]->dev = ndev;
rnet->rx_skb[i]->protocol =
eth_type_trans(rnet->rx_skb[i], ndev);
error = netif_rx(rnet->rx_skb[i]);
+ rnet->rx_skb[i] = NULL;
if (error == NET_RX_DROP) {
ndev->stats.rx_dropped++;
@@ -128,6 +182,7 @@ static int rionet_rx_clean(struct net_device *ndev)
return i;
}
+#endif
static void rionet_rx_fill(struct net_device *ndev, int end)
{
@@ -141,19 +196,86 @@ static void rionet_rx_fill(struct net_device *ndev, int end)
if (!rnet->rx_skb[i])
break;
+#ifndef CONFIG_RIONET_MEMMAP
rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
rnet->rx_skb[i]->data);
+#endif
} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
rnet->rx_slot = i;
}
+#ifdef CONFIG_RIONET_MEMMAP
+static int rio_send_mem(struct sk_buff *skb,
+ struct net_device *ndev, struct rio_dev *rdev)
+{
+ struct rionet_private *rnet = netdev_priv(ndev);
+ int enqueue, dequeue;
+
+ if (!rdev)
+ return -EFAULT;
+
+ if (skb->len > RIONET_MAX_SK_DATA_SIZE) {
+ printk(KERN_ERR "Frame len is more than RIONET max sk_data!\n");
+ return -EINVAL;
+ }
+
+ rio_map_outb_region(rnet->mport, rdev->destid, rnet->riores,
+ rnet->tx_addr, 0);
+
+ enqueue = in_be32(&rnet->txbuff->enqueue);
+ dequeue = in_be32(&rnet->txbuff->dequeue);
+
+ if (!(in_be32(&rnet->txbuff->size[enqueue]) & RIONET_SKDATA_EN)
+ && (RIONET_QUEUE_NEXT(enqueue) != dequeue)) {
+#ifdef CONFIG_RIONET_DMA
+ struct dma_device *dmadev;
+ struct dma_async_tx_descriptor *tx;
+ dma_cookie_t tx_cookie = 0;
+
+ dmadev = rnet->txdmachan->device;
+ tx = dmadev->device_prep_dma_memcpy(rnet->txdmachan,
+ (void *)rnet->txbuff->skdata[enqueue].data
+ - (void *)rnet->txbuff rnet->tx_addr,
+ dma_map_single(&ndev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE), skb->len, DMA_CTRL_ACK);
+ if (!tx)
+ return -EFAULT;
+ tx_cookie = tx->tx_submit(tx);
+
+ dma_async_memcpy_issue_pending(rnet->txdmachan);
+ while (dma_async_memcpy_complete(rnet->txdmachan,
+ tx_cookie, NULL, NULL) == DMA_IN_PROGRESS) ;
+#else
+ memcpy(rnet->txbuff->skdata[enqueue].data, skb->data, skb->len);
+#endif /* CONFIG_RIONET_DMA */
+ out_be32(&rnet->txbuff->size[enqueue],
+ RIONET_SKDATA_EN | skb->len);
+ out_be32(&rnet->txbuff->enqueue,
+ RIONET_QUEUE_NEXT(enqueue));
+ in_be32(&rnet->txbuff->enqueue); /* verify read */
+ } else if (netif_msg_tx_err(rnet))
+ printk(KERN_ERR "rionmet(memmap): txbuff is busy!\n");
+
+ rio_unmap_outb_region(rnet->mport, rnet->tx_addr);
+ rio_send_doorbell(rdev, RIONET_DOORBELL_SEND);
+ return 0;
+}
+#endif
+
static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
struct rio_dev *rdev)
{
struct rionet_private *rnet = netdev_priv(ndev);
+#ifdef CONFIG_RIONET_MEMMAP
+ int ret = 0;
+ ret = rio_send_mem(skb, ndev, rdev);
+ if (ret)
+ return ret;
+#else
rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
+#endif
rnet->tx_skb[rnet->tx_slot] = skb;
ndev->stats.tx_packets++;
@@ -165,6 +287,19 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
++rnet->tx_slot;
rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
+#ifdef CONFIG_RIONET_MEMMAP
+ while (rnet->tx_cnt && (rnet->ack_slot != rnet->tx_slot)) {
+ /* dma unmap single */
+ dev_kfree_skb_any(rnet->tx_skb[rnet->ack_slot]);
+ rnet->tx_skb[rnet->ack_slot] = NULL;
+ ++rnet->ack_slot;
+ rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
+ rnet->tx_cnt--;
+ }
+
+ if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
+ netif_wake_queue(ndev);
+#endif
if (netif_msg_tx_queued(rnet))
printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
(u32) skb, skb->len);
@@ -211,6 +346,92 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return 0;
}
+#ifdef CONFIG_RIONET_MEMMAP
+static void rio_recv_mem(struct net_device *ndev)
+{
+ struct rionet_private *rnet = netdev_priv(ndev);
+ struct sk_buff *skb;
+ u32 enqueue, dequeue, size;
+ int error = 0;
+#ifdef CONFIG_RIONET_DMA
+ dma_cookie_t rx_cookie = 0;
+ struct dma_device *dmadev;
+ struct dma_async_tx_descriptor *tx;
+#endif
+
+ dequeue = rnet->rxbuff->dequeue;
+ enqueue = rnet->rxbuff->enqueue;
+
+ while (enqueue != dequeue) {
+ size = rnet->rxbuff->size[dequeue];
+ if (!(size & RIONET_SKDATA_EN))
+ return;
+ size &= ~RIONET_SKDATA_EN;
+
+ skb = dev_alloc_skb(size + 2);
+ if (!skb)
+ return;
+
+#ifdef CONFIG_RIONET_DMA
+ dmadev = rnet->rxdmachan->device;
+ tx = dmadev->device_prep_dma_memcpy(rnet->rxdmachan,
+ dma_map_single(&ndev->dev, skb_put(skb, size),
+ size, DMA_FROM_DEVICE),
+ (void *)rnet->rxbuff->skdata[dequeue].data
+ - (void *)rnet->rxbuff + rnet->rx_addr,
+ size, DMA_CTRL_ACK);
+ if (!tx)
+ return;
+ rx_cookie = tx->tx_submit(tx);
+ dma_async_memcpy_issue_pending(rnet->rxdmachan);
+ while (dma_async_memcpy_complete(rnet->rxdmachan,
+ rx_cookie, NULL, NULL) == DMA_IN_PROGRESS);
+#else
+ memcpy(skb_put(skb, size),
+ rnet->rxbuff->skdata[dequeue].data,
+ size);
+#endif /* CONFIG_RIONET_DMA */
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ error = netif_rx(skb);
+
+ rnet->rxbuff->size[dequeue] &= ~RIONET_SKDATA_EN;
+ rnet->rxbuff->dequeue = RIONET_QUEUE_NEXT(dequeue);
+ dequeue = RIONET_QUEUE_NEXT(dequeue);
+
+ if (error == NET_RX_DROP) {
+ ndev->stats.rx_dropped++;
+ } else if (error == NET_RX_BAD) {
+ if (netif_msg_rx_err(rnet))
+ printk(KERN_WARNING "%s: bad rx packet\n",
+ DRV_NAME);
+ ndev->stats.rx_errors++;
+ } else {
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE;
+ }
+ }
+}
+
+static void rionet_inb_recv_event(struct rio_mport *mport, void *dev_id)
+{
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = netdev_priv(ndev);
+ unsigned long flags;
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO "%s: inbound memory data receive event\n",
+ DRV_NAME);
+
+ spin_lock_irqsave(&rnet->lock, flags);
+ rio_recv_mem(ndev);
+ spin_unlock_irqrestore(&rnet->lock, flags);
+}
+#endif
+
+
static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
u16 info)
{
@@ -232,6 +453,10 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
}
} else if (info == RIONET_DOORBELL_LEAVE) {
rionet_active[sid] = NULL;
+#ifdef CONFIG_RIONET_MEMMAP
+ } else if (info == RIONET_DOORBELL_SEND) {
+ rionet_inb_recv_event(mport, ndev);
+#endif
} else {
if (netif_msg_intr(rnet))
printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -239,6 +464,7 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
}
}
+#ifndef CONFIG_RIONET_MEMMAP
static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
{
int n;
@@ -281,6 +507,58 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo
spin_unlock(&rnet->lock);
}
+#endif
+
+#ifdef CONFIG_RIONET_DMA
+static enum dma_state_client rionet_dma_event(struct dma_client *client,
+ struct dma_chan *chan, enum dma_state state)
+{
+ struct rionet_private *rnet = container_of(client,
+ struct rionet_private, rio_dma_client);
+ enum dma_state_client ack = DMA_DUP;
+
+ spin_lock(&rnet->lock);
+ switch (state) {
+ case DMA_RESOURCE_AVAILABLE:
+ if (!rnet->txdmachan) {
+ ack = DMA_ACK;
+ rnet->txdmachan = chan;
+ } else if (!rnet->rxdmachan) {
+ ack = DMA_ACK;
+ rnet->rxdmachan = chan;
+ }
+ break;
+ case DMA_RESOURCE_REMOVED:
+ if (rnet->txdmachan == chan) {
+ ack = DMA_ACK;
+ rnet->txdmachan = NULL;
+ } else if (rnet->rxdmachan == chan) {
+ ack = DMA_ACK;
+ rnet->rxdmachan = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ spin_unlock(&rnet->lock);
+ return ack;
+}
+
+static int rionet_dma_register(struct rionet_private *rnet)
+{
+ int rc = 0;
+ spin_lock_init(&rnet->rio_dma_event_lock);
+ rnet->rio_dma_client.event_callback = rionet_dma_event;
+ dma_cap_set(DMA_MEMCPY, rnet->rio_dma_client.cap_mask);
+ dma_async_client_register(&rnet->rio_dma_client);
+ dma_async_client_chan_request(&rnet->rio_dma_client);
+
+ if (!rnet->txdmachan || !rnet->rxdmachan)
+ rc = -ENODEV;
+
+ return rc;
+}
+#endif
static int rionet_open(struct net_device *ndev)
{
@@ -297,21 +575,63 @@ static int rionet_open(struct net_device *ndev)
RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE,
rionet_dbell_event)) < 0)
- goto out;
+ return rc;
+
+#ifdef CONFIG_RIONET_MEMMAP
+ if (!request_rio_region(RIONET_MEM_RIO_BASE, RIONET_TX_RX_BUFF_SIZE,
+ ndev->name, 0)) {
+ dev_err(&ndev->dev, "RapidIO space busy\n");
+ rc = -EBUSY;
+ goto out1;
+ }
+ rnet->riores = kmalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!rnet->riores) {
+ rc = -ENOMEM;
+ goto out2;
+ }
+ rnet->riores->start = RIONET_MEM_RIO_BASE;
+ rnet->riores->end = RIONET_MEM_RIO_BASE + RIONET_TX_RX_BUFF_SIZE - 1;
+ rnet->rxbuff = dma_alloc_coherent(&ndev->dev, RIONET_TX_RX_BUFF_SIZE,
+ &rnet->rx_addr, GFP_KERNEL);
+ if (!rnet->rxbuff) {
+ rc = -ENOMEM;
+ goto out3;
+ }
+ rc = rio_map_inb_region(rnet->mport, rnet->riores, rnet->rx_addr, 0);
+ if (rc) {
+ rc = -EBUSY;
+ goto out4;
+ }
+
+ /* Use space right after the doorbell window, aligned to
+ * size of RIONET_TX_RX_BUFF_SIZE */
+ rnet->tx_addr = rnet->mport->iores.start + 0x500000;
+ rnet->txbuff = ioremap(rnet->tx_addr, resource_size(rnet->riores));
+ if (!rnet->txbuff) {
+ rc = -ENOMEM;
+ goto out5;
+ }
+#ifdef CONFIG_RIONET_DMA
+ rc = rionet_dma_register(rnet);
+ if (rc)
+ goto out6;
+#endif /* CONFIG_RIONET_DMA */
+#else
if ((rc = rio_request_inb_mbox(rnet->mport,
(void *)ndev,
RIONET_MAILBOX,
RIONET_RX_RING_SIZE,
rionet_inb_msg_event)) < 0)
- goto out;
+ goto out1;
if ((rc = rio_request_outb_mbox(rnet->mport,
(void *)ndev,
RIONET_MAILBOX,
RIONET_TX_RING_SIZE,
rionet_outb_msg_event)) < 0)
- goto out;
+ goto out8;
+#endif
/* Initialize inbound message ring */
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
@@ -344,8 +664,31 @@ static int rionet_open(struct net_device *ndev)
if (pwdcsr & RIO_DOORBELL_AVAIL)
rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
}
+ return 0;
- out:
+#ifndef CONFIG_RIONET_MEMMAP
+out8:
+ rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
+#else
+#ifdef CONFIG_RIONET_DMA
+out6:
+ iounmap(rnet->txbuff);
+#endif
+out5:
+ rio_unmap_inb_region(rnet->mport, rnet->rx_addr);
+out4:
+ dma_free_coherent(&ndev->dev, RIONET_TX_RX_BUFF_SIZE,
+ rnet->rxbuff, rnet->rx_addr);
+ rnet->rxbuff = NULL;
+ rnet->txbuff = NULL;
+out3:
+ kfree(rnet->riores);
+out2:
+ release_rio_region(RIONET_MEM_RIO_BASE, RIONET_TX_RX_BUFF_SIZE);
+#endif
+out1:
+ rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE);
return rc;
}
@@ -374,8 +717,22 @@ static int rionet_close(struct net_device *ndev)
rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE);
+#ifdef CONFIG_RIONET_MEMMAP
+ rio_unmap_inb_region(rnet->mport, rnet->rx_addr);
+ iounmap(rnet->txbuff);
+ dma_free_coherent(&ndev->dev, RIONET_TX_RX_BUFF_SIZE,
+ rnet->rxbuff, rnet->rx_addr);
+ kfree(rnet->riores);
+ release_rio_region(RIONET_MEM_RIO_BASE, RIONET_TX_RX_BUFF_SIZE);
+ rnet->rxbuff = NULL;
+ rnet->txbuff = NULL;
+#ifdef CONFIG_RIONET_DMA
+ dma_async_client_unregister(&rnet->rio_dma_client);
+#endif
+#else
rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
+#endif
return 0;
}
--
1.5.4
^ permalink raw reply related
* [PATCH 6/6] rio: fix section mismatch
From: Li Yang @ 2009-05-12 8:36 UTC (permalink / raw)
To: akpm, galak, davem, mporter; +Cc: linuxppc-dev, Li Yang, linux-kernel, netdev
In-Reply-To: <1242117363-14949-5-git-send-email-leoli@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/rapidio/rio-scan.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 0838fb2..e29be3c 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -296,7 +296,7 @@ static int __devinit rio_add_device(struct rio_dev *rdev)
* to a RIO device on success or NULL on failure.
*
*/
-static struct rio_dev *rio_setup_device(struct rio_net *net,
+static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
struct rio_mport *port, u16 destid,
u8 hopcount, int do_enum)
{
@@ -569,7 +569,7 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
* Recursively enumerates a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
u8 hopcount)
{
int port_num;
@@ -728,7 +728,7 @@ static int rio_enum_complete(struct rio_mport *port)
* Recursively discovers a RIO network. Transactions are sent via the
* master port passed in @port.
*/
-static int
+static int __devinit
rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
u8 hopcount)
{
--
1.5.4
^ permalink raw reply related
* [PATCH 2/6] powerpc/fsl_rio: use LAW address from device tree
From: Li Yang @ 2009-05-12 8:35 UTC (permalink / raw)
To: akpm, galak, davem, mporter; +Cc: linuxppc-dev, Li Yang, linux-kernel, netdev
In-Reply-To: <1242117363-14949-1-git-send-email-leoli@freescale.com>
Instead of fixed address in old code.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index abdb124..fa0720f 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1077,8 +1077,9 @@ int fsl_rio_setup(struct of_device *dev)
INIT_LIST_HEAD(&port->dbells);
port->iores.start = law_start;
- port->iores.end = law_start + law_size;
+ port->iores.end = law_start + law_size - 1;
port->iores.flags = IORESOURCE_MEM;
+ port->iores.name = "rio_io_win";
priv->bellirq = irq_of_parse_and_map(dev->node, 2);
priv->txirq = irq_of_parse_and_map(dev->node, 3);
@@ -1156,14 +1157,15 @@ int fsl_rio_setup(struct of_device *dev)
out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
/* Configure maintenance transaction window */
- out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
- out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
+ out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12);
+ out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */
priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
/* Configure outbound doorbell window */
- out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
- out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
+ out_be32(&priv->dbell_atmu_regs->rowbar,
+ (law_start + RIO_MAINT_WIN_SIZE) >> 12);
+ out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); /* 4k */
fsl_rio_doorbell_init(port);
return 0;
--
1.5.4
^ permalink raw reply related
* [PATCH 3/6] powerpc: add memory map support to Freescale RapidIO block
From: Li Yang @ 2009-05-12 8:36 UTC (permalink / raw)
To: akpm, galak, davem, mporter
Cc: linuxppc-dev, Zhang Wei, Li Yang, linux-kernel, netdev
In-Reply-To: <1242117363-14949-2-git-send-email-leoli@freescale.com>
The RIO memory map functions are used to support direct IO memory access
to RapidIO space. The patch adds its support for Freescale RapidIO block
driver.
Signed-off-by: Zhang Wei <zw@zh-kernel.org>
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 217 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 215 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index fa0720f..7056dc0 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -31,6 +31,9 @@
#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
+#define IS_64BIT_DMA ((sizeof(dma_addr_t) == 8) ? 1 : 0)
+#define IS_64BIT_PHYS ((sizeof(phys_addr_t) == 8) ? 1 : 0)
+
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_P_MSG_REGS_OFFSET 0x11000
#define RIO_S_MSG_REGS_OFFSET 0x13000
@@ -40,6 +43,15 @@
#define RIO_ISR_AACR_AA 0x1 /* Accept All ID */
#define RIO_MAINT_WIN_SIZE 0x400000
#define RIO_DBELL_WIN_SIZE 0x1000
+#define RIO_MAX_INB_ATMU 4
+#define RIO_MAX_OUTB_ATMU 8
+#define RIO_INB_ATMU_REGS_OFFSET 0x10de0
+#define RIO_ATMU_EN_MASK 0x80000000
+
+#define RIO_NREAD 0x4
+#define RIO_NWRITE 0x4
+#define RIO_NWRITE_R 0x5
+#define RIO_NREAD_R 0x5
#define RIO_MSG_OMR_MUI 0x00000002
#define RIO_MSG_OSR_TE 0x00000080
@@ -83,6 +95,15 @@ struct rio_atmu_regs {
u32 pad3[3];
};
+struct rio_inb_atmu_regs {
+ u32 riwtar;
+ u32 pad1;
+ u32 riwbar;
+ u32 pad2;
+ u32 riwar;
+ u32 pad3[3];
+};
+
struct rio_msg_regs {
u32 omr;
u32 osr;
@@ -341,6 +362,188 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
}
/**
+ * fsl_rio_map_inb_mem -- Mapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the inbound mapping
+ * from rstart to lstart.
+ */
+static int fsl_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
+ resource_size_t rstart, resource_size_t size, u32 flags)
+{
+ int i;
+ struct rio_priv *priv = mport->priv;
+ struct rio_inb_atmu_regs __iomem *inbatmu = (struct rio_inb_atmu_regs *)
+ (priv->regs_win + RIO_INB_ATMU_REGS_OFFSET) - 1;
+ int size_ffs;
+ resource_size_t align;
+
+ if (flags == 0)
+ flags = (RIO_NREAD_R << 4) | RIO_NWRITE_R;
+
+ align = (size < 0x1000) ? 0x1000 : 1 << (__ilog2(size - 1) + 1);
+
+ /* Align the size */
+ if ((lstart + size) > (_ALIGN_DOWN(lstart, align) + align)) {
+ size_ffs = __ffs(_ALIGN_DOWN(lstart + size - 1, align));
+ size = 1 << (size_ffs + (((_ALIGN_DOWN(lstart, 1 << size_ffs) +
+ (1 << size_ffs)) < (lstart + size)) ? 1 : 0));
+ } else
+ size = align;
+
+ if ((lstart & (size - 1)) != (rstart & (size - 1))) {
+ dev_err(mport->dev, "The local address 0x%llx can not be "
+ "aligned to the same size 0x%llx with the RapidIO "
+ "space address 0x%llx!\n", (unsigned long long)lstart,
+ (unsigned long long)size, (unsigned long long)rstart);
+ return -EINVAL;
+ }
+
+ /* Search for free inbound ATMU */
+ for (i = 1;
+ (i <= RIO_MAX_INB_ATMU) && (inbatmu->riwar & RIO_ATMU_EN_MASK);
+ i++, inbatmu--)
+ ;
+
+ if (i > RIO_MAX_INB_ATMU) {
+ dev_err(mport->dev, "No free inbound ATMU!\n");
+ return -EBUSY;
+ }
+ out_be32(&inbatmu->riwtar, ((IS_64BIT_DMA ? (lstart >> 32)
+ & 0xf : 0) << 20) | ((lstart >> 12) & 0xfffff));
+ out_be32(&inbatmu->riwbar, ((IS_64BIT_DMA ? (rstart >> 32)
+ & 0x3 : 0) << 20) | ((rstart >> 12) & 0xfffff));
+ out_be32(&inbatmu->riwar, 0x80000000 | (0xf << 20)
+ | ((flags & 0xff) << 12)
+ | (__ilog2(size) - 1));
+ return 0;
+}
+
+/**
+ * fsl_rio_map_outb_mem -- Mapping outbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @tid: The target RapidIO device id.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the outbound mapping
+ * from lstart to rstart.
+ */
+static int fsl_rio_map_outb_mem(struct rio_mport *mport, phys_addr_t lstart,
+ resource_size_t rstart, resource_size_t size,
+ u16 tid, u32 flags)
+{
+ int i;
+ struct rio_priv *priv = mport->priv;
+ struct rio_atmu_regs __iomem *outbatmu = (struct rio_atmu_regs *)
+ (priv->regs_win + RIO_ATMU_REGS_OFFSET) + 1;
+ int size_ffs;
+ resource_size_t align;
+
+ if (flags == 0)
+ flags = (RIO_NREAD << 4) | RIO_NWRITE_R;
+
+ align = (size < 0x1000) ? 0x1000 : 1 << (__ilog2(size - 1) + 1);
+
+ /* Align the size */
+ if ((lstart + size) > (_ALIGN_DOWN(lstart, align) + align)) {
+ size_ffs = __ffs(_ALIGN_DOWN(lstart + size - 1, align));
+ size = 1 << (size_ffs + (((_ALIGN_DOWN(lstart, 1 << size_ffs) +
+ (1 << size_ffs)) < (lstart + size)) ? 1 : 0));
+ } else
+ size = align;
+
+ if ((lstart & (size - 1)) != (rstart & (size - 1))) {
+ dev_err(mport->dev, "The local address 0x%llx can not be "
+ "aligned to the same size 0x%llx with the RapidIO "
+ "space address 0x%llx!\n", (unsigned long long)lstart,
+ (unsigned long long)size, (unsigned long long)rstart);
+ return -EINVAL;
+ }
+
+ /* Search for free outbound ATMU */
+ for (i = 1;
+ (i <= RIO_MAX_OUTB_ATMU) && (outbatmu->rowar & RIO_ATMU_EN_MASK);
+ i++, outbatmu++)
+ ;
+
+ if (i > RIO_MAX_OUTB_ATMU) {
+ dev_err(mport->dev, "No free outbound ATMU!\n");
+ return -EBUSY;
+ }
+ out_be32(&outbatmu->rowtar, ((tid & 0x3ff) << 22)
+ | ((IS_64BIT_PHYS ? (rstart >> 32) & 0x3 : 0) << 20)
+ | ((rstart >> 12) & 0xfffff));
+ if (mport->phy_type == RIO_PHY_SERIAL)
+ out_be32(&outbatmu->rowtear, tid >> 10);
+ out_be32(&outbatmu->rowbar, ((IS_64BIT_PHYS ?
+ (lstart >> 32) & 0xf : 0) << 20)
+ | ((lstart >> 12) & 0xfffff));
+ out_be32(&outbatmu->rowar, 0x80000000
+ | ((flags & 0xff) << 12)
+ | (__ilog2(size) - 1));
+ return 0;
+}
+
+/**
+ * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ */
+static void fsl_rio_unmap_inb_mem(struct rio_mport *mport,
+ dma_addr_t lstart)
+{
+ int i;
+ struct rio_priv *priv = mport->priv;
+ struct rio_inb_atmu_regs __iomem *inbatmu = (struct rio_inb_atmu_regs *)
+ (priv->regs_win + RIO_INB_ATMU_REGS_OFFSET) - 1;
+
+ /* Search for inbound ATMU */
+ for (i = 1; i <= RIO_MAX_INB_ATMU ; i++, inbatmu--) {
+ u32 tar = ((IS_64BIT_DMA ? (lstart >> 32) & 0xf : 0) << 20)
+ | ((lstart >> 12) & 0xfffff);
+ if (inbatmu->riwtar == tar) {
+ out_be32(&inbatmu->riwar, ~(RIO_ATMU_EN_MASK));
+ return;
+ }
+ }
+}
+
+/**
+ * fsl_rio_unmap_outb_mem -- Unmapping outbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ */
+static void fsl_rio_unmap_outb_mem(struct rio_mport *mport,
+ phys_addr_t lstart)
+{
+ int i;
+ struct rio_priv *priv = mport->priv;
+ struct rio_atmu_regs __iomem *outbatmu = (struct rio_atmu_regs *)
+ (priv->regs_win + RIO_ATMU_REGS_OFFSET) + 1;
+
+ /* Search for outbound ATMU */
+ for (i = 1; i <= RIO_MAX_OUTB_ATMU ; i++, outbatmu++) {
+ u32 bar = ((IS_64BIT_PHYS ? (lstart >> 32) & 0xf : 0) << 20)
+ | ((lstart >> 12) & 0xfffff);
+ if (outbatmu->rowbar == bar) {
+ out_be32(&outbatmu->rowar, ~(RIO_ATMU_EN_MASK));
+ return;
+ }
+ }
+}
+
+/**
* rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
* @mport: Master port with outbound message queue
* @rdev: Target of outbound message
@@ -951,6 +1154,13 @@ static int fsl_rio_get_cmdline(char *s)
__setup("riohdid=", fsl_rio_get_cmdline);
+static struct rio_mem_ops fsl_mem_ops = {
+ .map_inb = fsl_rio_map_inb_mem,
+ .map_outb = fsl_rio_map_outb_mem,
+ .unmap_inb = fsl_rio_unmap_inb_mem,
+ .unmap_outb = fsl_rio_unmap_outb_mem,
+};
+
static inline void fsl_rio_info(struct device *dev, u32 ccsr)
{
const char *str;
@@ -1026,8 +1236,9 @@ int fsl_rio_setup(struct of_device *dev)
return -EFAULT;
}
dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
- dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n", regs.start,
- regs.end - regs.start + 1);
+ dev_info(&dev->dev, "Regs start 0x%llx size 0x%llx\n",
+ (unsigned long long)regs.start,
+ (unsigned long long)(regs.end - regs.start + 1));
dt_range = of_get_property(dev->node, "ranges", &rlen);
if (!dt_range) {
@@ -1067,6 +1278,7 @@ int fsl_rio_setup(struct of_device *dev)
port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
port->id = 0;
port->index = 0;
+ port->dev = &dev->dev;
priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
if (!priv) {
@@ -1095,6 +1307,7 @@ int fsl_rio_setup(struct of_device *dev)
priv->dev = &dev->dev;
port->ops = ops;
+ port->mops = &fsl_mem_ops;
port->host_deviceid = fsl_rio_get_hdid(port->id);
port->priv = priv;
--
1.5.4
^ permalink raw reply related
* [PATCH 0/6] rapidio: adding memory mapping IO support and misc fixes
From: Li Yang @ 2009-05-12 8:40 UTC (permalink / raw)
To: akpm, Kumar Gala, David Miller, mporter
Cc: linuxppc-dev Development, linux-kernel, Netdev
This is a re-post of patch series which adds MMIO support to Linux
RapidIO and fixes a few nits.
- Leo
^ permalink raw reply
* Re: [PowerPC] Next May 8 boot failure: OOPS during ibmveth moduleinit
From: Jiri Pirko @ 2009-05-12 8:16 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, linux-next, David Miller, netdev
In-Reply-To: <20090512174451.eeed4126.sfr@canb.auug.org.au>
Tue, May 12, 2009 at 09:44:51AM CEST, sfr@canb.auug.org.au wrote:
>Hi Dave,
>
>This fixes it (I wonder if this bug is lurking in any other drivers):
Grepping the sources I see some other places suffering this problem. I'll send
patch for this.
>
>From: Stephen Rothwell <sfr@canb.auug.org.au>
>Date: Tue, 12 May 2009 17:24:02 +1000
>Subject: [PATCH] net/ibmveth: fix panic in probe
>
>netdev->dev_addr changed from being an array to being a pointer, so we
>should not take its address for memcpy().
Nice!
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>
>Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
>---
> drivers/net/ibmveth.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
>diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
>index 7902e5e..8daffad 100644
>--- a/drivers/net/ibmveth.c
>+++ b/drivers/net/ibmveth.c
>@@ -1285,7 +1285,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
> netdev->features |= NETIF_F_LLTX;
> spin_lock_init(&adapter->stats_lock);
>
>- memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
>+ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
>
> for(i = 0; i<IbmVethNumBufferPools; i++) {
> struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
>--
>1.6.3
>
>
>--
>Cheers,
>Stephen Rothwell sfr@canb.auug.org.au
>http://www.canb.auug.org.au/~sfr/
^ permalink raw reply
* Re: question about softirqs
From: Ingo Molnar @ 2009-05-12 8:12 UTC (permalink / raw)
To: Chris Friesen, Peter Zijlstra, Thomas Gleixner, Steven Rostedt
Cc: linuxppc-dev, paulus, David Miller, netdev
In-Reply-To: <4A08C62F.1050105@nortel.com>
* Chris Friesen <cfriesen@nortel.com> wrote:
> This started out as a thread on the ppc list, but on the
> suggestion of DaveM and Paul Mackerras I'm expanding the receiver
> list a bit.
>
> Currently, if a softirq is raised in process context the
> TIF_RESCHED_PENDING flag gets set and on return to userspace we
> run the scheduler, expecting it to switch to ksoftirqd to handle
> the softirqd processing.
>
> I think I see a possible problem with this. Suppose I have a
> SCHED_FIFO task spinning on recvmsg() with MSG_DONTWAIT set. Under
> the scenario above, schedule() would re-run the spinning task
> rather than ksoftirqd, thus preventing any incoming packets from
> being sent up the stack until we get a real hardware
> interrupt--which could be a whole jiffy if interrupt mitigation is
> enabled in the net device.
TIF_RESCHED_PENDING will not be set if a SCHED_FIFO task wakes up a
SCHED_OTHER ksoftirqd task. But starvation of ksoftirqd processing
will occur.
> DaveM pointed out that if we're doing transmits we're likely to
> hit local_bh_enable(), which would process the softirq work.
> However, I think we may still have a problem in the above rx-only
> scenario--or is it too contrived to matter?
This could occur, and the problem is really that task priorities do
not extend across softirq work processing.
This could occur in ordinary SCHED_OTHER tasks as well, if the
softirq is bounced to ksoftirqd - which it only should be if there's
serious softirq overload - or, as you describe it above, if the
softirq is raised in process context:
if (!in_interrupt())
wakeup_softirqd();
that's not really clean. We look into eliminating process context
use of raise_softirq_irqsoff(). Such code sequence:
local_irq_save(flags);
...
raise_softirq_irqsoff(nr);
...
local_irq_restore(flags);
should be converted to something like:
local_irq_save(flags);
...
raise_softirq_irqsoff(nr);
...
local_irq_restore(flags);
recheck_softirqs();
If someone does not do proper local_bh_disable()/enable() sequences
for micro-optimization reasons, then push the check to after the
critcal section - and dont cause extra reschedules by waking up
ksoftirqd. raise_softirq_irqsoff() will also be faster.
Ingo
^ permalink raw reply
* Re: [PowerPC] Next May 8 boot failure: OOPS during ibmveth moduleinit
From: Stephen Rothwell @ 2009-05-12 7:44 UTC (permalink / raw)
To: David Miller; +Cc: linuxppc-dev, linux-next, netdev, Jiri Pirko
In-Reply-To: <20090512170458.39c4ffb7.sfr@canb.auug.org.au>
Hi Dave,
This fixes it (I wonder if this bug is lurking in any other drivers):
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue, 12 May 2009 17:24:02 +1000
Subject: [PATCH] net/ibmveth: fix panic in probe
netdev->dev_addr changed from being an array to being a pointer, so we
should not take its address for memcpy().
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
drivers/net/ibmveth.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 7902e5e..8daffad 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1285,7 +1285,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
netdev->features |= NETIF_F_LLTX;
spin_lock_init(&adapter->stats_lock);
- memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
for(i = 0; i<IbmVethNumBufferPools; i++) {
struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
--
1.6.3
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* Re: device trees.
From: Wolfram Sang @ 2009-05-12 7:38 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, David H. Lynch Jr.
In-Reply-To: <fa686aa40905111704g29d18835w249c89b97d22fc0d@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 717 bytes --]
On Mon, May 11, 2009 at 06:04:16PM -0600, Grant Likely wrote:
> > David: If you would like to have a discussion regarding particular
> > design tradeoffs, I'd be happy to, but since I doubt there is anyone on
> > this list who is interested in the vagaries of FPGA configuration
> > methods, I suggest we have the discussion privately.
>
> I disagree. There are lots of lurkers on this list who care about
> virtex stuff, not to mention non-lurkers like me. :-) I would at
> least like to be a fly on the wall of any such discussion.
+1 :)
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [alsa-devel] [PATCH] aoa: remove driver_data direct access of struct device
From: Takashi Iwai @ 2009-05-12 7:23 UTC (permalink / raw)
To: Greg KH; +Cc: linuxppc-dev, johannes, Roel Kluin, alsa-devel, lkml
In-Reply-To: <20090512065743.GA25267@suse.de>
At Mon, 11 May 2009 23:57:43 -0700,
Greg KH wrote:
>
> On Tue, May 12, 2009 at 08:40:05AM +0200, Takashi Iwai wrote:
> > At Mon, 11 May 2009 21:54:51 +0200,
> > Roel Kluin wrote:
> > >
> > > To avoid direct access to the driver_data pointer in struct device, the
> > > functions dev_get_drvdata() and dev_set_drvdata() should be used.
> > >
> > > Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
> >
> > The same fix has been already in Greg's tree (and thus in linux-next).
> >
> > Greg, is it OK that I take over your patch to sound git tree?
>
> Yes, please do, no objection from me at all.
OK, will do.
BTW, should it be pushed to 2.6.30? If "the near future" you
mentioned in the patch means 2.6.31, it'll be better to merge that fix
now. Otherwise, I'm going to apply the patch as a 2.6.31 material.
thanks,
Takashi
^ permalink raw reply
* Xilinx FIFO TEMAC !?
From: David H. Lynch Jr. @ 2009-05-12 7:20 UTC (permalink / raw)
To: linuxppc-dev
I am working on changes to xilinx_lltemac.c that support both
the SDMA and FIFO TEMAC's.
I was wondering if anyone else had done anything already ?
I have it pretty much working with a few issues:
every so often the read FIFO gets out of sync and I have to
reset it dropping atleast one packet.
Somehow something is screwed up that is breaking the
Busybox Web server. This is really weird because nothing else seems to
be broken.
I have no clue how a driver that has no idea what is in the
packets passing through it can selectively screw up HTTP packets, but I
have proven to myself that the problem is in the driver - despite the my
beleif that is impossible.
Anyway is there any interest in an LL FIFO TEMAC driver ?
Or adding the FIFO code to the SDMA TEMAC code ? It only adds a
couple of dozen lines to the driver.
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 dhlii@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.
"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein
^ permalink raw reply
* [PATCH] Trivial spelling fix in ppc code comments
From: Sankar P @ 2009-05-12 7:11 UTC (permalink / raw)
To: linux-kernel@vger.kernel.org, trivial@kernel.org, linuxppc-dev
Fixes a trivial spelling error in powerpc code comments.
Signed-off-by: Sankar P <sankar.curiosity@gmail.com>
---
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 89497fb..3b52c80 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -2,7 +2,7 @@
* PowerPC64 SLB support.
*
* Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
- * Based on earlier code writteh by:
+ * Based on earlier code written by:
* Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
* Copyright (c) 2001 Dave Engebretsen
* Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
^ permalink raw reply related
* Re: [PowerPC] Next May 8 boot failure: OOPS during ibmveth moduleinit
From: Stephen Rothwell @ 2009-05-12 7:04 UTC (permalink / raw)
To: Sachin Sant; +Cc: linuxppc-dev, netdev, linux-next, David Miller, Jiri Pirko
In-Reply-To: <4A085B3D.5000806@in.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1381 bytes --]
Hi all,
On Mon, 11 May 2009 22:37:09 +0530 Sachin Sant <sachinp@in.ibm.com> wrote:
>
> Jiri Pirko wrote:
> > Fri, May 08, 2009 at 09:57:22PM CEST, davem@davemloft.net wrote:
> >
> >> From: Sachin Sant <sachinp@in.ibm.com>
> >> Date: Fri, 08 May 2009 18:22:48 +0530
> >>
> >>
> >>> Todays Next failed to boot on a Power6 JS22 blade with following oops.
> >>>
> >> Jiri, I suspect this might be your address list changes.
> >>
> >> Although that's just a guess. But please take a look.
> >>
> >
> > Hmm, only thing I see might cause the problem would be if calling __hw_addr_add
> > in dev_addr_init fails, then dev->dev_addr would contain zeroes (which looks
> > this is not the case). But in this case the oops would appear earlier (in
> > ibmveth_probe dev_addr memcpy).
> >
> > Will do the patch which checks the result to behave correctly in case of oom
> > but this imho this wouldn't help. Strange, I will dig into this more tomorrow.
Bisected down to:
commit f001fde5eadd915f4858d22ed70d7040f48767cf
Author: Jiri Pirko <jpirko@redhat.com>
Date: Tue May 5 02:48:28 2009 +0000
net: introduce a list of device addresses dev_addr_list (v6)
I can reproduce this at will on the last three linux-next trees.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [alsa-devel] [PATCH] aoa: remove driver_data direct access of struct device
From: Greg KH @ 2009-05-12 6:57 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, johannes, Roel Kluin, alsa-devel, lkml
In-Reply-To: <s5hws8mu8my.wl%tiwai@suse.de>
On Tue, May 12, 2009 at 08:40:05AM +0200, Takashi Iwai wrote:
> At Mon, 11 May 2009 21:54:51 +0200,
> Roel Kluin wrote:
> >
> > To avoid direct access to the driver_data pointer in struct device, the
> > functions dev_get_drvdata() and dev_set_drvdata() should be used.
> >
> > Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
>
> The same fix has been already in Greg's tree (and thus in linux-next).
>
> Greg, is it OK that I take over your patch to sound git tree?
Yes, please do, no objection from me at all.
thanks,
greg k-h
^ permalink raw reply
* Re: Next May 11 : BUG during scsi initialization
From: Nick Piggin @ 2009-05-12 6:56 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-scsi, Matthew Wilcox, linuxppc-dev, Pekka Enberg,
linux-next
In-Reply-To: <20090512165245.78b6bf83.sfr@canb.auug.org.au>
On Tue, May 12, 2009 at 04:52:45PM +1000, Stephen Rothwell wrote:
> Hi Nick,
>
> On Tue, 12 May 2009 16:03:52 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> >
> > This is what I have been getting for the last few days:
>
> bisected into the net changes, I will follow up there, sorry.
No problem. Phew, yours was looking like a nasty one if it was indeed
an SLQB bug ;)
Thanks,
Nick
^ permalink raw reply
* Re: Next May 11 : BUG during scsi initialization
From: Stephen Rothwell @ 2009-05-12 6:52 UTC (permalink / raw)
To: Nick Piggin
Cc: linux-scsi, Matthew Wilcox, linuxppc-dev, Pekka Enberg,
linux-next
In-Reply-To: <20090512160352.4a97d2f4.sfr@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 331 bytes --]
Hi Nick,
On Tue, 12 May 2009 16:03:52 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> This is what I have been getting for the last few days:
bisected into the net changes, I will follow up there, sorry.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [alsa-devel] [PATCH] aoa: remove driver_data direct access of struct device
From: Takashi Iwai @ 2009-05-12 6:40 UTC (permalink / raw)
To: Roel Kluin; +Cc: linuxppc-dev, johannes, Greg Kroah-Hartman, alsa-devel, lkml
In-Reply-To: <4A08828B.7090106@gmail.com>
At Mon, 11 May 2009 21:54:51 +0200,
Roel Kluin wrote:
>
> To avoid direct access to the driver_data pointer in struct device, the
> functions dev_get_drvdata() and dev_set_drvdata() should be used.
>
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
The same fix has been already in Greg's tree (and thus in linux-next).
Greg, is it OK that I take over your patch to sound git tree?
thanks,
Takashi
> ---
> diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
> index fbf5c93..586965f 100644
> --- a/sound/aoa/fabrics/layout.c
> +++ b/sound/aoa/fabrics/layout.c
> @@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
> }
> ldev->selfptr_headphone.ptr = ldev;
> ldev->selfptr_lineout.ptr = ldev;
> - sdev->ofdev.dev.driver_data = ldev;
> + dev_set_drvdata(&sdev->ofdev.dev, ldev);
> list_add(&ldev->list, &layouts_list);
> layouts_list_items++;
>
> @@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
>
> static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
> {
> - struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
> + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
> int i;
>
> for (i=0; i<MAX_CODECS_PER_BUS; i++) {
> @@ -1114,7 +1114,7 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
> #ifdef CONFIG_PM
> static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
> {
> - struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
> + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
>
> if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
> ldev->gpio.methods->all_amps_off(&ldev->gpio);
> @@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta
>
> static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
> {
> - struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
> + struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
>
> if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
> ldev->gpio.methods->all_amps_restore(&ldev->gpio);
> diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
> index 418c84c..4e3b819 100644
> --- a/sound/aoa/soundbus/i2sbus/core.c
> +++ b/sound/aoa/soundbus/i2sbus/core.c
> @@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
> return -ENODEV;
> }
>
> - dev->ofdev.dev.driver_data = control;
> + dev_set_drvdata(&dev->ofdev.dev, control);
>
> return 0;
> }
>
> static int i2sbus_remove(struct macio_dev* dev)
> {
> - struct i2sbus_control *control = dev->ofdev.dev.driver_data;
> + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
> struct i2sbus_dev *i2sdev, *tmp;
>
> list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
> @@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev)
> #ifdef CONFIG_PM
> static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
> {
> - struct i2sbus_control *control = dev->ofdev.dev.driver_data;
> + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
> struct codec_info_item *cii;
> struct i2sbus_dev* i2sdev;
> int err, ret = 0;
> @@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
>
> static int i2sbus_resume(struct macio_dev* dev)
> {
> - struct i2sbus_control *control = dev->ofdev.dev.driver_data;
> + struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
> struct codec_info_item *cii;
> struct i2sbus_dev* i2sdev;
> int err, ret = 0;
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
^ permalink raw reply
* Re: Next May 11 : BUG during scsi initialization
From: Stephen Rothwell @ 2009-05-12 6:03 UTC (permalink / raw)
To: Nick Piggin
Cc: linux-scsi, Matthew Wilcox, linuxppc-dev, Pekka Enberg,
linux-next
In-Reply-To: <20090512055918.GF32535@wotan.suse.de>
[-- Attachment #1: Type: text/plain, Size: 3246 bytes --]
On Tue, 12 May 2009 07:59:18 +0200 Nick Piggin <npiggin@suse.de> wrote:
>
> On Tue, May 12, 2009 at 03:56:13PM +1000, Stephen Rothwell wrote:
> > Hi Nick,
> >
> > On Tue, 12 May 2009 06:57:16 +0200 Nick Piggin <npiggin@suse.de> wrote:
> > >
> > > Hmm, I think (hope) your problems were fixed with the recent memory
> > > coruption bug fix for SLQB. (if not, let me know)
> > >
> > > This one possibly looks like a problem with remote memory allocation
> > > or memory hotplug or something like that. I'll do a bit of code
> > > review....
> >
> > These are -next kernels which include the two fixes you posted recently
> > (I am pretty sure).
>
> Yes they should do.
>
>
> > I am also getting the network failures that Sachin
> > is seeing on several of my machines here. The previously reported
> > problems have gone away.
>
> This one is a SCSI failure... was there also a network one reported?
> At any rate, I'm fairly sure this is a problem with SLQB, so it could
> easily happen in any early driver setup.
This is what I have been getting for the last few days:
calling .ibmveth_module_init+0x0/0x80 @ 1
Unable to handle kernel paging request for data at address 0x22640004002d310
Faulting instruction address: 0xc000000000038840
cpu 0x0: Vector: 300 (Data Access) at [c0000000be67ef50]
pc: c000000000038840: .memcpy+0x240/0x280
lr: c0000000002a7860: .__nla_put+0x30/0x50
sp: c0000000be67f1d0
msr: 8000000000009032
dar: 22640004002d310
dsisr: 40000000
current = 0xc0000000be67a000
paca = 0xc000000000913280
pid = 1, comm = swapper
enter ? for help
[link register ] c0000000002a7860 .__nla_put+0x30/0x50
[c0000000be67f1d0] c0000000002a7850 .__nla_put+0x20/0x50 (unreliable)
[c0000000be67f260] c0000000002a7bb8 .nla_put+0x48/0x60
[c0000000be67f2e0] c0000000004a50b0 .rtnl_fill_ifinfo+0x320/0x740
[c0000000be67f3e0] c0000000004a586c .rtmsg_ifinfo+0x7c/0x110
[c0000000be67f480] c0000000004a59f0 .rtnetlink_event+0xf0/0x110
[c0000000be67f500] c00000000008a848 .notifier_call_chain+0x78/0x100
[c0000000be67f5a0] c0000000004964b8 .call_netdevice_notifiers+0x28/0x40
[c0000000be67f620] c000000000497a40 .register_netdevice+0x340/0x400
[c0000000be67f700] c000000000497b58 .register_netdev+0x58/0x80
[c0000000be67f790] c000000000574b4c .ibmveth_probe+0x2ec/0x400
[c0000000be67f8a0] c0000000000248b0 .vio_bus_probe+0xa0/0xb0
[c0000000be67f930] c000000000328b30 .driver_probe_device+0xf0/0x210
[c0000000be67f9d0] c000000000328d28 .__driver_attach+0xd8/0xe0
[c0000000be67fa60] c000000000327c78 .bus_for_each_dev+0x98/0xf0
[c0000000be67fb10] c000000000328898 .driver_attach+0x28/0x40
[c0000000be67fb90] c00000000032849c .bus_add_driver+0xdc/0x2d0
[c0000000be67fc30] c000000000329314 .driver_register+0x84/0x1d0
[c0000000be67fcd0] c0000000000247f0 .vio_register_driver+0x40/0x60
[c0000000be67fd60] c00000000077c5ac .ibmveth_module_init+0x5c/0x80
[c0000000be67fde0] c00000000000901c .do_one_initcall+0x6c/0x1e0
[c0000000be67fee0] c00000000074ed1c .kernel_init+0x1fc/0x280
[c0000000be67ff90] c00000000002a4c0 .kernel_thread+0x54/0x70
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: Next May 11 : BUG during scsi initialization
From: Nick Piggin @ 2009-05-12 5:59 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-scsi, Matthew Wilcox, linuxppc-dev, Pekka Enberg,
linux-next
In-Reply-To: <20090512155613.881fa2ec.sfr@canb.auug.org.au>
On Tue, May 12, 2009 at 03:56:13PM +1000, Stephen Rothwell wrote:
> Hi Nick,
>
> On Tue, 12 May 2009 06:57:16 +0200 Nick Piggin <npiggin@suse.de> wrote:
> >
> > Hmm, I think (hope) your problems were fixed with the recent memory
> > coruption bug fix for SLQB. (if not, let me know)
> >
> > This one possibly looks like a problem with remote memory allocation
> > or memory hotplug or something like that. I'll do a bit of code
> > review....
>
> These are -next kernels which include the two fixes you posted recently
> (I am pretty sure).
Yes they should do.
> I am also getting the network failures that Sachin
> is seeing on several of my machines here. The previously reported
> problems have gone away.
This one is a SCSI failure... was there also a network one reported?
At any rate, I'm fairly sure this is a problem with SLQB, so it could
easily happen in any early driver setup.
^ permalink raw reply
* Re: Next May 11 : BUG during scsi initialization
From: Stephen Rothwell @ 2009-05-12 5:56 UTC (permalink / raw)
To: Nick Piggin
Cc: linux-scsi, Matthew Wilcox, linuxppc-dev, Pekka Enberg,
linux-next
In-Reply-To: <20090512045716.GC32535@wotan.suse.de>
[-- Attachment #1: Type: text/plain, Size: 720 bytes --]
Hi Nick,
On Tue, 12 May 2009 06:57:16 +0200 Nick Piggin <npiggin@suse.de> wrote:
>
> Hmm, I think (hope) your problems were fixed with the recent memory
> coruption bug fix for SLQB. (if not, let me know)
>
> This one possibly looks like a problem with remote memory allocation
> or memory hotplug or something like that. I'll do a bit of code
> review....
These are -next kernels which include the two fixes you posted recently
(I am pretty sure). I am also getting the network failures that Sachin
is seeing on several of my machines here. The previously reported
problems have gone away.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox