Commit 6fcd61f7bf5d56a83cbf26c14915138d1a64ca4e

Authored by Frank Blaschka
Committed by David S. Miller
1 parent c69748d1c9

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>

Showing 1 changed file with 74 additions and 45 deletions Side-by-side Diff

... ... @@ -42,6 +42,8 @@
42 42 .obj_size = sizeof(struct iucv_sock),
43 43 };
44 44  
  45 +static struct iucv_interface *pr_iucv;
  46 +
45 47 /* special AF_IUCV IPRM messages */
46 48 static const u8 iprm_shutdown[8] =
47 49 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
... ... @@ -165,7 +167,7 @@
165 167 case IUCV_CLOSING:
166 168 case IUCV_CONNECTED:
167 169 if (iucv->path) {
168   - err = iucv_path_sever(iucv->path, NULL);
  170 + err = pr_iucv->path_sever(iucv->path, NULL);
169 171 iucv_path_free(iucv->path);
170 172 iucv->path = NULL;
171 173 }
... ... @@ -229,7 +231,7 @@
229 231 static struct device_driver af_iucv_driver = {
230 232 .owner = THIS_MODULE,
231 233 .name = "afiucv",
232   - .bus = &iucv_bus,
  234 + .bus = NULL,
233 235 .pm = &afiucv_pm_ops,
234 236 };
235 237  
... ... @@ -412,7 +414,7 @@
412 414 low_nmcpy(user_data, iucv->src_name);
413 415 high_nmcpy(user_data, iucv->dst_name);
414 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 418 iucv_path_free(iucv->path);
417 419 iucv->path = NULL;
418 420 }
... ... @@ -704,8 +706,9 @@
704 706 err = -ENOMEM;
705 707 goto done;
706 708 }
707   - err = iucv_path_connect(iucv->path, &af_iucv_handler,
708   - sa->siucv_user_id, NULL, user_data, sk);
  709 + err = pr_iucv->path_connect(iucv->path, &af_iucv_handler,
  710 + sa->siucv_user_id, NULL, user_data,
  711 + sk);
709 712 if (err) {
710 713 iucv_path_free(iucv->path);
711 714 iucv->path = NULL;
... ... @@ -738,7 +741,7 @@
738 741 }
739 742  
740 743 if (err) {
741   - iucv_path_sever(iucv->path, NULL);
  744 + pr_iucv->path_sever(iucv->path, NULL);
742 745 iucv_path_free(iucv->path);
743 746 iucv->path = NULL;
744 747 }
... ... @@ -871,7 +874,7 @@
871 874  
872 875 memcpy(prmdata, (void *) skb->data, skb->len);
873 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 878 (void *) prmdata, 8);
876 879 }
877 880  
878 881  
... ... @@ -999,13 +1002,13 @@
999 1002 /* this error should never happen since the
1000 1003 * IUCV_IPRMDATA path flag is set... sever path */
1001 1004 if (err == 0x15) {
1002   - iucv_path_sever(iucv->path, NULL);
  1005 + pr_iucv->path_sever(iucv->path, NULL);
1003 1006 skb_unlink(skb, &iucv->send_skb_q);
1004 1007 err = -EPIPE;
1005 1008 goto fail;
1006 1009 }
1007 1010 } else
1008   - err = iucv_message_send(iucv->path, &txmsg, 0, 0,
  1011 + err = pr_iucv->message_send(iucv->path, &txmsg, 0, 0,
1009 1012 (void *) skb->data, skb->len);
1010 1013 if (err) {
1011 1014 if (err == 3) {
... ... @@ -1095,8 +1098,9 @@
1095 1098 skb->len = 0;
1096 1099 }
1097 1100 } else {
1098   - rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA,
1099   - skb->data, len, NULL);
  1101 + rc = pr_iucv->message_receive(path, msg,
  1102 + msg->flags & IUCV_IPRMDATA,
  1103 + skb->data, len, NULL);
1100 1104 if (rc) {
1101 1105 kfree_skb(skb);
1102 1106 return;
... ... @@ -1110,7 +1114,7 @@
1110 1114 kfree_skb(skb);
1111 1115 skb = NULL;
1112 1116 if (rc) {
1113   - iucv_path_sever(path, NULL);
  1117 + pr_iucv->path_sever(path, NULL);
1114 1118 return;
1115 1119 }
1116 1120 skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
... ... @@ -1327,8 +1331,8 @@
1327 1331 if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) {
1328 1332 txmsg.class = 0;
1329 1333 txmsg.tag = 0;
1330   - err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0,
1331   - (void *) iprm_shutdown, 8);
  1334 + err = pr_iucv->message_send(iucv->path, &txmsg, IUCV_IPRMDATA,
  1335 + 0, (void *) iprm_shutdown, 8);
1332 1336 if (err) {
1333 1337 switch (err) {
1334 1338 case 1:
... ... @@ -1345,7 +1349,7 @@
1345 1349 }
1346 1350  
1347 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 1353 if (err)
1350 1354 err = -ENOTCONN;
1351 1355  
... ... @@ -1372,7 +1376,7 @@
1372 1376  
1373 1377 /* Unregister with IUCV base support */
1374 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 1380 iucv_path_free(iucv_sk(sk)->path);
1377 1381 iucv_sk(sk)->path = NULL;
1378 1382 }
1379 1383  
... ... @@ -1514,14 +1518,14 @@
1514 1518 high_nmcpy(user_data, iucv->dst_name);
1515 1519 ASCEBC(user_data, sizeof(user_data));
1516 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 1522 iucv_path_free(path);
1519 1523 goto fail;
1520 1524 }
1521 1525  
1522 1526 /* Check for backlog size */
1523 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 1529 iucv_path_free(path);
1526 1530 goto fail;
1527 1531 }
... ... @@ -1529,7 +1533,7 @@
1529 1533 /* Create the new socket */
1530 1534 nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
1531 1535 if (!nsk) {
1532   - err = iucv_path_sever(path, user_data);
  1536 + err = pr_iucv->path_sever(path, user_data);
1533 1537 iucv_path_free(path);
1534 1538 goto fail;
1535 1539 }
1536 1540  
... ... @@ -1553,9 +1557,9 @@
1553 1557 /* set message limit for path based on msglimit of accepting socket */
1554 1558 niucv->msglimit = iucv->msglimit;
1555 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 1561 if (err) {
1558   - err = iucv_path_sever(path, user_data);
  1562 + err = pr_iucv->path_sever(path, user_data);
1559 1563 iucv_path_free(path);
1560 1564 iucv_sock_kill(nsk);
1561 1565 goto fail;
... ... @@ -1589,7 +1593,7 @@
1589 1593 int len;
1590 1594  
1591 1595 if (sk->sk_shutdown & RCV_SHUTDOWN) {
1592   - iucv_message_reject(path, msg);
  1596 + pr_iucv->message_reject(path, msg);
1593 1597 return;
1594 1598 }
1595 1599  
... ... @@ -1718,6 +1722,41 @@
1718 1722 .create = iucv_sock_create,
1719 1723 };
1720 1724  
  1725 +static 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 +
  1752 +out_driver:
  1753 + driver_unregister(&af_iucv_driver);
  1754 +out_iucv:
  1755 + pr_iucv->iucv_unregister(&af_iucv_handler, 0);
  1756 +out:
  1757 + return err;
  1758 +}
  1759 +
