Skip to content

Commit 6fcd61f

Browse files
Frank Blaschkadavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c69748d commit 6fcd61f

File tree

1 file changed

+74
-45
lines changed

1 file changed

+74
-45
lines changed

net/iucv/af_iucv.c

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ static struct proto iucv_proto = {
4242
.obj_size = sizeof(struct iucv_sock),
4343
};
4444

45+
static struct iucv_interface *pr_iucv;
46+
4547
/* special AF_IUCV IPRM messages */
4648
static const u8 iprm_shutdown[8] =
4749
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
@@ -165,7 +167,7 @@ static int afiucv_pm_freeze(struct device *dev)
165167
case IUCV_CLOSING:
166168
case IUCV_CONNECTED:
167169
if (iucv->path) {
168-
err = iucv_path_sever(iucv->path, NULL);
170+
err = pr_iucv->path_sever(iucv->path, NULL);
169171
iucv_path_free(iucv->path);
170172
iucv->path = NULL;
171173
}
@@ -229,7 +231,7 @@ static const struct dev_pm_ops afiucv_pm_ops = {
229231
static struct device_driver af_iucv_driver = {
230232
.owner = THIS_MODULE,
231233
.name = "afiucv",
232-
.bus = &iucv_bus,
234+
.bus = NULL,
233235
.pm = &afiucv_pm_ops,
234236
};
235237

@@ -412,7 +414,7 @@ static void iucv_sock_close(struct sock *sk)
412414
low_nmcpy(user_data, iucv->src_name);
413415
high_nmcpy(user_data, iucv->dst_name);
414416
ASCEBC(user_data, sizeof(user_data));
415-
iucv_path_sever(iucv->path, user_data);
417+
pr_iucv->path_sever(iucv->path, user_data);
416418
iucv_path_free(iucv->path);
417419
iucv->path = NULL;
418420
}
@@ -704,8 +706,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
704706
err = -ENOMEM;
705707
goto done;
706708
}
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);
709712
if (err) {
710713
iucv_path_free(iucv->path);
711714
iucv->path = NULL;
@@ -738,7 +741,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
738741
}
739742

740743
if (err) {
741-
iucv_path_sever(iucv->path, NULL);
744+
pr_iucv->path_sever(iucv->path, NULL);
742745
iucv_path_free(iucv->path);
743746
iucv->path = NULL;
744747
}
@@ -871,7 +874,7 @@ static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
871874

872875
memcpy(prmdata, (void *) skb->data, skb->len);
873876
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,
875878
(void *) prmdata, 8);
876879
}
877880

@@ -999,13 +1002,13 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
9991002
/* this error should never happen since the
10001003
* IUCV_IPRMDATA path flag is set... sever path */
10011004
if (err == 0x15) {
1002-
iucv_path_sever(iucv->path, NULL);
1005+
pr_iucv->path_sever(iucv->path, NULL);
10031006
skb_unlink(skb, &iucv->send_skb_q);
10041007
err = -EPIPE;
10051008
goto fail;
10061009
}
10071010
} else
1008-
err = iucv_message_send(iucv->path, &txmsg, 0, 0,
1011+
err = pr_iucv->message_send(iucv->path, &txmsg, 0, 0,
10091012
(void *) skb->data, skb->len);
10101013
if (err) {
10111014
if (err == 3) {
@@ -1095,8 +1098,9 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
10951098
skb->len = 0;
10961099
}
10971100
} 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);
11001104
if (rc) {
11011105
kfree_skb(skb);
11021106
return;
@@ -1110,7 +1114,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
11101114
kfree_skb(skb);
11111115
skb = NULL;
11121116
if (rc) {
1113-
iucv_path_sever(path, NULL);
1117+
pr_iucv->path_sever(path, NULL);
11141118
return;
11151119
}
11161120
skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
@@ -1327,8 +1331,8 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
13271331
if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) {
13281332
txmsg.class = 0;
13291333
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);
13321336
if (err) {
13331337
switch (err) {
13341338
case 1:
@@ -1345,7 +1349,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
13451349
}
13461350

13471351
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);
13491353
if (err)
13501354
err = -ENOTCONN;
13511355

@@ -1372,7 +1376,7 @@ static int iucv_sock_release(struct socket *sock)
13721376

