aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/viohs.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/viohs.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/viohs.c')
-rw-r--r--arch/sparc64/kernel/viohs.c35
1 files changed, 9 insertions, 26 deletions
diff --git a/arch/sparc64/kernel/viohs.c b/arch/sparc64/kernel/viohs.c
index b0b1b877934..15613add45d 100644
--- a/arch/sparc64/kernel/viohs.c
+++ b/arch/sparc64/kernel/viohs.c
@@ -136,7 +136,7 @@ static int process_unknown(struct vio_driver_state *vio, void *arg)
136 pkt->type, pkt->stype, pkt->stype_env, pkt->sid); 136 pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
137 137
138 printk(KERN_ERR "vio: ID[%lu] Resetting connection.\n", 138 printk(KERN_ERR "vio: ID[%lu] Resetting connection.\n",
139 vio->channel_id); 139 vio->vdev->channel_id);
140 140
141 ldc_disconnect(vio->lp); 141 ldc_disconnect(vio->lp);
142 142
@@ -678,21 +678,11 @@ extern int vio_ldc_alloc(struct vio_driver_state *vio,
678{ 678{
679 struct ldc_channel_config cfg = *base_cfg; 679 struct ldc_channel_config cfg = *base_cfg;
680 struct ldc_channel *lp; 680 struct ldc_channel *lp;
681 const u64 *id;
682 681
683 id = md_get_property(vio->endpoint, "id", NULL); 682 cfg.tx_irq = vio->vdev->tx_irq;
684 if (!id) { 683 cfg.rx_irq = vio->vdev->rx_irq;
685 printk(KERN_ERR "%s: Channel lacks id property.\n",
686 vio->name);
687 return -ENODEV;
688 }
689
690 vio->channel_id = *id;
691
692 cfg.rx_irq = vio->rx_irq;
693 cfg.tx_irq = vio->tx_irq;
694 684
695 lp = ldc_alloc(vio->channel_id, &cfg, event_arg); 685 lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg);
696 if (IS_ERR(lp)) 686 if (IS_ERR(lp))
697 return PTR_ERR(lp); 687 return PTR_ERR(lp);
698 688
@@ -728,7 +718,7 @@ void vio_port_up(struct vio_driver_state *vio)
728 if (err) 718 if (err)
729 printk(KERN_WARNING "%s: Port %lu bind failed, " 719 printk(KERN_WARNING "%s: Port %lu bind failed, "
730 "err=%d\n", 720 "err=%d\n",
731 vio->name, vio->channel_id, err); 721 vio->name, vio->vdev->channel_id, err);
732 } 722 }
733 723
734 if (!err) { 724 if (!err) {
@@ -736,7 +726,7 @@ void vio_port_up(struct vio_driver_state *vio)
736 if (err) 726 if (err)
737 printk(KERN_WARNING "%s: Port %lu connect failed, " 727 printk(KERN_WARNING "%s: Port %lu connect failed, "
738 "err=%d\n", 728 "err=%d\n",
739 vio->name, vio->channel_id, err); 729 vio->name, vio->vdev->channel_id, err);
740 } 730 }
741 if (err) { 731 if (err) {
742 unsigned long expires = jiffies + HZ; 732 unsigned long expires = jiffies + HZ;
@@ -757,9 +747,9 @@ static void vio_port_timer(unsigned long _arg)
757} 747}
758 748
759int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, 749int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
760 u8 dev_class, struct mdesc_node *channel_endpoint, 750 u8 dev_class, struct vio_version *ver_table,
761 struct vio_version *ver_table, int ver_table_size, 751 int ver_table_size, struct vio_driver_ops *ops,
762 struct vio_driver_ops *ops, char *name) 752 char *name)
763{ 753{
764 switch (dev_class) { 754 switch (dev_class) {
765 case VDEV_NETWORK: 755 case VDEV_NETWORK:
@@ -777,9 +767,6 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
777 !ops->handshake_complete) 767 !ops->handshake_complete)
778 return -EINVAL; 768 return -EINVAL;
779 769
780 if (!channel_endpoint)
781 return -EINVAL;
782
783 if (!ver_table || ver_table_size < 0) 770 if (!ver_table || ver_table_size < 0)
784 return -EINVAL; 771 return -EINVAL;
785 772
@@ -793,10 +780,6 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
793 vio->dev_class = dev_class; 780 vio->dev_class = dev_class;
794 vio->vdev = vdev; 781 vio->vdev = vdev;
795 782
796 vio->endpoint = channel_endpoint;
797 vio->tx_irq = channel_endpoint->irqs[0];
798 vio->rx_irq = channel_endpoint->irqs[1];
799
800 vio->ver_table = ver_table; 783 vio->ver_table = ver_table;
801 vio->ver_table_entries = ver_table_size; 784 vio->ver_table_entries = ver_table_size;
802 785