aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/ds.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-12 16:47:50 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-16 07:04:28 -0400
commit43fdf27470b216ebdef47e09ff83bed2f2894b13 (patch)
tree76b9b838089e5679471026037c93325c228df84a /arch/sparc64/kernel/ds.c
parent133f09a169f3022be3de671b29658b7ecb375022 (diff)
[SPARC64]: Abstract out mdesc accesses for better MD update handling.
Since we have to be able to handle MD updates, having an in-tree set of data structures representing the MD objects actually makes things more painful. The MD itself is easy to parse, and we can implement the existing interfaces using direct parsing of the MD binary image. The MD is now reference counted, so accesses have to now take the form: handle = mdesc_grab(); ... operations on MD ... mdesc_release(handle); The only remaining issue are cases where code holds on to references to MD property values. mdesc_get_property() returns a direct pointer to the property value, most cases just pull in the information they need and discard the pointer, but there are few that use the pointer directly over a long lifetime. Those will be fixed up in a subsequent changeset. A preliminary handler for MD update events from domain services is there, it is rudimentry but it works and handles all of the reference counting. It does not check the generation number of the MDs, and it does not generate a "add/delete" list for notification to interesting parties about MD changes but that will be forthcoming. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/ds.c')
-rw-r--r--arch/sparc64/kernel/ds.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index c7ece8c5203..9c8839d1cff 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -15,6 +15,7 @@
15#include <asm/ldc.h> 15#include <asm/ldc.h>
16#include <asm/vio.h> 16#include <asm/vio.h>
17#include <asm/power.h> 17#include <asm/power.h>
18#include <asm/mdesc.h>
18 19
19#define DRV_MODULE_NAME "ds" 20#define DRV_MODULE_NAME "ds"
20#define PFX DRV_MODULE_NAME ": " 21#define PFX DRV_MODULE_NAME ": "
@@ -170,8 +171,7 @@ static void md_update_data(struct ldc_channel *lp,
170 171
171 rp = (struct ds_md_update_req *) (dpkt + 1); 172 rp = (struct ds_md_update_req *) (dpkt + 1);
172 173
173 printk(KERN_ERR PFX "MD update REQ [%lx] len=%d\n", 174 printk(KERN_ERR PFX "Machine description update.\n");
174 rp->req_num, len);
175 175
176 memset(&pkt, 0, sizeof(pkt)); 176 memset(&pkt, 0, sizeof(pkt));
177 pkt.data.tag.type = DS_DATA; 177 pkt.data.tag.type = DS_DATA;
@@ -181,6 +181,8 @@ static void md_update_data(struct ldc_channel *lp,
181 pkt.res.result = DS_OK; 181 pkt.res.result = DS_OK;
182 182
183 ds_send(lp, &pkt, sizeof(pkt)); 183 ds_send(lp, &pkt, sizeof(pkt));
184
185 mdesc_update();
184} 186}
185 187
186struct ds_shutdown_req { 188struct ds_shutdown_req {
@@ -555,7 +557,6 @@ static int __devinit ds_probe(struct vio_dev *vdev,
555 const struct vio_device_id *id) 557 const struct vio_device_id *id)
556{ 558{
557 static int ds_version_printed; 559 static int ds_version_printed;
558 struct mdesc_node *endp;
559 struct ldc_channel_config ds_cfg = { 560 struct ldc_channel_config ds_cfg = {
560 .event = ds_event, 561 .event = ds_event,
561 .mtu = 4096, 562 .mtu = 4096,
@@ -563,20 +564,11 @@ static int __devinit ds_probe(struct vio_dev *vdev,
563 }; 564 };
564 struct ldc_channel *lp; 565 struct ldc_channel *lp;
565 struct ds_info *dp; 566 struct ds_info *dp;
566 const u64 *chan_id;
567 int err; 567 int err;
568 568
569 if (ds_version_printed++ == 0) 569 if (ds_version_printed++ == 0)
570 printk(KERN_INFO "%s", version); 570 printk(KERN_INFO "%s", version);
571 571
572 endp = vio_find_endpoint(vdev);
573 if (!endp)
574 return -ENODEV;
575
576 chan_id = md_get_property(endp, "id", NULL);
577 if (!chan_id)
578 return -ENODEV;
579
580 dp = kzalloc(sizeof(*dp), GFP_KERNEL); 572 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
581 err = -ENOMEM; 573 err = -ENOMEM;
582 if (!dp) 574 if (!dp)
@@ -588,10 +580,10 @@ static int __devinit ds_probe(struct vio_dev *vdev,
588 580
589 dp->rcv_buf_len = 4096; 581 dp->rcv_buf_len = 4096;
590 582
591 ds_cfg.tx_irq = endp->irqs[0]; 583 ds_cfg.tx_irq = vdev->tx_irq;
592 ds_cfg.rx_irq = endp->irqs[1]; 584 ds_cfg.rx_irq = vdev->rx_irq;
593 585
594 lp = ldc_alloc(*chan_id, &ds_cfg, dp); 586 lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp);
595 if (IS_ERR(lp)) { 587 if (IS_ERR(lp)) {
596 err = PTR_ERR(lp); 588 err = PTR_ERR(lp);
597 goto out_free_rcv_buf; 589 goto out_free_rcv_buf;