{
struct ap_queue_status status;
+ if (msg == NULL)
+ return -EINVAL;
status = __ap_recv(qid, psmid, msg, length);
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
{
struct ap_queue_status status;
+ if (!ap_dev->reply)
+ return AP_WAIT_NONE;
status = ap_sm_recv(ap_dev);
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
}
}
+/**
+ * ap_sm_suspend_read(): Receive pending reply messages from an AP device
+ * without changing the device state in between. In suspend mode we don't
+ * allow sending new requests, therefore just fetch pending replies.
+ * @ap_dev: pointer to the AP device
+ *
+ * Returns AP_WAIT_NONE or AP_WAIT_AGAIN
+ */
+static enum ap_wait ap_sm_suspend_read(struct ap_device *ap_dev)
+{
+ struct ap_queue_status status;
+
+ if (!ap_dev->reply)
+ return AP_WAIT_NONE;
+ status = ap_sm_recv(ap_dev);
+ switch (status.response_code) {
+ case AP_RESPONSE_NORMAL:
+ if (ap_dev->queue_count > 0)
+ return AP_WAIT_AGAIN;
+ /* fall through */
+ default:
+ return AP_WAIT_NONE;
+ }
+}
+
/**
* ap_sm_write(): Send messages from the request queue to an AP device.
* @ap_dev: pointer to the AP device
struct ap_queue_status status;
unsigned long info;
- if (ap_dev->queue_count > 0)
+ if (ap_dev->queue_count > 0 && ap_dev->reply)
/* Try to read a completed message and get the status */
status = ap_sm_recv(ap_dev);
else
struct ap_queue_status status;
unsigned long info;
- if (ap_dev->queue_count > 0)
+ if (ap_dev->queue_count > 0 && ap_dev->reply)
/* Try to read a completed message and get the status */
status = ap_sm_recv(ap_dev);
else
[AP_EVENT_TIMEOUT] = ap_sm_reset,
},
[AP_STATE_SUSPEND_WAIT] = {
- [AP_EVENT_POLL] = ap_sm_read,
+ [AP_EVENT_POLL] = ap_sm_suspend_read,
[AP_EVENT_TIMEOUT] = ap_sm_nop,
},
[AP_STATE_BORKED] = {
.resume = ap_dev_resume,
};
+void ap_device_init_reply(struct ap_device *ap_dev,
+ struct ap_message *reply)
+{
+ ap_dev->reply = reply;
+
+ spin_lock_bh(&ap_dev->lock);
+ ap_sm_wait(ap_sm_event(ap_dev, AP_EVENT_POLL));
+ spin_unlock_bh(&ap_dev->lock);
+}
+EXPORT_SYMBOL(ap_device_init_reply);
+
static int ap_device_probe(struct device *dev)
{
struct ap_device *ap_dev = to_ap_dev(dev);