aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv/iucv.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/iucv/iucv.c')
-rw-r--r--net/iucv/iucv.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index a35240f61ec3..61e8038a55ee 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -280,6 +280,7 @@ union iucv_param {
280 * Anchor for per-cpu IUCV command parameter block. 280 * Anchor for per-cpu IUCV command parameter block.
281 */ 281 */
282static union iucv_param *iucv_param[NR_CPUS]; 282static union iucv_param *iucv_param[NR_CPUS];
283static union iucv_param *iucv_param_irq[NR_CPUS];
283 284
284/** 285/**
285 * iucv_call_b2f0 286 * iucv_call_b2f0
@@ -358,7 +359,7 @@ static void iucv_allow_cpu(void *data)
358 * 0x10 - Flag to allow priority message completion interrupts 359 * 0x10 - Flag to allow priority message completion interrupts
359 * 0x08 - Flag to allow IUCV control interrupts 360 * 0x08 - Flag to allow IUCV control interrupts
360 */ 361 */
361 parm = iucv_param[cpu]; 362 parm = iucv_param_irq[cpu];
362 memset(parm, 0, sizeof(union iucv_param)); 363 memset(parm, 0, sizeof(union iucv_param));
363 parm->set_mask.ipmask = 0xf8; 364 parm->set_mask.ipmask = 0xf8;
364 iucv_call_b2f0(IUCV_SETMASK, parm); 365 iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -379,7 +380,7 @@ static void iucv_block_cpu(void *data)
379 union iucv_param *parm; 380 union iucv_param *parm;
380 381
381 /* Disable all iucv interrupts. */ 382 /* Disable all iucv interrupts. */
382 parm = iucv_param[cpu]; 383 parm = iucv_param_irq[cpu];
383 memset(parm, 0, sizeof(union iucv_param)); 384 memset(parm, 0, sizeof(union iucv_param));
384 iucv_call_b2f0(IUCV_SETMASK, parm); 385 iucv_call_b2f0(IUCV_SETMASK, parm);
385 386
@@ -403,7 +404,7 @@ static void iucv_declare_cpu(void *data)
403 return; 404 return;
404 405
405 /* Declare interrupt buffer. */ 406 /* Declare interrupt buffer. */
406 parm = iucv_param[cpu]; 407 parm = iucv_param_irq[cpu];
407 memset(parm, 0, sizeof(union iucv_param)); 408 memset(parm, 0, sizeof(union iucv_param));
408 parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]); 409 parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
409 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); 410 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
@@ -460,7 +461,7 @@ static void iucv_retrieve_cpu(void *data)
460 iucv_block_cpu(NULL); 461 iucv_block_cpu(NULL);
461 462
462 /* Retrieve interrupt buffer. */ 463 /* Retrieve interrupt buffer. */
463 parm = iucv_param[cpu]; 464 parm = iucv_param_irq[cpu];
464 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); 465 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
465 466
466 /* Clear indication that an iucv buffer exists for this cpu. */ 467 /* Clear indication that an iucv buffer exists for this cpu. */
@@ -574,11 +575,22 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
574 iucv_irq_data[cpu] = NULL; 575 iucv_irq_data[cpu] = NULL;
575 return NOTIFY_BAD; 576 return NOTIFY_BAD;
576 } 577 }
578 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
579 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
580 if (!iucv_param_irq[cpu]) {
581 kfree(iucv_param[cpu]);
582 iucv_param[cpu] = NULL;
583 kfree(iucv_irq_data[cpu]);
584 iucv_irq_data[cpu] = NULL;
585 return NOTIFY_BAD;
586 }
577 break; 587 break;
578 case CPU_UP_CANCELED: 588 case CPU_UP_CANCELED:
579 case CPU_UP_CANCELED_FROZEN: 589 case CPU_UP_CANCELED_FROZEN:
580 case CPU_DEAD: 590 case CPU_DEAD:
581 case CPU_DEAD_FROZEN: 591 case CPU_DEAD_FROZEN:
592 kfree(iucv_param_irq[cpu]);
593 iucv_param_irq[cpu] = NULL;
582 kfree(iucv_param[cpu]); 594 kfree(iucv_param[cpu]);
583 iucv_param[cpu] = NULL; 595 iucv_param[cpu] = NULL;
584 kfree(iucv_irq_data[cpu]); 596 kfree(iucv_irq_data[cpu]);
@@ -625,7 +637,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
625{ 637{
626 union iucv_param *parm; 638 union iucv_param *parm;
627 639
628 parm = iucv_param[smp_processor_id()]; 640 parm = iucv_param_irq[smp_processor_id()];
629 memset(parm, 0, sizeof(union iucv_param)); 641 memset(parm, 0, sizeof(union iucv_param));
630 if (userdata) 642 if (userdata)
631 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); 643 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -918,10 +930,8 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
918 if (iucv_active_cpu != smp_processor_id()) 930 if (iucv_active_cpu != smp_processor_id())
919 spin_lock_bh(&iucv_table_lock); 931 spin_lock_bh(&iucv_table_lock);
920 rc = iucv_sever_pathid(path->pathid, userdata); 932 rc = iucv_sever_pathid(path->pathid, userdata);
921 if (!rc) { 933 iucv_path_table[path->pathid] = NULL;
922 iucv_path_table[path->pathid] = NULL; 934 list_del_init(&path->list);
923 list_del_init(&path->list);
924 }
925 if (iucv_active_cpu != smp_processor_id()) 935 if (iucv_active_cpu != smp_processor_id())
926 spin_unlock_bh(&iucv_table_lock); 936 spin_unlock_bh(&iucv_table_lock);
927 preempt_enable(); 937 preempt_enable();
@@ -1378,6 +1388,8 @@ static void iucv_path_complete(struct iucv_irq_data *data)
1378 struct iucv_path_complete *ipc = (void *) data; 1388 struct iucv_path_complete *ipc = (void *) data;
1379 struct iucv_path *path = iucv_path_table[ipc->ippathid]; 1389 struct iucv_path *path = iucv_path_table[ipc->ippathid];
1380 1390
1391 if (path)
1392 path->flags = ipc->ipflags1;
1381 if (path && path->handler && path->handler->path_complete) 1393 if (path && path->handler && path->handler->path_complete)
1382 path->handler->path_complete(path, ipc->ipuser); 1394 path->handler->path_complete(path, ipc->ipuser);
1383} 1395}
@@ -1413,7 +1425,7 @@ static void iucv_path_severed(struct iucv_irq_data *data)
1413 else { 1425 else {
1414 iucv_sever_pathid(path->pathid, NULL); 1426 iucv_sever_pathid(path->pathid, NULL);
1415 iucv_path_table[path->pathid] = NULL; 1427 iucv_path_table[path->pathid] = NULL;
1416 list_del_init(&path->list); 1428 list_del(&path->list);
1417 iucv_path_free(path); 1429 iucv_path_free(path);
1418 } 1430 }
1419} 1431}
@@ -1717,6 +1729,13 @@ static int __init iucv_init(void)
1717 rc = -ENOMEM; 1729 rc = -ENOMEM;
1718 goto out_free; 1730 goto out_free;
1719 } 1731 }
1732 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
1733 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
1734 if (!iucv_param_irq[cpu]) {
1735 rc = -ENOMEM;
1736 goto out_free;
1737 }
1738
1720 } 1739 }
1721 rc = register_hotcpu_notifier(&iucv_cpu_notifier); 1740 rc = register_hotcpu_notifier(&iucv_cpu_notifier);
1722 if (rc) 1741 if (rc)
@@ -1734,6 +1753,8 @@ out_cpu:
1734 unregister_hotcpu_notifier(&iucv_cpu_notifier); 1753 unregister_hotcpu_notifier(&iucv_cpu_notifier);
1735out_free: 1754out_free:
1736 for_each_possible_cpu(cpu) { 1755 for_each_possible_cpu(cpu) {
1756 kfree(iucv_param_irq[cpu]);
1757 iucv_param_irq[cpu] = NULL;
1737 kfree(iucv_param[cpu]); 1758 kfree(iucv_param[cpu]);
1738 iucv_param[cpu] = NULL; 1759 iucv_param[cpu] = NULL;
1739 kfree(iucv_irq_data[cpu]); 1760 kfree(iucv_irq_data[cpu]);
@@ -1764,6 +1785,8 @@ static void __exit iucv_exit(void)
1764 spin_unlock_irq(&iucv_queue_lock); 1785 spin_unlock_irq(&iucv_queue_lock);
1765 unregister_hotcpu_notifier(&iucv_cpu_notifier); 1786 unregister_hotcpu_notifier(&iucv_cpu_notifier);
1766 for_each_possible_cpu(cpu) { 1787 for_each_possible_cpu(cpu) {
1788 kfree(iucv_param_irq[cpu]);
1789 iucv_param_irq[cpu] = NULL;
1767 kfree(iucv_param[cpu]); 1790 kfree(iucv_param[cpu]);
1768 iucv_param[cpu] = NULL; 1791 iucv_param[cpu] = NULL;
1769 kfree(iucv_irq_data[cpu]); 1792 kfree(iucv_irq_data[cpu]);