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.c161
1 files changed, 122 insertions, 39 deletions
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index d7b54b5bfa69..8f57d4f4328a 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -30,6 +30,9 @@
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 */ 31 */
32 32
33#define KMSG_COMPONENT "iucv"
34#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
35
33#include <linux/module.h> 36#include <linux/module.h>
34#include <linux/moduleparam.h> 37#include <linux/moduleparam.h>
35#include <linux/spinlock.h> 38#include <linux/spinlock.h>
@@ -424,8 +427,8 @@ static void iucv_declare_cpu(void *data)
424 err = "Paging or storage error"; 427 err = "Paging or storage error";
425 break; 428 break;
426 } 429 }
427 printk(KERN_WARNING "iucv_register: iucv_declare_buffer " 430 pr_warning("Defining an interrupt buffer on CPU %i"
428 "on cpu %i returned error 0x%02x (%s)\n", cpu, rc, err); 431 " failed with 0x%02x (%s)\n", cpu, rc, err);
429 return; 432 return;
430 } 433 }
431 434
@@ -957,7 +960,52 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
957EXPORT_SYMBOL(iucv_message_purge); 960EXPORT_SYMBOL(iucv_message_purge);
958 961
959/** 962/**
960 * iucv_message_receive 963 * iucv_message_receive_iprmdata
964 * @path: address of iucv path structure
965 * @msg: address of iucv msg structure
966 * @flags: how the message is received (IUCV_IPBUFLST)
967 * @buffer: address of data buffer or address of struct iucv_array
968 * @size: length of data buffer
969 * @residual:
970 *
971 * Internal function used by iucv_message_receive and __iucv_message_receive
972 * to receive RMDATA data stored in struct iucv_message.
973 */
974static int iucv_message_receive_iprmdata(struct iucv_path *path,
975 struct iucv_message *msg,
976 u8 flags, void *buffer,
977 size_t size, size_t *residual)
978{
979 struct iucv_array *array;
980 u8 *rmmsg;
981 size_t copy;
982
983 /*
984 * Message is 8 bytes long and has been stored to the
985 * message descriptor itself.
986 */
987 if (residual)
988 *residual = abs(size - 8);
989 rmmsg = msg->rmmsg;
990 if (flags & IUCV_IPBUFLST) {
991 /* Copy to struct iucv_array. */
992 size = (size < 8) ? size : 8;
993 for (array = buffer; size > 0; array++) {
994 copy = min_t(size_t, size, array->length);
995 memcpy((u8 *)(addr_t) array->address,
996 rmmsg, copy);
997 rmmsg += copy;
998 size -= copy;
999 }
1000 } else {
1001 /* Copy to direct buffer. */
1002 memcpy(buffer, rmmsg, min_t(size_t, size, 8));
1003 }
1004 return 0;
1005}
1006
1007/**
1008 * __iucv_message_receive
961 * @path: address of iucv path structure 1009 * @path: address of iucv path structure
962 * @msg: address of iucv msg structure 1010 * @msg: address of iucv msg structure
963 * @flags: how the message is received (IUCV_IPBUFLST) 1011 * @flags: how the message is received (IUCV_IPBUFLST)
@@ -969,44 +1017,19 @@ EXPORT_SYMBOL(iucv_message_purge);
969 * established paths. This function will deal with RMDATA messages 1017 * established paths. This function will deal with RMDATA messages
970 * embedded in struct iucv_message as well. 1018 * embedded in struct iucv_message as well.
971 * 1019 *
1020 * Locking: no locking
1021 *
972 * Returns the result from the CP IUCV call. 1022 * Returns the result from the CP IUCV call.
973 */ 1023 */
974int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg, 1024int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
975 u8 flags, void *buffer, size_t size, size_t *residual) 1025 u8 flags, void *buffer, size_t size, size_t *residual)
976{ 1026{
977 union iucv_param *parm; 1027 union iucv_param *parm;
978 struct iucv_array *array;
979 u8 *rmmsg;
980 size_t copy;
981 int rc; 1028 int rc;
982 1029
983 if (msg->flags & IUCV_IPRMDATA) { 1030 if (msg->flags & IUCV_IPRMDATA)
984 /* 1031 return iucv_message_receive_iprmdata(path, msg, flags,
985 * Message is 8 bytes long and has been stored to the 1032 buffer, size, residual);
986 * message descriptor itself.
987 */
988 rc = (size < 8) ? 5 : 0;
989 if (residual)
990 *residual = abs(size - 8);
991 rmmsg = msg->rmmsg;
992 if (flags & IUCV_IPBUFLST) {
993 /* Copy to struct iucv_array. */
994 size = (size < 8) ? size : 8;
995 for (array = buffer; size > 0; array++) {
996 copy = min_t(size_t, size, array->length);
997 memcpy((u8 *)(addr_t) array->address,
998 rmmsg, copy);
999 rmmsg += copy;
1000 size -= copy;
1001 }
1002 } else {
1003 /* Copy to direct buffer. */
1004 memcpy(buffer, rmmsg, min_t(size_t, size, 8));
1005 }
1006 return 0;
1007 }
1008
1009 local_bh_disable();
1010 parm = iucv_param[smp_processor_id()]; 1033 parm = iucv_param[smp_processor_id()];
1011 memset(parm, 0, sizeof(union iucv_param)); 1034 memset(parm, 0, sizeof(union iucv_param));
1012 parm->db.ipbfadr1 = (u32)(addr_t) buffer; 1035 parm->db.ipbfadr1 = (u32)(addr_t) buffer;
@@ -1022,6 +1045,37 @@ int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
1022 if (residual) 1045 if (residual)
1023 *residual = parm->db.ipbfln1f; 1046 *residual = parm->db.ipbfln1f;
1024 } 1047 }
1048 return rc;
1049}
1050EXPORT_SYMBOL(__iucv_message_receive);
1051
1052/**
1053 * iucv_message_receive
1054 * @path: address of iucv path structure
1055 * @msg: address of iucv msg structure
1056 * @flags: how the message is received (IUCV_IPBUFLST)
1057 * @buffer: address of data buffer or address of struct iucv_array
1058 * @size: length of data buffer
1059 * @residual:
1060 *
1061 * This function receives messages that are being sent to you over
1062 * established paths. This function will deal with RMDATA messages
1063 * embedded in struct iucv_message as well.
1064 *
1065 * Locking: local_bh_enable/local_bh_disable
1066 *
1067 * Returns the result from the CP IUCV call.
1068 */
1069int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
1070 u8 flags, void *buffer, size_t size, size_t *residual)
1071{
1072 int rc;
1073
1074 if (msg->flags & IUCV_IPRMDATA)
1075 return iucv_message_receive_iprmdata(path, msg, flags,
1076 buffer, size, residual);
1077 local_bh_disable();
1078 rc = __iucv_message_receive(path, msg, flags, buffer, size, residual);
1025 local_bh_enable(); 1079 local_bh_enable();
1026 return rc; 1080 return rc;
1027} 1081}
@@ -1101,7 +1155,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
1101EXPORT_SYMBOL(iucv_message_reply); 1155EXPORT_SYMBOL(iucv_message_reply);
1102 1156
1103/** 1157/**
1104 * iucv_message_send 1158 * __iucv_message_send
1105 * @path: address of iucv path structure 1159 * @path: address of iucv path structure
1106 * @msg: address of iucv msg structure 1160 * @msg: address of iucv msg structure
1107 * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST) 1161 * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
@@ -1113,15 +1167,16 @@ EXPORT_SYMBOL(iucv_message_reply);
1113 * transmitted is in a buffer and this is a one-way message and the 1167 * transmitted is in a buffer and this is a one-way message and the
1114 * receiver will not reply to the message. 1168 * receiver will not reply to the message.
1115 * 1169 *
1170 * Locking: no locking
1171 *
1116 * Returns the result from the CP IUCV call. 1172 * Returns the result from the CP IUCV call.
1117 */ 1173 */
1118int iucv_message_send(struct iucv_path *path, struct iucv_message *msg, 1174int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
1119 u8 flags, u32 srccls, void *buffer, size_t size) 1175 u8 flags, u32 srccls, void *buffer, size_t size)
1120{ 1176{
1121 union iucv_param *parm; 1177 union iucv_param *parm;
1122 int rc; 1178 int rc;
1123 1179
1124 local_bh_disable();
1125 parm = iucv_param[smp_processor_id()]; 1180 parm = iucv_param[smp_processor_id()];
1126 memset(parm, 0, sizeof(union iucv_param)); 1181 memset(parm, 0, sizeof(union iucv_param));
1127 if (flags & IUCV_IPRMDATA) { 1182 if (flags & IUCV_IPRMDATA) {
@@ -1144,6 +1199,34 @@ int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
1144 rc = iucv_call_b2f0(IUCV_SEND, parm); 1199 rc = iucv_call_b2f0(IUCV_SEND, parm);
1145 if (!rc) 1200 if (!rc)
1146 msg->id = parm->db.ipmsgid; 1201 msg->id = parm->db.ipmsgid;
1202 return rc;
1203}
1204EXPORT_SYMBOL(__iucv_message_send);
1205
1206/**
1207 * iucv_message_send
1208 * @path: address of iucv path structure
1209 * @msg: address of iucv msg structure
1210 * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
1211 * @srccls: source class of message
1212 * @buffer: address of send buffer or address of struct iucv_array
1213 * @size: length of send buffer
1214 *
1215 * This function transmits data to another application. Data to be
1216 * transmitted is in a buffer and this is a one-way message and the
1217 * receiver will not reply to the message.
1218 *
1219 * Locking: local_bh_enable/local_bh_disable
1220 *
1221 * Returns the result from the CP IUCV call.
1222 */
1223int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
1224 u8 flags, u32 srccls, void *buffer, size_t size)
1225{
1226 int rc;
1227
1228 local_bh_disable();
1229 rc = __iucv_message_send(path, msg, flags, srccls, buffer, size);
1147 local_bh_enable(); 1230 local_bh_enable();
1148 return rc; 1231 return rc;
1149} 1232}
@@ -1572,7 +1655,7 @@ static void iucv_external_interrupt(u16 code)
1572 BUG_ON(p->iptype < 0x01 || p->iptype > 0x09); 1655 BUG_ON(p->iptype < 0x01 || p->iptype > 0x09);
1573 work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); 1656 work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC);
1574 if (!work) { 1657 if (!work) {
1575 printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); 1658 pr_warning("iucv_external_interrupt: out of memory\n");
1576 return; 1659 return;
1577 } 1660 }
1578 memcpy(&work->data, p, sizeof(work->data)); 1661 memcpy(&work->data, p, sizeof(work->data));