1721 1760 static int __init afiucv_init(void)
1722 1761 {
1723 1762 int err;
1724 1763  
1725 1764  
1726 1765  
1727 1766  
1728 1767  
1729 1768  
1730 1769  
... ... @@ -1735,44 +1774,33 @@
1735 1774 goto out;
1736 1775 }
1737 1776  
1738   - err = iucv_register(&af_iucv_handler, 0);
1739   - if (err)
  1777 + pr_iucv = try_then_request_module(symbol_get(iucv_if), "iucv");
  1778 + if (!pr_iucv) {
  1779 + printk(KERN_WARNING "iucv_if lookup failed\n");
  1780 + err = -EPROTONOSUPPORT;
1740 1781 goto out;
  1782 + }
  1783 +
1741 1784 err = proto_register(&iucv_proto, 0);
1742 1785 if (err)
1743   - goto out_iucv;
  1786 + goto out;
1744 1787 err = sock_register(&iucv_sock_family_ops);
1745 1788 if (err)
1746 1789 goto out_proto;
1747   - /* establish dummy device */
1748   - err = driver_register(&af_iucv_driver);
  1790 +
  1791 + err = afiucv_iucv_init();
1749 1792 if (err)
1750 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 1795 return 0;
1766 1796  
1767   -out_driver:
1768   - driver_unregister(&af_iucv_driver);
1769 1797 out_sock:
1770 1798 sock_unregister(PF_IUCV);
1771 1799 out_proto:
1772 1800 proto_unregister(&iucv_proto);
1773   -out_iucv:
1774   - iucv_unregister(&af_iucv_handler, 0);
1775 1801 out:
  1802 + if (pr_iucv)
  1803 + symbol_put(iucv_if);
1776 1804 return err;
1777 1805 }
1778 1806  
1779 1807  
... ... @@ -1780,9 +1808,10 @@
1780 1808 {
1781 1809 device_unregister(af_iucv_dev);
1782 1810 driver_unregister(&af_iucv_driver);
  1811 + pr_iucv->iucv_unregister(&af_iucv_handler, 0);
  1812 + symbol_put(iucv_if);
1783 1813 sock_unregister(PF_IUCV);
1784 1814 proto_unregister(&iucv_proto);
1785   - iucv_unregister(&af_iucv_handler, 0);
1786 1815 }
1787 1816  
1788 1817 module_init(afiucv_init);