* Re: signals handling in the kernel
From: David Hawkins @ 2007-08-08 17:19 UTC (permalink / raw)
To: Mirek23; +Cc: linuxppc-embedded
In-Reply-To: <12048448.post@talk.nabble.com>
Hi Mirek,
> I run embedded Linux on ppc405 (ml403 xilinx evaluation board).
> I use the GPIO based device build on FPGA part of the xilinx
> chip. My gpio device generates interrupts whenever it changes
> its state.
>
> I use Montavista gpio driver with some modifications to react
> on interrupts. Each time when interrupt occurs the interrupt
> handler routine is called. This routine sends the signal to the
> application in user space to trigger it. When the application
> is triggered it reads the data from the GPIO device.
>
> I read that in this situation the best is to use signals. In my
> case the ideal would be to use kill_proc_info which sends to the
> application the Signal with info data were I intended to put just
> one integer value. Such a value determines how to react for the
> signal on the application level.
Signals are not the appropriate solution.
It sounds like your application is read-only, so how about
the following use-cases for the driver:
1. In user-space, you only have one GPIO, and the code
only needs to react in response to this one I/O port.
The information required by user-space is the 1-byte
(or 2, or 4) of GPIO
Solution:
The driver implements a buffer that a user-space read() call
consumes. A user-space read() call blocks until there is
data in the buffer.
The driver ISR reads the GPIO port, and writes the
contents to the buffer.
2. In user-space, you have multiple GPIO ports, and
the code needs to respond to any one.
Solution:
The driver implements the poll() call back so that
user-space can call select() on the multiple GPIO
file descriptors.
Again, the driver ISR reads the different GPIO ports,
and writes the data to the GPIO specific buffer.
I have plenty of driver code lying around, and can point
you to an example that implements both of these options.
The driver easily supports both (1) and (2) since
(1) is just a blocking-read, and (2) is poll().
Is the kernel 2.4 or 2.6? Here's some code I wrote for
2.6, and this code was ported from some 2.4 drivers
(and I still have that code in CVS)
http://www.ovro.caltech.edu/~dwh/correlator/cobra_docs.html
http://www.ovro.caltech.edu/~dwh/correlator/software/driver_design.tar.gz
http://www.ovro.caltech.edu/~dwh/correlator/pdf/LNX-762-Hawkins.pdf
I can re-write say the parallel port example to demonstrate
how the value of the GPIO port (the parallel port) can be
sent to user space. There's a parallel port interrupt
example in there somewhere. I know I wrote a GPIO driver
for my Yosemite board (440EP example), but I don't see it
in that zip ... it must be lying around here somewhere :)
I wouldn't necessarily copy say a parallel port example
verbatim, since there is only ever one of those devices
in a system. There are more likely to be multiple GPIO ports,
so the driver design would be generalized a little more.
Look at the COBRA driver code. I have crates of cPCI equipment
loaded with 10s of boards, with each board having multiple
device nodes, transferring megabytes per second over
multiple cPCI crates :)
Anyway, stop thinking about signals, they'll just mess you up.
Oh, the driver will also support sending SIGIO to the process,
via the fasync() driver call, so you can try signals, and
convince yourself that select() is much nicer.
A GPIO driver seems like such an obvious thing to write. Are
you sure the montavista driver doesn't already support these
features? I have no idea of your experience with coding, so
it could just be that you are unaware of what the driver
implements. If you are allowed to post it, go ahead, and
I'll comment on its features.
Cheers
Dave
^ permalink raw reply
* [patch 1/3 v2] PS3: Fix storage probe logic
From: Geoff Levand @ 2007-08-08 18:01 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20070808033119.960825832@am.sony.com>
Subject: PS3: Fix storage probe logic
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Fix the PS3 storage probe logic to properly find device regions on cold
startup.
o Change the storage probe event mask from notify_device_ready
to notify_region_update.
o Improve the storage probe error handling.
o Change ps3_storage_wait_for_device() to use a temporary variable to hold
the buffer address.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
V2 changes:
o Correct the value the returned notify_event->event_type is compared to.
arch/powerpc/platforms/ps3/device-init.c | 37 +++++++++++++++----------------
1 file changed, 19 insertions(+), 18 deletions(-)
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -273,55 +273,58 @@ static int ps3stor_wait_for_completion(u
static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
{
+ int error = -ENODEV;
int result;
const u64 notification_dev_id = (u64)-1LL;
const unsigned int timeout = HZ;
u64 lpar;
u64 tag;
+ void *buf;
+ enum ps3_notify_type {
+ notify_device_ready = 0,
+ notify_region_probe = 1,
+ notify_region_update = 2,
+ };
struct {
u64 operation_code; /* must be zero */
- u64 event_mask; /* 1 = device ready */
+ u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
} *notify_cmd;
struct {
- u64 event_type; /* notify_device_ready */
+ u64 event_type; /* enum ps3_notify_type */
u64 bus_id;
u64 dev_id;
u64 dev_type;
u64 dev_port;
} *notify_event;
- enum {
- notify_device_ready = 1
- };
pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
__LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
- notify_cmd = kzalloc(512, GFP_KERNEL);
- notify_event = (void *)notify_cmd;
- if (!notify_cmd)
+ buf = kzalloc(512, GFP_KERNEL);
+ if (!buf)
return -ENOMEM;
- lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd));
+ lpar = ps3_mm_phys_to_lpar(__pa(buf));
+ notify_cmd = buf;
+ notify_event = buf;
result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
if (result) {
printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
__LINE__, ps3_result(result));
- result = -ENODEV;
goto fail_free;
}
/* Setup and write the request for device notification. */
- notify_cmd->operation_code = 0; /* must be zero */
- notify_cmd->event_mask = 0x01; /* device ready */
+ notify_cmd->operation_code = 0; /* must be zero */
+ notify_cmd->event_mask = 1UL << notify_region_probe;
result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
&tag);
if (result) {
printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
ps3_result(result));
- result = -ENODEV;
goto fail_close;
}
@@ -332,13 +335,11 @@ static int ps3_storage_wait_for_device(c
if (result) {
printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
__LINE__, ps3_result(result));
- result = -ENODEV;
goto fail_close;
}
/* Loop here processing the requested notification events. */
- result = -ENODEV;
while (1) {
memset(notify_event, 0, sizeof(*notify_event));
@@ -358,7 +359,7 @@ static int ps3_storage_wait_for_device(c
break;
}
- if (notify_event->event_type != notify_device_ready ||
+ if (notify_event->event_type != notify_region_probe ||
notify_event->bus_id != repo->bus_id) {
pr_debug("%s:%u: bad notify_event: event %lu, "
"dev_id %lu, dev_type %lu\n",
@@ -386,9 +387,9 @@ static int ps3_storage_wait_for_device(c
fail_close:
lv1_close_device(repo->bus_id, notification_dev_id);
fail_free:
- kfree(notify_cmd);
+ kfree(buf);
pr_debug(" <- %s:%u\n", __func__, __LINE__);
- return result;
+ return error;
}
static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
^ permalink raw reply
* [PATCH 0/7] IB/ehca: support for user space small queues, support more than 4k queue pairs, generate last WQE reached
From: Stefan Roscher @ 2007-08-08 18:36 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, general
Cc: craisch, Hoang-Nam Nguyen, fenkes
Here is a patch set against Roland's git, branch for-2.6.23 for ehca.
It enables userspace support for small QP feature and make some fixes for it.
Also there is add the mapping of 4k firmware context to user space.
They are in details:
[1/7] add support for userspace small queues and make some fixes
[2/7] ensure that a non-existing queues in case of SRQs are not interprete as
small queues
[3/7] we have no longer to add 1 to the number of requestet wqes, because
firmware does now
[4/7] make changes to ehca_mmap() to support more than 4k queues
[5/7] map 4k firmware context of cq, qp to user space
[6/7] generate last WQE reached, when base QP for SRQ has entered error state
[7/7] prevent overwriting QP init attributes given by caller
The patches should apply cleanly, in order, against Roland's git. Please
review the changes and apply the patches if they are okay.
Regards,
Stefan
^ permalink raw reply
* [PATCH 1/7] IB/ehca: Small QP userspace support and fixes
From: Stefan Roscher @ 2007-08-08 18:37 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, Hoang-Nam Nguyen, raisch
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_qp.c | 7 +++----
drivers/infiniband/hw/ehca/ipz_pt_fn.c | 3 ++-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index b178cba..cfa83fa 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -273,6 +273,7 @@ static inline void queue2resp(struct ipzu_queue_resp *resp,
resp->queue_length = queue->queue_length;
resp->pagesize = queue->pagesize;
resp->toggle_state = queue->toggle_state;
+ resp->offset = queue->offset;
}
/*
@@ -598,8 +599,7 @@ static struct ehca_qp *internal_create_qp(
parms.squeue.max_sge = max_send_sge;
parms.rqueue.max_sge = max_recv_sge;
- if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)
- && !(context && udata)) { /* no small QP support in userspace ATM */
+ if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)) {
ehca_determine_small_queue(
&parms.squeue, max_send_sge, is_llqp);
ehca_determine_small_queue(
@@ -739,8 +739,7 @@ static struct ehca_qp *internal_create_qp(
resp.ext_type = my_qp->ext_type;
resp.qkey = my_qp->qkey;
resp.real_qp_num = my_qp->real_qp_num;
- resp.ipz_rqueue.offset = my_qp->ipz_rqueue.offset;
- resp.ipz_squeue.offset = my_qp->ipz_squeue.offset;
+
if (HAS_SQ(my_qp))
queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue);
if (HAS_RQ(my_qp))
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index a090c67..661f8db 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -158,6 +158,7 @@ static int alloc_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd)
queue->queue_pages[0] = (void *)(page->page | (bit << (order + 9)));
queue->small_page = page;
+ queue->offset = bit << (order + 9);
return 1;
out:
@@ -172,7 +173,7 @@ static void free_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd)
unsigned long bit;
int free_page = 0;
- bit = ((unsigned long)queue->queue_pages[0] & PAGE_MASK)
+ bit = ((unsigned long)queue->queue_pages[0] & ~PAGE_MASK)
>> (order + 9);
mutex_lock(&pd->lock);
--
1.5.2
^ permalink raw reply related
* [PATCH 2/7] IB/ehca: Ensure non-existing queues aren't made small queues
From: Stefan Roscher @ 2007-08-08 18:39 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, raisch, "Hoang-Nam Nguyen" @dyn-9-152-249-53
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_qp.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index cfa83fa..13b61c3 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -600,10 +600,12 @@ static struct ehca_qp *internal_create_qp(
parms.rqueue.max_sge = max_recv_sge;
if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)) {
- ehca_determine_small_queue(
- &parms.squeue, max_send_sge, is_llqp);
- ehca_determine_small_queue(
- &parms.rqueue, max_recv_sge, is_llqp);
+ if (HAS_SQ(my_qp))
+ ehca_determine_small_queue(
+ &parms.squeue, max_send_sge, is_llqp);
+ if (HAS_RQ(my_qp))
+ ehca_determine_small_queue(
+ &parms.rqueue, max_recv_sge, is_llqp);
parms.qp_storage =
(parms.squeue.is_small || parms.rqueue.is_small);
}
--
1.5.2
^ permalink raw reply related
* [PATCH 3/7] IB/ehca: Add 1 is not longer needed because of firmware interface change
From: Stefan Roscher @ 2007-08-08 18:40 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, raisch, "Hoang-Nam Nguyen" @dyn-9-152-249-53
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/hcp_if.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 24f4541..8534061 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -317,9 +317,9 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
max_r10_reg =
EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
- parms->squeue.max_wr + 1)
+ parms->squeue.max_wr)
| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
- parms->rqueue.max_wr + 1)
+ parms->rqueue.max_wr)
| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
parms->squeue.max_sge)
| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
--
1.5.2
^ permalink raw reply related
* [PATCH 4/7] IB/ehca: Support more than 4k QPs for userspace and kernelspace
From: Stefan Roscher @ 2007-08-08 18:41 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general,
"Hoang-Nam Nguyen" @dyn-9-152-249-53, fenkes
Cc: raisch
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_cq.c | 7 ++++++-
drivers/infiniband/hw/ehca/ehca_qp.c | 6 ++++++
drivers/infiniband/hw/ehca/ehca_uverbs.c | 22 +++++++++++-----------
3 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 81aff36..c661939 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -168,7 +168,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
} while (ret == -EAGAIN);
-
+ if (my_cq->token > 0x1FFFFFF) {
+ cq = ERR_PTR(-ENOMEM);
+ ehca_err(device, "Invalid number of qp. device=%p",
+ device);
+ goto create_cq_exit2;
+ }
if (ret) {
cq = ERR_PTR(-ENOMEM);
ehca_err(device, "Can't allocate new idr entry. device=%p",
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 13b61c3..f26801b 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -560,6 +560,12 @@ static struct ehca_qp *internal_create_qp(
} while (ret == -EAGAIN);
+ if (my_qp->token > 0x1FFFFFF) {
+ ret = -EINVAL;
+ ehca_err(pd->device, "Invalid number of qp");
+ goto create_qp_exit1;
+ }
+
if (ret) {
ret = -ENOMEM;
ehca_err(pd->device, "Can't allocate new idr entry.");
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 4bc687f..3340f49 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -164,7 +164,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq,
int ret;
switch (rsrc_type) {
- case 1: /* galpa fw handle */
+ case 0: /* galpa fw handle */
ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number);
ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa);
if (unlikely(ret)) {
@@ -175,7 +175,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq,
}
break;
- case 2: /* cq queue_addr */
+ case 1: /* cq queue_addr */
ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number);
ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue);
if (unlikely(ret)) {
@@ -201,7 +201,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
int ret;
switch (rsrc_type) {
- case 1: /* galpa fw handle */
+ case 0: /* galpa fw handle */
ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num);
ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa);
if (unlikely(ret)) {
@@ -212,7 +212,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
}
break;
- case 2: /* qp rqueue_addr */
+ case 1: /* qp rqueue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue",
qp->ib_qp.qp_num);
ret = ehca_mmap_queue(vma, &qp->ipz_rqueue,
@@ -225,7 +225,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
}
break;
- case 3: /* qp squeue_addr */
+ case 2: /* qp squeue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue",
qp->ib_qp.qp_num);
ret = ehca_mmap_queue(vma, &qp->ipz_squeue,
@@ -249,10 +249,10 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
{
- u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT;
- u32 idr_handle = fileoffset >> 32;
- u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */
- u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */
+ u64 fileoffset = vma->vm_pgoff;
+ u32 idr_handle = fileoffset & 0x1FFFFFF;
+ u32 q_type = (fileoffset >> 27) & 0x1; /* CQ, QP,... */
+ u32 rsrc_type = (fileoffset >> 25) & 0x3; /* sq,rq,cmnd_window */
u32 cur_pid = current->tgid;
u32 ret;
struct ehca_cq *cq;
@@ -261,7 +261,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
struct ib_uobject *uobject;
switch (q_type) {
- case 1: /* CQ */
+ case 0: /* CQ */
read_lock(&ehca_cq_idr_lock);
cq = idr_find(&ehca_cq_idr, idr_handle);
read_unlock(&ehca_cq_idr_lock);
@@ -289,7 +289,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
}
break;
- case 2: /* QP */
+ case 1: /* QP */
read_lock(&ehca_qp_idr_lock);
qp = idr_find(&ehca_qp_idr, idr_handle);
read_unlock(&ehca_qp_idr_lock);
--
1.5.2
^ permalink raw reply related
* [PATCH 5/7] IB/ehca: map 4k firmware context of cq, qp to user space
From: Stefan Roscher @ 2007-08-08 18:42 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, "Hoang-Nam Nguyen" @dyn-9-152-249-53, raisch
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Date: Wed, 8 Aug 2007 19:33:23 +0200
This patch utilizes remap_4k_pfn() as introduced by Paul M.,
for details see http://patchwork.ozlabs.org/linuxppc/patch?id=10281,
to map ehca cq, qp firmware context (4k) to user space if kernel page
size is 64k. For reason, why this is required, see also Paul's patch.
In addition to that the kernel page offset of firmware context needs
to be set in cq and qp response block so that user space can assemble
the proper virtual address to use.
An appropriate patch for libehca will follow for ofed-1.3.
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_classes.h | 4 +++-
drivers/infiniband/hw/ehca/ehca_cq.c | 2 ++
drivers/infiniband/hw/ehca/ehca_qp.c | 2 ++
drivers/infiniband/hw/ehca/ehca_uverbs.c | 6 +++---
4 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index b5e9603..206d4eb 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -337,6 +337,8 @@ struct ehca_create_cq_resp {
u32 cq_number;
u32 token;
struct ipzu_queue_resp ipz_queue;
+ u32 fw_handle_ofs;
+ u32 dummy;
};
struct ehca_create_qp_resp {
@@ -347,7 +349,7 @@ struct ehca_create_qp_resp {
u32 qkey;
/* qp_num assigned by ehca: sqp0/1 may have got different numbers */
u32 real_qp_num;
- u32 dummy; /* padding for 8 byte alignment */
+ u32 fw_handle_ofs;
struct ipzu_queue_resp ipz_squeue;
struct ipzu_queue_resp ipz_rqueue;
};
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index c661939..0ac5a97 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -281,6 +281,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
resp.ipz_queue.queue_length = ipz_queue->queue_length;
resp.ipz_queue.pagesize = ipz_queue->pagesize;
resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
+ resp.fw_handle_ofs = (u32)
+ (my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
ehca_err(device, "Copy to udata failed.");
goto create_cq_exit4;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index f26801b..d8c1c22 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -752,6 +752,8 @@ static struct ehca_qp *internal_create_qp(
queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue);
if (HAS_RQ(my_qp))
queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue);
+ resp.fw_handle_ofs = (u32)
+ (my_qp->galpas.user.fw_handle & (PAGE_SIZE - 1));
if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
ehca_err(pd->device, "Copy to udata failed");
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 3340f49..84a16bc 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -109,7 +109,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
u64 vsize, physical;
vsize = vma->vm_end - vma->vm_start;
- if (vsize != EHCA_PAGESIZE) {
+ if (vsize < EHCA_PAGESIZE) {
ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start);
return -EINVAL;
}
@@ -118,8 +118,8 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical);
/* VM_IO | VM_RESERVED are set by remap_pfn_range() */
- ret = remap_pfn_range(vma, vma->vm_start, physical >> PAGE_SHIFT,
- vsize, vma->vm_page_prot);
+ ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT,
+ vma->vm_page_prot);
if (unlikely(ret)) {
ehca_gen_err("remap_pfn_range() failed ret=%x", ret);
return -ENOMEM;
--
1.5.2
^ permalink raw reply related
* Re: [PATCH] i2c-mpc: don't disable I2C module on stop condition.
From: Guennadi Liakhovetski @ 2007-08-08 18:33 UTC (permalink / raw)
To: Jean Delvare; +Cc: linuxppc-embedded, Domen Puncer, i2c
In-Reply-To: <20070808191913.3e6bb0e6@hyperion.delvare>
On Wed, 8 Aug 2007, Jean Delvare wrote:
> Hi Domen,
>
> On Tue, 24 Jul 2007 07:14:31 +0200, Domen Puncer wrote:
> > Disabling module on stop doesn't work on some CPUs (ie. mpc8241,
> > as reported by Guennadi Liakhovetski), so remove that.
> >
> > Disable I2C module on errors/interrupts to prevent it from
> > locking up on mpc5200b.
> >
> >
> > Signed-off-by: Domen Puncer <domen.puncer@telargo.com>
> > ---
> > Hi!
> >
> > So I fixed i2c on one board, and broke it on another :-(
> > This patch works on both Guennadi's and mine (hey, it might break
> > a third one!).
> > Jean, can you please push this, if there are no objections
> > and "doesn't work for me" reports.
>
> Queued for 2.6.23-rc3, thanks. Guennadi, can you please confirm that
> this patch fixes your problem?
Yes, it does. Also tested with i2c bus debugging on and with interrupting
hwclock, thereby messages
I2C: Interrupted
come, but the controller stays functional. Looks good so far:-)
Acked-by: G. Liakhovetski <g.liakhovetski@gmx.de>
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply
* [PATCH 6/7] IB/ehca: Generate last WQE reached, when base QP for SRQ has entered error state
From: Stefan Roscher @ 2007-08-08 18:43 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, "Hoang-Nam Nguyen" @dyn-9-152-249-53, raisch
From: Joachim Fenkes <fenkes@de.ibm.com>
Date: Wed, 8 Aug 2007 19:51:30 +0200
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_irq.c | 48 +++++++++++++++++++++-----------
1 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index ee06d8b..941816a 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -175,41 +175,55 @@ error_data1:
}
-static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
- enum ib_event_type event_type, int fatal)
+static void dispatch_qp_event(struct ehca_shca *shca, struct ehca_qp *qp,
+ enum ib_event_type event_type)
{
struct ib_event event;
- struct ehca_qp *qp;
- u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe);
-
- read_lock(&ehca_qp_idr_lock);
- qp = idr_find(&ehca_qp_idr, token);
- read_unlock(&ehca_qp_idr_lock);
-
-
- if (!qp)
- return;
-
- if (fatal)
- ehca_error_data(shca, qp, qp->ipz_qp_handle.handle);
event.device = &shca->ib_device;
+ event.event = event_type;
if (qp->ext_type == EQPT_SRQ) {
if (!qp->ib_srq.event_handler)
return;
- event.event = fatal ? IB_EVENT_SRQ_ERR : event_type;
event.element.srq = &qp->ib_srq;
qp->ib_srq.event_handler(&event, qp->ib_srq.srq_context);
} else {
if (!qp->ib_qp.event_handler)
return;
- event.event = event_type;
event.element.qp = &qp->ib_qp;
qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context);
}
+}
+
+static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
+ enum ib_event_type event_type, int fatal)
+{
+ struct ehca_qp *qp;
+ u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe);
+
+ read_lock(&ehca_qp_idr_lock);
+ qp = idr_find(&ehca_qp_idr, token);
+ read_unlock(&ehca_qp_idr_lock);
+
+ if (!qp)
+ return;
+
+ if (fatal)
+ ehca_error_data(shca, qp, qp->ipz_qp_handle.handle);
+
+ dispatch_qp_event(shca, qp, fatal && qp->ext_type == EQPT_SRQ ?
+ IB_EVENT_SRQ_ERR : event_type);
+
+ /*
+ * eHCA only processes one WQE at a time for SRQ base QPs,
+ * so the last WQE has been processed as soon as the QP enters
+ * error state.
+ */
+ if (fatal && qp->ext_type == EQPT_SRQBASE)
+ dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED);
return;
}
--
1.5.2
^ permalink raw reply related
* [PATCH 7/7] IB/ehca: Prevent overwriting QP init attributes given by caller
From: Stefan Roscher @ 2007-08-08 18:44 UTC (permalink / raw)
To: Roland Dreier, linux-kernel, linuxppc-dev, openib-general
Cc: fenkes, "Hoang-Nam Nguyen" @dyn-9-152-249-53, raisch
Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_qp.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index d8c1c22..6efda3d 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -709,12 +709,12 @@ static struct ehca_qp *internal_create_qp(
my_qp->ib_qp.event_handler = init_attr->event_handler;
}
- init_attr->cap.max_inline_data = 0; /* not supported yet */
- init_attr->cap.max_recv_sge = parms.rqueue.act_nr_sges;
- init_attr->cap.max_recv_wr = parms.rqueue.act_nr_wqes;
- init_attr->cap.max_send_sge = parms.squeue.act_nr_sges;
- init_attr->cap.max_send_wr = parms.squeue.act_nr_wqes;
my_qp->init_attr = *init_attr;
+ my_qp->init_attr.cap.max_inline_data = 0; /* not supported yet */
+ my_qp->init_attr.cap.max_recv_sge = parms.rqueue.act_nr_sges;
+ my_qp->init_attr.cap.max_recv_wr = parms.rqueue.act_nr_wqes;
+ my_qp->init_attr.cap.max_send_sge = parms.squeue.act_nr_sges;
+ my_qp->init_attr.cap.max_send_wr = parms.squeue.act_nr_wqes;
/* NOTE: define_apq0() not supported yet */
if (qp_type == IB_QPT_GSI) {
@@ -825,10 +825,6 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
if (IS_ERR(my_qp))
return (struct ib_srq *)my_qp;
- /* copy back return values */
- srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr;
- srq_init_attr->attr.max_sge = qp_init_attr.cap.max_recv_sge;
-
/* drive SRQ into RTR state */
mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
if (!mqpcb) {
--
1.5.2
^ permalink raw reply related
* Sequoia 440EPx patches not working
From: Jerone Young @ 2007-08-08 18:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: vbarshark
Using the Sequoia (AMCC 440EPx) patches recently submitted to the list I
am unable to boot to fully boot a uImage built with these patches under
Uboot. It appears to hang in very early boot.
Here is the output:
=> tftp 400000 sequoia/uImage
ENET Speed is 100 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 9.53.41.24; our IP address is 9.53.41.38
Filename 'sequoia/uImage'.
Load address: 0x400000
Loading: #################################################################
#################################################################
#################################################################
#######################
done
Bytes transferred = 1112434 (10f972 hex)
=> bootm 400000
## Booting image at 00400000 ...
Image Name: Linux-2.6.23-rc2
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 1112370 Bytes = 1.1 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
^ permalink raw reply
* [Documentation] Page Table Layout diagrams
From: Adam Litke @ 2007-08-08 18:47 UTC (permalink / raw)
To: linux-mm; +Cc: linuxppc-dev, linux-kernel
Hello all. In an effort to understand how the page tables are laid out
across various architectures I put together some diagrams. I have
posted them on the linux-mm wiki: http://linux-mm.org/PageTableStructure
and I hope they will be useful to others.
Just to make sure I am not spreading misinformation, could a few of you
experts take a quick look at the three diagrams I've got finished so far
and point out any errors I have made? Thanks.
--
Adam Litke - (agl at us.ibm.com)
IBM Linux Technology Center
^ permalink raw reply
* Re: pci in arch/powerpc vs arch/ppc
From: Scott Wood @ 2007-08-08 19:11 UTC (permalink / raw)
To: Alexandros Kostopoulos; +Cc: linuxppc-dev
In-Reply-To: <op.twqvg3i0nhx3hy@phoenix>
Alexandros Kostopoulos wrote:
> I've noticed the following: In function pci_process_bridge_OF_ranges,
> when parsing the ranges for MEM and I/O space, the res->start for mem
> is correctly set to ranges[na+2], which is the cpu address in the
> ranges property. However, in I/O related code, res->start is set to
> ranges[2], which is in the PCI address field of the ranges property
> (and in my case is 0, as is also for the mpc8272ads case as well).
> Thus, the res->start of the I/O of the bridge is 0, which leads to the
> first device with I/O space (a davicom ethernet device) been also
> assigned a I/O region starting at 0. Finally, the dmfe (davicom
> ethernet driver over PCI) fails with "dmfe: I/O base is zero". So, is
> the implementation of pci_process_bridge_OF_ranges correct ? shouldn't
> res->start = ranges[na+2] for I/O as well?
Ideally, yes -- but currently IO-space resources are relative to the
start of the primary bus's IO-space.
As a workaround, try not setting the primary flag when calling
pci_process_bridge_OF_ranges. Note that this means that any legacy I/O
ports that may exist on cards you plug in (such as VGA cards) will not
be found.
The proper solution is probably to refuse pre-existing BARs that are
lower than PCIBIOS_MIN_IO, and/or provide a flag to tell the PCI layer
to completely ignore pre-existing BARs.
-Scott
^ permalink raw reply
* Re: no output to serial console from /init process on ml405
From: Anton Kowalski @ 2007-08-08 19:31 UTC (permalink / raw)
To: Wolfgang Reissnegger; +Cc: linuxppc-embedded
In-Reply-To: <20070808164205.017C3370065@mail150-sin.bigfish.com>
On 8/8/07, Wolfgang Reissnegger <wolfgang.reissnegger@xilinx.com> wrote:
> The thing that points to a problem with init is:
> Kernel panic - not syncing: Attempted to kill init!
>
> What is the string that is supposed to be printed? Maybe the printf
> tries to print a string at an invalid address, causing init to crash?
>
To test that hypothesis, I created a program that loops indefinitely:
for (;;) {
printf("hello\n");
sleep(1);
}
return 0;
This produces the following output:
[ 2.715404] Freeing unused kernel memory: 116k init
[ 2.776225] sys_write 1
[ 3.808186] sys_write 1
[ 4.840192] sys_write 1
[ 5.872181] sys_write 1
[ 6.904193] sys_write 1
[ 7.936181] sys_write 1
....
The string "sys_write 1" is from a printk I inserted into sys_write.
So init doesn't crash, which suggests that I haven't set up the /dev
files correctly.
Thanks again.
Anton
> Also, you can check if you set the option for console on serial output:
> Location:
> -> Device Drivers
> -> Character devices
> -> Serial drivers
> -> 8250/16550 and compatible serial support (SERIAL_8250 [=y])
>
> Cheers,
> Wolfgang
>
> Anton Kowalski wrote:
> > Wolfgang,
> >
> > Thanks, I'll try your suggestion.
> >
> > It's worth noting that the init executable is calling into the
> > kernel.
> >
> > I put a printk in sys_write, which is on the call path of printf()
> > and the output is sent to the console. However, the output of printf
> > is not to be seen. This suggests the problem is perhaps in the serial
> > device setup?
> >
> > Anton
> >
> > On 8/8/07, Wolfgang Reissnegger <wolfgang.reissnegger@xilinx.com>
> > wrote:
> >> Hi Anton,
> >>
> >> it looks as if your init executable is not doing the right thing
> >> and for some reason terminates. Maybe your inittab configuration is
> >> wrong? Maybe the init executable has been compiled with the wrong
> >> options?
> >>
> >> You can try to copy another executable (e.g. sh, getty) into /init
> >> and see if you get any output. If you see anything doing that then
> >> most likely there's something wrong with your init executable.
> >>
> >> Wolfgang
> >>
> >> Anton Kowalski wrote:
> >>> Hi All:
> >>>
> >>> I'm trying to bring up linux 2.6.21.1 on an ml405 board. The
> >>> kernel boots fine but the init process does not produce any
> >>> output. The /init program resides in an initramfs file system and
> >>> I believe the /dev device files have been set up correctly.
> >>> Here's an excerpt from my initramfs specification:
> >>>
> >>> dir /dev 755 0 0 nod /dev/console 644 0 0 c 5 1 nod /dev/ttyS0
> >>> 644 0 0 c 4 64
> >>>
> >>> (I am able to open these files from the init program. I tested
> >>> this by sleeping for a specified time on success.)
> >>>
> >>> Also, printk continues to function after /init terminates and
> >>> before the kernel panics.
> >>>
> >>> Here are the last few lines of the console output:
> >>>
> >>> [ 0.507478] Serial: 8250/16550 driver $Revision: 1.90 $ 4
> >>> ports, IRQ sharing disabled [ 0.513862] serial8250.0: ttyS0 at
> >>> MMIO 0x80201003 (irq = 3) is a 16550A [ 2.927509] RAMDISK
> >>> driver initialized: 1 RAM disks of 8192K size 1024 blocksize [
> >>> 3.018391] tun: Universal TUN/TAP device driver, 1.6 [
> >>> 3.079115] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
> >>> [ 3.154919] mice: PS/2 mouse device common for all mice [
> >>> 3.218021] TCP cubic registered [ 3.257034] NET: Registered
> >>> protocol family 1 [ 3.309405] NET: Registered protocol family
> >>> 17 [ 3.363462] Freeing unused kernel memory: 300k init [
> >>> 23.488277] Kernel panic - not syncing: Attempted to kill init! [
> >>> 23.559517] Rebooting in 180 seconds..<NULL>
> >>>
> >>> I'm using the plb uart and the 8250.c driver. (The obp uartlite
> >>> driver didn't work so I switched.) The kernel and the init
> >>> program were compiled with eldk.
> >>>
> >>> Any insights into resolving this problem are greatly appreciated.
> >>>
> >>>
> >>>
> >>> Anton _______________________________________________
> >>> Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org
> >>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> >>>
> >>
> >
>
>
^ permalink raw reply
* Re: no output to serial console from /init process on ml405
From: Anton Kowalski @ 2007-08-08 19:42 UTC (permalink / raw)
To: Benedict, Michael; +Cc: linuxppc-embedded
In-Reply-To: <CF7E46FCFF66AD478BB72724345289EC2797CE@twx-exch01.twacs.local>
Indeed I hadn't set up the compulsary links correctly. In reading
through the devices.txt document I realized that I don't have /proc
mounted either. So the following links might not make much sense until
/proc is up.
slink /dev/fd /proc/self/fd 777 0 0
slink /dev/stdin /proc/self/fd/0 777 0 0
slink /dev/stdout /proc/self/fd/1 777 0 0
slink /dev/stderr /proc/self/fd/2 777 0 0
Thanks for your help.
Anton
On 8/8/07, Benedict, Michael <MBenedict@twacs.com> wrote:
> Just a guess, but do you have stdout and friends defined as recommended
> in the Compulsory links section of Documentation/devices.txt?
> -Michael
>
> > -----Original Message-----
> > From:
> > linuxppc-embedded-bounces+mbenedict=twacs.com@ozlabs.org
> > [mailto:linuxppc-embedded-bounces+mbenedict=twacs.com@ozlabs.o
> rg] On Behalf Of Anton Kowalski
> > Sent: Wednesday, August 08, 2007 6:28 AM
> > To: linuxppc-embedded@ozlabs.org
> > Subject: no output to serial console from /init process on ml405
> >
> > Hi All:
> >
> > I'm trying to bring up linux 2.6.21.1 on an ml405 board. The kernel
> > boots fine but the init process does not produce any output. The /init
> > program resides in an initramfs file system and I believe the /dev
> > device files have been set up correctly. Here's an excerpt from my
> > initramfs specification:
> >
> > dir /dev 755 0 0
> > nod /dev/console 644 0 0 c 5 1
> > nod /dev/ttyS0 644 0 0 c 4 64
> >
> > (I am able to open these files from the init program. I tested this by
> > sleeping for a specified time on success.)
> >
> > Also, printk continues to function after /init terminates and before
> > the kernel panics.
> >
> > Here are the last few lines of the console output:
> >
> > [ 0.507478] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports,
> > IRQ sharing disabled
> > [ 0.513862] serial8250.0: ttyS0 at MMIO 0x80201003 (irq =
> > 3) is a 16550A
> > [ 2.927509] RAMDISK driver initialized: 1 RAM disks of 8192K size
> > 1024 blocksize
> > [ 3.018391] tun: Universal TUN/TAP device driver, 1.6
> > [ 3.079115] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
> > [ 3.154919] mice: PS/2 mouse device common for all mice
> > [ 3.218021] TCP cubic registered
> > [ 3.257034] NET: Registered protocol family 1
> > [ 3.309405] NET: Registered protocol family 17
> > [ 3.363462] Freeing unused kernel memory: 300k init
> > [ 23.488277] Kernel panic - not syncing: Attempted to kill init!
> > [ 23.559517] Rebooting in 180 seconds..<NULL>
> >
> > I'm using the plb uart and the 8250.c driver. (The obp uartlite driver
> > didn't work so I switched.) The kernel and the init program were
> > compiled with eldk.
> >
> > Any insights into resolving this problem are greatly appreciated.
> >
> >
> > Anton
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> >
> >
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
^ permalink raw reply
* Re: pci in arch/powerpc vs arch/ppc
From: Alexandros Kostopoulos @ 2007-08-08 19:46 UTC (permalink / raw)
To: Scott Wood, Alexandros Kostopoulos; +Cc: linuxppc-dev
In-Reply-To: <46BA1560.7090703@freescale.com>
Scott Wood <scottwood@freescale.com> said:
> Alexandros Kostopoulos wrote:
> > I've noticed the following: In function pci_process_bridge_OF_ranges,
> > when parsing the ranges for MEM and I/O space, the res->start for mem
> > is correctly set to ranges[na+2], which is the cpu address in the
> > ranges property. However, in I/O related code, res->start is set to
> > ranges[2], which is in the PCI address field of the ranges property
> > (and in my case is 0, as is also for the mpc8272ads case as well).
> > Thus, the res->start of the I/O of the bridge is 0, which leads to the
> > first device with I/O space (a davicom ethernet device) been also
> > assigned a I/O region starting at 0. Finally, the dmfe (davicom
> > ethernet driver over PCI) fails with "dmfe: I/O base is zero". So, is
> > the implementation of pci_process_bridge_OF_ranges correct ? shouldn't
> > res->start = ranges[na+2] for I/O as well?
>
> Ideally, yes -- but currently IO-space resources are relative to the
> start of the primary bus's IO-space.
>
> As a workaround, try not setting the primary flag when calling
> pci_process_bridge_OF_ranges. Note that this means that any legacy I/O
> ports that may exist on cards you plug in (such as VGA cards) will not
> be found.
>
> The proper solution is probably to refuse pre-existing BARs that are
> lower than PCIBIOS_MIN_IO, and/or provide a flag to tell the PCI layer
> to completely ignore pre-existing BARs.
I was referring to the allocation of primary bus' IO space based on the
device tree. I understand that IO-space resources are relative to the start
of the primary bus' IO space. But I think the primary bus IO space allocation
itself is broken. Let me explain with an example:
In mpc8272ads.dts, the ranges property for pci is:
ranges = <42000000 0 80000000 80000000 0 20000000
02000000 0 a0000000 a0000000 0 20000000
01000000 0 00000000 f6000000 0 02000000>;
The third obviously corresponds to IO space. So, shouldn't the res->start for
the host bridge be set to f6000000 ? Because, currently, based on what I've
described in my previous mail, it gets set to 0. It seems to me like a matter
of incorrect parsing of the device tree from pci_process_bridge_OF_ranges()
for IO space. Or am I missing something else here, and it should actually be
0?
thanks
Alex
>
> -Scott
>
--
^ permalink raw reply
* Re: pci in arch/powerpc vs arch/ppc
From: Scott Wood @ 2007-08-08 19:56 UTC (permalink / raw)
To: Alexandros Kostopoulos; +Cc: linuxppc-dev
In-Reply-To: <twig.1186602365.9125@inaccessnetworks.com>
Alexandros Kostopoulos wrote:
> I was referring to the allocation of primary bus' IO space based on the
> device tree. I understand that IO-space resources are relative to the start
> of the primary bus' IO space. But I think the primary bus IO space allocation
> itself is broken. Let me explain with an example:
>
> In mpc8272ads.dts, the ranges property for pci is:
>
> ranges = <42000000 0 80000000 80000000 0 20000000
> 02000000 0 a0000000 a0000000 0 20000000
> 01000000 0 00000000 f6000000 0 02000000>;
>
> The third obviously corresponds to IO space. So, shouldn't the res->start for
> the host bridge be set to f6000000 ?
No, because as I said, res->start is relative to the start of IO-space.
The in/out functions add isa_io_base to the address.
> Because, currently, based on what I've
> described in my previous mail, it gets set to 0. It seems to me like a matter
> of incorrect parsing of the device tree from pci_process_bridge_OF_ranges()
> for IO space.
It is not, at least not in this case. It does appear to be ignoring the
possibility that it needs to do further translation of the address
through parent buses, though.
-Scott
^ permalink raw reply
* [PATCH 0/6] pseries: rtas & nvram cleanup/simpilification
From: Linas Vepstas @ 2007-08-08 19:59 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
Paul,
Please apply te following for 2.6.24
The following sequence of patches cleanup, simplify and shorten
the pseries code having to do with error logging. Several
global variables shared across directories are removed, and
the rtasd initialization sequence is rearranged and simplified,
making the flow of control clearer. A minor buglet is fixed,
and error mesages can now be logged earlier in the boot sequence.
--linas
^ permalink raw reply
* [PATCH 1/6] pseries: avoid excess rtas calls
From: Linas Vepstas @ 2007-08-08 20:01 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808195916.GA20055@austin.ibm.com>
We don't need to look up the rtas event token once per
cpu per second. This avoids some misc string ops and
rtas calls and provides some minor performance improvement.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/platforms/pseries/rtasd.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/rtasd.c 2007-07-08 18:32:17.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c 2007-08-07 17:57:13.000000000 -0500
@@ -44,10 +44,13 @@ static unsigned long rtas_log_start;
static unsigned long rtas_log_size;
static int surveillance_timeout = -1;
-static unsigned int rtas_event_scan_rate;
static unsigned int rtas_error_log_max;
static unsigned int rtas_error_log_buffer_max;
+/* RTAS service tokens */
+static unsigned int event_scan;
+static unsigned int rtas_event_scan_rate;
+
static int full_rtas_msgs = 0;
extern int no_logging;
@@ -381,7 +384,7 @@ static int get_eventscan_parms(void)
return 0;
}
-static void do_event_scan(int event_scan)
+static void do_event_scan(void)
{
int error;
do {
@@ -408,7 +411,7 @@ static void do_event_scan_all_cpus(long
cpu = first_cpu(cpu_online_map);
for (;;) {
set_cpus_allowed(current, cpumask_of_cpu(cpu));
- do_event_scan(rtas_token("event-scan"));
+ do_event_scan();
set_cpus_allowed(current, CPU_MASK_ALL);
/* Drop hotplug lock, and sleep for the specified delay */
@@ -426,12 +429,11 @@ static void do_event_scan_all_cpus(long
static int rtasd(void *unused)
{
unsigned int err_type;
- int event_scan = rtas_token("event-scan");
int rc;
daemonize("rtasd");
- if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1)
+ if (get_eventscan_parms() == -1)
goto error;
rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
@@ -486,7 +488,8 @@ static int __init rtas_init(void)
return 0;
/* No RTAS */
- if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
+ event_scan = rtas_token("event-scan");
+ if (event_scan == RTAS_UNKNOWN_SERVICE) {
printk(KERN_DEBUG "rtasd: no event-scan on system\n");
return -ENODEV;
}
^ permalink raw reply
* [PATCH 2/6] pseries: use rtas_token instead of hand-rolled code
From: Linas Vepstas @ 2007-08-08 20:02 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808200115.GA20134@austin.ibm.com>
The rtas_token() call does the same thing as this hand-rolled code.
This makes the code easier to read.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/platforms/pseries/rtasd.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/rtasd.c 2007-08-07 17:57:13.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c 2007-08-07 17:57:49.000000000 -0500
@@ -361,26 +361,17 @@ static int enable_surveillance(int timeo
static int get_eventscan_parms(void)
{
- struct device_node *node;
- const int *ip;
-
- node = of_find_node_by_path("/rtas");
-
- ip = of_get_property(node, "rtas-event-scan-rate", NULL);
- if (ip == NULL) {
+ rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
+ if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n");
- of_node_put(node);
return -1;
}
- rtas_event_scan_rate = *ip;
DEBUG("rtas-event-scan-rate %d\n", rtas_event_scan_rate);
/* Make room for the sequence number */
rtas_error_log_max = rtas_get_error_log_max();
rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
- of_node_put(node);
-
return 0;
}
^ permalink raw reply
* [PATCH 3/6] pseries: simplify rtasd initialization
From: Linas Vepstas @ 2007-08-08 20:03 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808200210.GB20134@austin.ibm.com>
Simplify rtasd initialization code; this also fixes a buglet,
where the /proc entries weren't being cleaned up in case of
failure.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/platforms/pseries/rtasd.c | 53 +++++++++++----------------------
1 file changed, 19 insertions(+), 34 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:19:47.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:20:44.000000000 -0500
@@ -64,8 +64,6 @@ volatile int error_log_cnt = 0;
*/
static unsigned char logdata[RTAS_ERROR_LOG_MAX];
-static int get_eventscan_parms(void);
-
static char *rtas_type[] = {
"Unknown", "Retry", "TCE Error", "Internal Device Failure",
"Timeout", "Data Parity", "Address Parity", "Cache Parity",
@@ -169,9 +167,9 @@ static int log_rtas_len(char * buf)
len += err->extended_log_length;
}
- if (rtas_error_log_max == 0) {
- get_eventscan_parms();
- }
+ if (rtas_error_log_max == 0)
+ rtas_error_log_max = rtas_get_error_log_max();
+
if (len > rtas_error_log_max)
len = rtas_error_log_max;
@@ -359,22 +357,6 @@ static int enable_surveillance(int timeo
return -1;
}
-static int get_eventscan_parms(void)
-{
- rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
- if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
- printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n");
- return -1;
- }
- DEBUG("rtas-event-scan-rate %d\n", rtas_event_scan_rate);
-
- /* Make room for the sequence number */
- rtas_error_log_max = rtas_get_error_log_max();
- rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
-
- return 0;
-}
-
static void do_event_scan(void)
{
int error;
@@ -424,22 +406,11 @@ static int rtasd(void *unused)
daemonize("rtasd");
- if (get_eventscan_parms() == -1)
- goto error;
-
- rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
- if (!rtas_log_buf) {
- printk(KERN_ERR "rtasd: no memory\n");
- goto error;
- }
-
printk(KERN_DEBUG "RTAS daemon started\n");
-
DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate));
/* See if we have any error stored in NVRAM */
memset(logdata, 0, rtas_error_log_max);
-
rc = nvram_read_error_log(logdata, rtas_error_log_max, &err_type);
/* We can use rtas_log_buf now */
@@ -466,8 +437,6 @@ static int rtasd(void *unused)
for (;;)
do_event_scan_all_cpus(30000/rtas_event_scan_rate);
-error:
- /* Should delete proc entries */
return -EINVAL;
}
@@ -485,6 +454,22 @@ static int __init rtas_init(void)
return -ENODEV;
}
+ rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
+ if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
+ return -ENODEV;
+ }
+
+ /* Make room for the sequence number */
+ rtas_error_log_max = rtas_get_error_log_max();
+ rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
+
+ rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
+ if (!rtas_log_buf) {
+ printk(KERN_ERR "rtasd: no memory\n");
+ return -ENOMEM;
+ }
+
entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL);
if (entry)
entry->proc_fops = &proc_rtas_log_operations;
^ permalink raw reply
* [PATCH 4/6] powerpc: remove nvram forward declarations
From: Linas Vepstas @ 2007-08-08 20:04 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808200337.GC20134@austin.ibm.com>
Forward declarations serve no purpose in this file.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/kernel/nvram_64.c | 5 -----
1 file changed, 5 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:19:17.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:21:05.000000000 -0500
@@ -34,11 +34,6 @@
#undef DEBUG_NVRAM
-static int nvram_scan_partitions(void);
-static int nvram_setup_partition(void);
-static int nvram_create_os_partition(void);
-static int nvram_remove_os_partition(void);
-
static struct nvram_partition * nvram_part;
static long nvram_error_log_index = -1;
static long nvram_error_log_size = 0;
^ permalink raw reply
* [PATCH 5/6] pseries: fix jumbled no_logging flag.
From: Linas Vepstas @ 2007-08-08 20:06 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808200448.GD20134@austin.ibm.com>
Get rid of the jumbled usage of the no_logging flag. Its use
spans several directories, and is incorrectly/misleadingly
documented. Instead, two changes:
1) nvram will accept error log as soon as its ready.
2) logging to nvram stops on the first fatal error reported.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/kernel/nvram_64.c | 8 --------
arch/powerpc/platforms/pseries/rtasd.c | 14 ++++++--------
2 files changed, 6 insertions(+), 16 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:21:05.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:21:16.000000000 -0500
@@ -38,10 +38,6 @@ static struct nvram_partition * nvram_pa
static long nvram_error_log_index = -1;
static long nvram_error_log_size = 0;
-int no_logging = 1; /* Until we initialize everything,
- * make sure we don't try logging
- * anything */
-
extern volatile int error_log_cnt;
struct err_log_info {
@@ -637,10 +633,6 @@ int nvram_write_error_log(char * buff, i
loff_t tmp_index;
struct err_log_info info;
- if (no_logging) {
- return -EPERM;
- }
-
if (nvram_error_log_index == -1) {
return -ESPIPE;
}
Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:20:44.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:21:16.000000000 -0500
@@ -53,7 +53,8 @@ static unsigned int rtas_event_scan_rate
static int full_rtas_msgs = 0;
-extern int no_logging;
+/* Stop logging to nvram after first fatal error */
+static int no_more_logging;
volatile int error_log_cnt = 0;
@@ -216,7 +217,7 @@ void pSeries_log_error(char *buf, unsign
}
/* Write error to NVRAM */
- if (!no_logging && !(err_type & ERR_FLAG_BOOT))
+ if (!no_more_logging && !(err_type & ERR_FLAG_BOOT))
nvram_write_error_log(buf, len, err_type);
/*
@@ -228,8 +229,8 @@ void pSeries_log_error(char *buf, unsign
printk_log_rtas(buf, len);
/* Check to see if we need to or have stopped logging */
- if (fatal || no_logging) {
- no_logging = 1;
+ if (fatal || no_more_logging) {
+ no_more_logging = 1;
spin_unlock_irqrestore(&rtasd_log_lock, s);
return;
}
@@ -301,7 +302,7 @@ static ssize_t rtas_log_read(struct file
spin_lock_irqsave(&rtasd_log_lock, s);
/* if it's 0, then we know we got the last one (the one in NVRAM) */
- if (rtas_log_size == 0 && !no_logging)
+ if (rtas_log_size == 0 && !no_more_logging)
nvram_clear_error_log();
spin_unlock_irqrestore(&rtasd_log_lock, s);
@@ -413,9 +414,6 @@ static int rtasd(void *unused)
memset(logdata, 0, rtas_error_log_max);
rc = nvram_read_error_log(logdata, rtas_error_log_max, &err_type);
- /* We can use rtas_log_buf now */
- no_logging = 0;
-
if (!rc) {
if (err_type != ERR_FLAG_ALREADY_LOGGED) {
pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
^ permalink raw reply
* [PATCH 6/6] pseries: eliminate global var
From: Linas Vepstas @ 2007-08-08 20:07 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <20070808200615.GE20134@austin.ibm.com>
Eliminate the use of error_log_cnt as a global var shared across
differnt directories. Pass it as a subroutine arg instead.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/kernel/nvram_64.c | 10 +++++-----
arch/powerpc/platforms/pseries/rtasd.c | 7 ++++---
include/asm-powerpc/nvram.h | 15 ++++++++++-----
3 files changed, 19 insertions(+), 13 deletions(-)
Index: linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:21:16.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/kernel/nvram_64.c 2007-08-08 12:24:01.000000000 -0500
@@ -38,8 +38,6 @@ static struct nvram_partition * nvram_pa
static long nvram_error_log_index = -1;
static long nvram_error_log_size = 0;
-extern volatile int error_log_cnt;
-
struct err_log_info {
int error_type;
unsigned int seq_num;
@@ -627,7 +625,8 @@ void __exit nvram_cleanup(void)
* sequence #: The unique sequence # for each event. (until it wraps)
* error log: The error log from event_scan
*/
-int nvram_write_error_log(char * buff, int length, unsigned int err_type)
+int nvram_write_error_log(char * buff, int length,
+ unsigned int err_type, unsigned int error_log_cnt)
{
int rc;
loff_t tmp_index;
@@ -665,7 +664,8 @@ int nvram_write_error_log(char * buff, i
*
* Reads nvram for error log for at most 'length'
*/
-int nvram_read_error_log(char * buff, int length, unsigned int * err_type)
+int nvram_read_error_log(char * buff, int length,
+ unsigned int * err_type, unsigned int * error_log_cnt)
{
int rc;
loff_t tmp_index;
@@ -691,7 +691,7 @@ int nvram_read_error_log(char * buff, in
return rc;
}
- error_log_cnt = info.seq_num;
+ *error_log_cnt = info.seq_num;
*err_type = info.error_type;
return 0;
Index: linux-2.6.22-git2/include/asm-powerpc/nvram.h
===================================================================
--- linux-2.6.22-git2.orig/include/asm-powerpc/nvram.h 2007-07-08 18:32:17.000000000 -0500
+++ linux-2.6.22-git2/include/asm-powerpc/nvram.h 2007-08-08 13:34:27.000000000 -0500
@@ -62,14 +62,19 @@ struct nvram_partition {
unsigned int index;
};
-
-extern int nvram_write_error_log(char * buff, int length, unsigned int err_type);
-extern int nvram_read_error_log(char * buff, int length, unsigned int * err_type);
-extern int nvram_clear_error_log(void);
extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
-extern int pSeries_nvram_init(void);
extern int mmio_nvram_init(void);
+
+#ifdef CONFIG_PPC_PSERIES
+extern int pSeries_nvram_init(void);
+extern int nvram_write_error_log(char * buff, int length,
+ unsigned int err_type, unsigned int err_seq);
+extern int nvram_read_error_log(char * buff, int length,
+ unsigned int * err_type, unsigned int *err_seq);
+extern int nvram_clear_error_log(void);
+#endif /* CONFIG_PPC_PSERIES */
+
#endif /* __KERNEL__ */
/* PowerMac specific nvram stuffs */
Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:21:16.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/rtasd.c 2007-08-08 12:50:40.000000000 -0500
@@ -56,7 +56,7 @@ static int full_rtas_msgs = 0;
/* Stop logging to nvram after first fatal error */
static int no_more_logging;
-volatile int error_log_cnt = 0;
+static int error_log_cnt;
/*
* Since we use 32 bit RTAS, the physical address of this must be below
@@ -218,7 +218,7 @@ void pSeries_log_error(char *buf, unsign
/* Write error to NVRAM */
if (!no_more_logging && !(err_type & ERR_FLAG_BOOT))
- nvram_write_error_log(buf, len, err_type);
+ nvram_write_error_log(buf, len, err_type, error_log_cnt);
/*
* rtas errors can occur during boot, and we do want to capture
@@ -412,7 +412,8 @@ static int rtasd(void *unused)
/* See if we have any error stored in NVRAM */
memset(logdata, 0, rtas_error_log_max);
- rc = nvram_read_error_log(logdata, rtas_error_log_max, &err_type);
+ rc = nvram_read_error_log(logdata, rtas_error_log_max,
+ &err_type, &error_log_cnt);
if (!rc) {
if (err_type != ERR_FLAG_ALREADY_LOGGED) {
^ 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