13731377
/* Unregister with IUCV base support */
13741378
if (iucv_sk(sk)->path) {
1375-
iucv_path_sever(iucv_sk(sk)->path, NULL);
1379+
pr_iucv->path_sever(iucv_sk(sk)->path, NULL);
13761380
iucv_path_free(iucv_sk(sk)->path);
13771381
iucv_sk(sk)->path = NULL;
13781382
}
@@ -1514,22 +1518,22 @@ static int iucv_callback_connreq(struct iucv_path *path,
15141518
high_nmcpy(user_data, iucv->dst_name);
15151519
ASCEBC(user_data, sizeof(user_data));
15161520
if (sk->sk_state != IUCV_LISTEN) {
1517-
err = iucv_path_sever(path, user_data);
1521+
err = pr_iucv->path_sever(path, user_data);
15181522
iucv_path_free(path);
15191523
goto fail;
15201524
}
15211525

15221526
/* Check for backlog size */
15231527
if (sk_acceptq_is_full(sk)) {
1524-
err = iucv_path_sever(path, user_data);
1528+
err = pr_iucv->path_sever(path, user_data);
15251529
iucv_path_free(path);
15261530
goto fail;
15271531
}
15281532

15291533
/* Create the new socket */
15301534
nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
15311535
if (!nsk) {
1532-
err = iucv_path_sever(path, user_data);
1536+
err = pr_iucv->path_sever(path, user_data);
15331537
iucv_path_free(path);
15341538
goto fail;
15351539
}
@@ -1553,9 +1557,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
15531557
/* set message limit for path based on msglimit of accepting socket */
15541558
niucv->msglimit = iucv->msglimit;
15551559
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);
15571561
if (err) {
1558-
err = iucv_path_sever(path, user_data);
1562+
err = pr_iucv->path_sever(path, user_data);
15591563
iucv_path_free(path);
15601564
iucv_sock_kill(nsk);
15611565
goto fail;
@@ -1589,7 +1593,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
15891593
int len;
15901594

15911595
if (sk->sk_shutdown & RCV_SHUTDOWN) {
1592-
iucv_message_reject(path, msg);
1596+
pr_iucv->message_reject(path, msg);
15931597
return;
15941598
}
15951599

@@ -1718,6 +1722,41 @@ static const struct net_proto_family iucv_sock_family_ops = {
17181722
.create = iucv_sock_create,
17191723
};
17201724

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+
17211760
static int __init afiucv_init(void)
17221761
{
17231762
int err;
@@ -1735,54 +1774,44 @@ static int __init afiucv_init(void)
17351774
goto out;
17361775
}
17371776

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;
17401781
goto out;
1782+
}
1783+
17411784
err = proto_register(&iucv_proto, 0);
17421785
if (err)
1743-
goto out_iucv;
1786+
goto out;
17441787
err = sock_register(&iucv_sock_family_ops);
17451788
if (err)
17461789
goto out_proto;
1747-
/* establish dummy device */
1748-
err = driver_register(&af_iucv_driver);
1790+
1791+
err = afiucv_iucv_init();
17491792
if (err)
17501793
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;
17641794

17651795
return 0;
17661796

1767-
out_driver:
1768-
driver_unregister(&af_iucv_driver);
17691797
out_sock:
17701798
sock_unregister(PF_IUCV);
17711799
out_proto:
17721800
proto_unregister(&iucv_proto);
1773-
out_iucv:
1774-
iucv_unregister(&af_iucv_handler, 0);
17751801
out:
1802+
if (pr_iucv)
1803+
symbol_put(iucv_if);
17761804
return err;
17771805
}
17781806

17791807
static void __exit afiucv_exit(void)
17801808
{
17811809
device_unregister(af_iucv_dev);
17821810
driver_unregister(&af_iucv_driver);
1811+
pr_iucv->iucv_unregister(&af_iucv_handler, 0);
1812+
symbol_put(iucv_if);
17831813
sock_unregister(PF_IUCV);
17841814
proto_unregister(&iucv_proto);
1785-
iucv_unregister(&af_iucv_handler, 0);
17861815
}
17871816

17881817
module_init(afiucv_init);

0 commit comments

Comments
 (0)