aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv
diff options
context:
space:
mode:
authorFrank Blaschka <frank.blaschka@de.ibm.com>2011-08-07 21:33:51 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-13 04:10:16 -0400
commit6fcd61f7bf5d56a83cbf26c14915138d1a64ca4e (patch)
tree5efef0bc1c28fb5e9707bcab7bad9b9cd405ef3d /net/iucv
parentc69748d1c9b5c2db8daae7a1eb55c46932e4376a (diff)
af_iucv: use loadable iucv interface
For future af_iucv extensions the module should be able to run in LPAR mode too. For this we use the new dynamic loading iucv interface. Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/iucv')
-rw-r--r--net/iucv/af_iucv.c119
1 files changed, 74 insertions, 45 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index e2013e434d03..2270e25a0298 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -42,6 +42,8 @@ static struct proto iucv_proto = {
42 .obj_size = sizeof(struct iucv_sock), 42 .obj_size = sizeof(struct iucv_sock),
43}; 43};
44 44
45static struct iucv_interface *pr_iucv;
46
45/* special AF_IUCV IPRM messages */ 47/* special AF_IUCV IPRM messages */
46static const u8 iprm_shutdown[8] = 48static const u8 iprm_shutdown[8] =
47 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; 49 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
@@ -165,7 +167,7 @@ static int afiucv_pm_freeze(struct device *dev)
165 case IUCV_CLOSING: 167 case IUCV_CLOSING:
166 case IUCV_CONNECTED: 168 case IUCV_CONNECTED:
167 if (iucv->path) { 169 if (iucv->path) {
168 err = iucv_path_sever(iucv->path, NULL); 170 err = pr_iucv->path_sever(iucv->path, NULL);
169 iucv_path_free(iucv->path); 171 iucv_path_free(iucv->path);
170 iucv->path = NULL; 172 iucv->path = NULL;
171 } 173 }
@@ -229,7 +231,7 @@ static const struct dev_pm_ops afiucv_pm_ops = {
229static struct device_driver af_iucv_driver = { 231static struct device_driver af_iucv_driver = {
230 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
231 .name = "afiucv", 233 .name = "afiucv",
232 .bus = &iucv_bus, 234 .bus = NULL,
233 .pm = &afiucv_pm_ops, 235 .pm = &afiucv_pm_ops,
234}; 236};
235 237
@@ -412,7 +414,7 @@ static void iucv_sock_close(struct sock *sk)
412 low_nmcpy(user_data, iucv->src_name); 414 low_nmcpy(user_data, iucv->src_name);
413 high_nmcpy(user_data, iucv->dst_name); 415 high_nmcpy(user_data, iucv->dst_name);
414 ASCEBC(user_data, sizeof(user_data)); 416 ASCEBC(user_data, sizeof(user_data));
415 iucv_path_sever(iucv->path, user_data); 417 pr_iucv->path_sever(iucv->path, user_data);
416 iucv_path_free(iucv->path); 418 iucv_path_free(iucv->path);
417 iucv->path = NULL; 419 iucv->path = NULL;
418 } 420 }
@@ -704,8 +706,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
704 err = -ENOMEM; 706 err = -ENOMEM;
705 goto done; 707 goto done;
706 } 708 }
707 err = iucv_path_connect(iucv->path, &af_iucv_handler, 709 err = pr_iucv->path_connect(iucv->path, &af_iucv_handler,
708 sa->siucv_user_id, NULL, user_data, sk); 710 sa->siucv_user_id, NULL, user_data,
711 sk);
709 if (err) { 712 if (err) {
710 iucv_path_free(iucv->path); 713 iucv_path_free(iucv->path);
711 iucv->path = NULL; 714 iucv->path = NULL;
@@ -738,7 +741,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
738 } 741 }
739 742
740 if (err) { 743 if (err) {
741 iucv_path_sever(iucv->path, NULL); 744 pr_iucv->path_sever(iucv->path, NULL);
742 iucv_path_free(iucv->path); 745 iucv_path_free(iucv->path);
743 iucv->path = NULL; 746 iucv->path = NULL;
744 } 747 }
@@ -871,7 +874,7 @@ static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
871 874
872 memcpy(prmdata, (void *) skb->data, skb->len); 875 memcpy(prmdata, (void *) skb->data, skb->len);
873 prmdata[7] = 0xff - (u8) skb->len; 876 prmdata[7] = 0xff - (u8) skb->len;
874 return iucv_message_send(path, msg, IUCV_IPRMDATA, 0, 877 return pr_iucv->message_send(path, msg, IUCV_IPRMDATA, 0,
875 (void *) prmdata, 8); 878 (void *) prmdata, 8);
876} 879}
877 880
@@ -999,13 +1002,13 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
999 /* this error should never happen since the 1002 /* this error should never happen since the
1000 * IUCV_IPRMDATA path flag is set... sever path */ 1003 * IUCV_IPRMDATA path flag is set... sever path */
1001 if (err == 0x15) { 1004 if (err == 0x15) {
1002 iucv_path_sever(iucv->path, NULL); 1005 pr_iucv->path_sever(iucv->path, NULL);
1003 skb_unlink(skb, &iucv->send_skb_q); 1006 skb_unlink(skb, &iucv->send_skb_q);
1004 err = -EPIPE; 1007 err = -EPIPE;
1005 goto fail; 1008 goto fail;
1006 } 1009 }
1007 } else 1010 } else
1008 err = iucv_message_send(iucv->path, &txmsg, 0, 0, 1011 err = pr_iucv->message_send(iucv->path, &txmsg, 0, 0,
1009 (void *) skb->data, skb->len); 1012 (void *) skb->data, skb->len);
1010 if (err) { 1013 if (err) {
1011 if (err == 3) { 1014 if (err == 3) {
@@ -1095,8 +1098,9 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
1095 skb->len = 0; 1098 skb->len = 0;
1096 } 1099 }
1097 } else { 1100 } else {
1098 rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA, 1101 rc = pr_iucv->message_receive(path, msg,
1099 skb->data, len, NULL); 1102 msg->flags & IUCV_IPRMDATA,
1103 skb->data, len, NULL);
1100 if (rc) { 1104 if (rc) {
1101 kfree_skb(skb); 1105 kfree_skb(skb);
1102 return; 1106 return;
@@ -1110,7 +1114,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
1110 kfree_skb(skb); 1114 kfree_skb(skb);
1111 skb = NULL; 1115 skb = NULL;
1112 if (rc) { 1116 if (rc) {
1113 iucv_path_sever(path, NULL); 1117 pr_iucv->path_sever(path, NULL);
1114 return; 1118 return;
1115 } 1119 }
1116 skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q); 1120 skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
@@ -1327,8 +1331,8 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
1327 if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) { 1331 if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) {
1328 txmsg.class = 0; 1332 txmsg.class = 0;
1329 txmsg.tag = 0; 1333 txmsg.tag = 0;
1330 err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0, 1334 err = pr_iucv->message_send(iucv->path, &txmsg, IUCV_IPRMDATA,
1331 (void *) iprm_shutdown, 8); 1335 0, (void *) iprm_shutdown, 8);
1332 if (err) { 1336 if (err) {
1333 switch (err) { 1337 switch (err) {
1334 case 1: 1338 case 1:
@@ -1345,7 +1349,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
1345 } 1349 }
1346 1350
1347 if (how == RCV_SHUTDOWN || how == SHUTDOWN_MASK) { 1351 if (how == RCV_SHUTDOWN || how == SHUTDOWN_MASK) {
1348 err = iucv_path_quiesce(iucv_sk(sk)->path, NULL); 1352 err = pr_iucv->path_quiesce(iucv->path, NULL);
1349 if (err) 1353 if (err)
1350 err = -ENOTCONN; 1354 err = -ENOTCONN;
1351 1355
@@ -1372,7 +1376,7 @@ static int iucv_sock_release(struct socket *sock)
1372 1376
1373 /* Unregister with IUCV base support */ 1377 /* Unregister with IUCV base support */
1374 if (iucv_sk(sk)->path) { 1378 if (iucv_sk(sk)->path) {
1375 iucv_path_sever(iucv_sk(sk)->path, NULL); 1379 pr_iucv->path_sever(iucv_sk(sk)->path, NULL);
1376 iucv_path_free(iucv_sk(sk)->path); 1380 iucv_path_free(iucv_sk(sk)->path);
1377 iucv_sk(sk)->path = NULL; 1381 iucv_sk(sk)->path = NULL;
1378 } 1382 }
@@ -1514,14 +1518,14 @@ static int iucv_callback_connreq(struct iucv_path *path,
1514 high_nmcpy(user_data, iucv->dst_name); 1518 high_nmcpy(user_data, iucv->dst_name);
1515 ASCEBC(user_data, sizeof(user_data)); 1519 ASCEBC(user_data, sizeof(user_data));
1516 if (sk->sk_state != IUCV_LISTEN) { 1520 if (sk->sk_state != IUCV_LISTEN) {
1517 err = iucv_path_sever(path, user_data); 1521 err = pr_iucv->path_sever(path, user_data);
1518 iucv_path_free(path); 1522 iucv_path_free(path);
1519 goto fail; 1523 goto fail;
1520 } 1524 }
1521 1525
1522 /* Check for backlog size */ 1526 /* Check for backlog size */
1523 if (sk_acceptq_is_full(sk)) { 1527 if (sk_acceptq_is_full(sk)) {
1524 err = iucv_path_sever(path, user_data); 1528 err = pr_iucv->path_sever(path, user_data);
1525 iucv_path_free(path); 1529 iucv_path_free(path);
1526 goto fail; 1530 goto fail;
1527 } 1531 }
@@ -1529,7 +1533,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
1529 /* Create the new socket */ 1533 /* Create the new socket */
1530 nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC); 1534 nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
1531 if (!nsk) { 1535 if (!nsk) {
1532 err = iucv_path_sever(path, user_data); 1536 err = pr_iucv->path_sever(path, user_data);
1533 iucv_path_free(path); 1537 iucv_path_free(path);
1534 goto fail; 1538 goto fail;
1535 } 1539 }
@@ -1553,9 +1557,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
1553 /* set message limit for path based on msglimit of accepting socket */ 1557 /* set message limit for path based on msglimit of accepting socket */
1554 niucv->msglimit = iucv->msglimit; 1558 niucv->msglimit = iucv->msglimit;
1555 path->msglim = iucv->msglimit; 1559 path->msglim = iucv->msglimit;
1556 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); 1560 err = pr_iucv->path_accept(path, &af_iucv_handler, nuser_data, nsk);
1557 if (err) { 1561 if (err) {
1558 err = iucv_path_sever(path, user_data); 1562 err = pr_iucv->path_sever(path, user_data);
1559 iucv_path_free(path); 1563 iucv_path_free(path);
1560 iucv_sock_kill(nsk); 1564 iucv_sock_kill(nsk);
1561 goto fail; 1565 goto fail;
@@ -1589,7 +1593,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
1589 int len; 1593 int len;
1590 1594
1591 if (sk->sk_shutdown & RCV_SHUTDOWN) { 1595 if (sk->sk_shutdown & RCV_SHUTDOWN) {
1592 iucv_message_reject(path, msg); 1596 pr_iucv->message_reject(path, msg);
1593 return; 1597 return;
1594 } 1598 }
1595 1599
@@ -1718,6 +1722,41 @@ static const struct net_proto_family iucv_sock_family_ops = {
1718 .create = iucv_sock_create, 1722 .create = iucv_sock_create,
1719}; 1723};
1720 1724
1725static int __init afiucv_iucv_init(void)
1726{
1727 int err;
1728
1729 err = pr_iucv->iucv_register(&af_iucv_handler, 0);
1730 if (err)
1731 goto out;
1732 /* establish dummy device */
1733 af_iucv_driver.bus = pr_iucv->bus;
1734 err = driver_register(&af_iucv_driver);
1735 if (err)
1736 goto out_iucv;
1737 af_iucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1738 if (!af_iucv_dev) {
1739 err = -ENOMEM;
1740 goto out_driver;
1741 }
1742 dev_set_name(af_iucv_dev, "af_iucv");
1743 af_iucv_dev->bus = pr_iucv->bus;
1744 af_iucv_dev->parent = pr_iucv->root;
1745 af_iucv_dev->release = (void (*)(struct device *))kfree;
1746 af_iucv_dev->driver = &af_iucv_driver;
1747 err = device_register(af_iucv_dev);
1748 if (err)
1749 goto out_driver;
1750 return 0;
1751
1752out_driver:
1753 driver_unregister(&af_iucv_driver);
1754out_iucv:
1755 pr_iucv->iucv_unregister(&af_iucv_handler, 0);
1756out:
1757 return err;
1758}
1759
1721static int __init afiucv_init(void) 1760static int __init afiucv_init(void)
1722{ 1761{
1723 int err; 1762 int err;
@@ -1735,44 +1774,33 @@ static int __init afiucv_init(void)
1735 goto out; 1774 goto out;
1736 } 1775 }
1737 1776
1738 err = iucv_register(&af_iucv_handler, 0); 1777 pr_iucv = try_then_request_module(symbol_get(iucv_if), "iucv");
1739 if (err) 1778 if (!pr_iucv) {
1779 printk(KERN_WARNING "iucv_if lookup failed\n");
1780 err = -EPROTONOSUPPORT;
1740 goto out; 1781 goto out;
1782 }
1783
1741 err = proto_register(&iucv_proto, 0); 1784 err = proto_register(&iucv_proto, 0);
1742 if (err) 1785 if (err)
1743 goto out_iucv; 1786 goto out;
1744 err = sock_register(&iucv_sock_family_ops); 1787 err = sock_register(&iucv_sock_family_ops);
1745 if (err) 1788 if (err)
1746 goto out_proto; 1789 goto out_proto;
1747 /* establish dummy device */ 1790
1748 err = driver_register(&af_iucv_driver); 1791 err = afiucv_iucv_init();
1749 if (err) 1792 if (err)
1750 goto out_sock; 1793 goto out_sock;
1751 af_iucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1752 if (!af_iucv_dev) {
1753 err = -ENOMEM;
1754 goto out_driver;
1755 }
1756 dev_set_name(af_iucv_dev, "af_iucv");
1757 af_iucv_dev->bus = &iucv_bus;
1758 af_iucv_dev->parent = iucv_root;
1759 af_iucv_dev->release = (void (*)(struct device *))kfree;
1760 af_iucv_dev->driver = &af_iucv_driver;
1761 err = device_register(af_iucv_dev);
1762 if (err)
1763 goto out_driver;
1764 1794
1765 return 0; 1795 return 0;
1766 1796
1767out_driver:
1768 driver_unregister(&af_iucv_driver);
1769out_sock: 1797out_sock:
1770 sock_unregister(PF_IUCV); 1798 sock_unregister(PF_IUCV);
1771out_proto: 1799out_proto:
1772 proto_unregister(&iucv_proto); 1800 proto_unregister(&iucv_proto);
1773out_iucv:
1774 iucv_unregister(&af_iucv_handler, 0);
1775out: 1801out:
1802 if (pr_iucv)
1803 symbol_put(iucv_if);
1776 return err; 1804 return err;
1777} 1805}
1778 1806
@@ -1780,9 +1808,10 @@ static void __exit afiucv_exit(void)
1780{ 1808{
1781 device_unregister(af_iucv_dev); 1809 device_unregister(af_iucv_dev);
1782 driver_unregister(&af_iucv_driver); 1810 driver_unregister(&af_iucv_driver);
1811 pr_iucv->iucv_unregister(&af_iucv_handler, 0);
1812 symbol_put(iucv_if);
1783 sock_unregister(PF_IUCV); 1813 sock_unregister(PF_IUCV);
1784 proto_unregister(&iucv_proto); 1814 proto_unregister(&iucv_proto);
1785 iucv_unregister(&af_iucv_handler, 0);
1786} 1815}
1787 1816
1788module_init(afiucv_init); 1817module_init(afiucv_init);