|
@@ -957,7 +957,52 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
|
|
EXPORT_SYMBOL(iucv_message_purge);
|
|
EXPORT_SYMBOL(iucv_message_purge);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * iucv_message_receive
|
|
|
|
|
|
+ * iucv_message_receive_iprmdata
|
|
|
|
+ * @path: address of iucv path structure
|
|
|
|
+ * @msg: address of iucv msg structure
|
|
|
|
+ * @flags: how the message is received (IUCV_IPBUFLST)
|
|
|
|
+ * @buffer: address of data buffer or address of struct iucv_array
|
|
|
|
+ * @size: length of data buffer
|
|
|
|
+ * @residual:
|
|
|
|
+ *
|
|
|
|
+ * Internal function used by iucv_message_receive and __iucv_message_receive
|
|
|
|
+ * to receive RMDATA data stored in struct iucv_message.
|
|
|
|
+ */
|
|
|
|
+static int iucv_message_receive_iprmdata(struct iucv_path *path,
|
|
|
|
+ struct iucv_message *msg,
|
|
|
|
+ u8 flags, void *buffer,
|
|
|
|
+ size_t size, size_t *residual)
|
|
|
|
+{
|
|
|
|
+ struct iucv_array *array;
|
|
|
|
+ u8 *rmmsg;
|
|
|
|
+ size_t copy;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Message is 8 bytes long and has been stored to the
|
|
|
|
+ * message descriptor itself.
|
|
|
|
+ */
|
|
|
|
+ if (residual)
|
|
|
|
+ *residual = abs(size - 8);
|
|
|
|
+ rmmsg = msg->rmmsg;
|
|
|
|
+ if (flags & IUCV_IPBUFLST) {
|
|
|
|
+ /* Copy to struct iucv_array. */
|
|
|
|
+ size = (size < 8) ? size : 8;
|
|
|
|
+ for (array = buffer; size > 0; array++) {
|
|
|
|
+ copy = min_t(size_t, size, array->length);
|
|
|
|
+ memcpy((u8 *)(addr_t) array->address,
|
|
|
|
+ rmmsg, copy);
|
|
|
|
+ rmmsg += copy;
|
|
|
|
+ size -= copy;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ /* Copy to direct buffer. */
|
|
|
|
+ memcpy(buffer, rmmsg, min_t(size_t, size, 8));
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * __iucv_message_receive
|
|
* @path: address of iucv path structure
|
|
* @path: address of iucv path structure
|
|
* @msg: address of iucv msg structure
|
|
* @msg: address of iucv msg structure
|
|
* @flags: how the message is received (IUCV_IPBUFLST)
|
|
* @flags: how the message is received (IUCV_IPBUFLST)
|
|
@@ -969,44 +1014,19 @@ EXPORT_SYMBOL(iucv_message_purge);
|
|
* established paths. This function will deal with RMDATA messages
|
|
* established paths. This function will deal with RMDATA messages
|
|
* embedded in struct iucv_message as well.
|
|
* embedded in struct iucv_message as well.
|
|
*
|
|
*
|
|
|
|
+ * Locking: no locking
|
|
|
|
+ *
|
|
* Returns the result from the CP IUCV call.
|
|
* Returns the result from the CP IUCV call.
|
|
*/
|
|
*/
|
|
-int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
|
|
|
|
- u8 flags, void *buffer, size_t size, size_t *residual)
|
|
|
|
|
|
+int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
|
|
|
|
+ u8 flags, void *buffer, size_t size, size_t *residual)
|
|
{
|
|
{
|
|
union iucv_param *parm;
|
|
union iucv_param *parm;
|
|
- struct iucv_array *array;
|
|
|
|
- u8 *rmmsg;
|
|
|
|
- size_t copy;
|
|
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
- if (msg->flags & IUCV_IPRMDATA) {
|
|
|
|
- /*
|
|
|
|
- * Message is 8 bytes long and has been stored to the
|
|
|
|
- * message descriptor itself.
|
|
|
|
- */
|
|
|
|
- rc = (size < 8) ? 5 : 0;
|
|
|
|
- if (residual)
|
|
|
|
- *residual = abs(size - 8);
|
|
|
|
- rmmsg = msg->rmmsg;
|
|
|
|
- if (flags & IUCV_IPBUFLST) {
|
|
|
|
- /* Copy to struct iucv_array. */
|
|
|
|
- size = (size < 8) ? size : 8;
|
|
|
|
- for (array = buffer; size > 0; array++) {
|
|
|
|
- copy = min_t(size_t, size, array->length);
|
|
|
|
- memcpy((u8 *)(addr_t) array->address,
|
|
|
|
- rmmsg, copy);
|
|
|
|
- rmmsg += copy;
|
|
|
|
- size -= copy;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- /* Copy to direct buffer. */
|
|
|
|
- memcpy(buffer, rmmsg, min_t(size_t, size, 8));
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- local_bh_disable();
|
|
|
|
|
|
+ if (msg->flags & IUCV_IPRMDATA)
|
|
|
|
+ return iucv_message_receive_iprmdata(path, msg, flags,
|
|
|
|
+ buffer, size, residual);
|
|
parm = iucv_param[smp_processor_id()];
|
|
parm = iucv_param[smp_processor_id()];
|
|
memset(parm, 0, sizeof(union iucv_param));
|
|
memset(parm, 0, sizeof(union iucv_param));
|
|
parm->db.ipbfadr1 = (u32)(addr_t) buffer;
|
|
parm->db.ipbfadr1 = (u32)(addr_t) buffer;
|
|
@@ -1022,6 +1042,37 @@ int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
|
|
if (residual)
|
|
if (residual)
|
|
*residual = parm->db.ipbfln1f;
|
|
*residual = parm->db.ipbfln1f;
|
|
}
|
|
}
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(__iucv_message_receive);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * iucv_message_receive
|
|
|
|
+ * @path: address of iucv path structure
|
|
|
|
+ * @msg: address of iucv msg structure
|
|
|
|
+ * @flags: how the message is received (IUCV_IPBUFLST)
|
|
|
|
+ * @buffer: address of data buffer or address of struct iucv_array
|
|
|
|
+ * @size: length of data buffer
|
|
|
|
+ * @residual:
|
|
|
|
+ *
|
|
|
|
+ * This function receives messages that are being sent to you over
|
|
|
|
+ * established paths. This function will deal with RMDATA messages
|
|
|
|
+ * embedded in struct iucv_message as well.
|
|
|
|
+ *
|
|
|
|
+ * Locking: local_bh_enable/local_bh_disable
|
|
|
|
+ *
|
|
|
|
+ * Returns the result from the CP IUCV call.
|
|
|
|
+ */
|
|
|
|
+int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
|
|
|
|
+ u8 flags, void *buffer, size_t size, size_t *residual)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ if (msg->flags & IUCV_IPRMDATA)
|
|
|
|
+ return iucv_message_receive_iprmdata(path, msg, flags,
|
|
|
|
+ buffer, size, residual);
|
|
|
|
+ local_bh_disable();
|
|
|
|
+ rc = __iucv_message_receive(path, msg, flags, buffer, size, residual);
|
|
local_bh_enable();
|
|
local_bh_enable();
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
@@ -1101,7 +1152,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
|
|
EXPORT_SYMBOL(iucv_message_reply);
|
|
EXPORT_SYMBOL(iucv_message_reply);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * iucv_message_send
|
|
|
|
|
|
+ * __iucv_message_send
|
|
* @path: address of iucv path structure
|
|
* @path: address of iucv path structure
|
|
* @msg: address of iucv msg structure
|
|
* @msg: address of iucv msg structure
|
|
* @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
|
|
* @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
|
|
@@ -1113,15 +1164,16 @@ EXPORT_SYMBOL(iucv_message_reply);
|
|
* transmitted is in a buffer and this is a one-way message and the
|
|
* transmitted is in a buffer and this is a one-way message and the
|
|
* receiver will not reply to the message.
|
|
* receiver will not reply to the message.
|
|
*
|
|
*
|
|
|
|
+ * Locking: no locking
|
|
|
|
+ *
|
|
* Returns the result from the CP IUCV call.
|
|
* Returns the result from the CP IUCV call.
|
|
*/
|
|
*/
|
|
-int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
|
|
|
|
|
|
+int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
|
|
u8 flags, u32 srccls, void *buffer, size_t size)
|
|
u8 flags, u32 srccls, void *buffer, size_t size)
|
|
{
|
|
{
|
|
union iucv_param *parm;
|
|
union iucv_param *parm;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
- local_bh_disable();
|
|
|
|
parm = iucv_param[smp_processor_id()];
|
|
parm = iucv_param[smp_processor_id()];
|
|
memset(parm, 0, sizeof(union iucv_param));
|
|
memset(parm, 0, sizeof(union iucv_param));
|
|
if (flags & IUCV_IPRMDATA) {
|
|
if (flags & IUCV_IPRMDATA) {
|
|
@@ -1144,6 +1196,34 @@ int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
|
|
rc = iucv_call_b2f0(IUCV_SEND, parm);
|
|
rc = iucv_call_b2f0(IUCV_SEND, parm);
|
|
if (!rc)
|
|
if (!rc)
|
|
msg->id = parm->db.ipmsgid;
|
|
msg->id = parm->db.ipmsgid;
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(__iucv_message_send);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * iucv_message_send
|
|
|
|
+ * @path: address of iucv path structure
|
|
|
|
+ * @msg: address of iucv msg structure
|
|
|
|
+ * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
|
|
|
|
+ * @srccls: source class of message
|
|
|
|
+ * @buffer: address of send buffer or address of struct iucv_array
|
|
|
|
+ * @size: length of send buffer
|
|
|
|
+ *
|
|
|
|
+ * This function transmits data to another application. Data to be
|
|
|
|
+ * transmitted is in a buffer and this is a one-way message and the
|
|
|
|
+ * receiver will not reply to the message.
|
|
|
|
+ *
|
|
|
|
+ * Locking: local_bh_enable/local_bh_disable
|
|
|
|
+ *
|
|
|
|
+ * Returns the result from the CP IUCV call.
|
|
|
|
+ */
|
|
|
|
+int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
|
|
|
|
+ u8 flags, u32 srccls, void *buffer, size_t size)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ local_bh_disable();
|
|
|
|
+ rc = __iucv_message_send(path, msg, flags, srccls, buffer, size);
|
|
local_bh_enable();
|
|
local_bh_enable();
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|