atomic_add(posted, &sc->recv_io.credits.available);
+ /*
+ * If the last send credit is waiting for credits
+ * it can grant we need to wake it up
+ */
+ if (posted &&
+ atomic_read(&sc->send_io.bcredits.count) == 0 &&
+ atomic_read(&sc->send_io.credits.count) == 0)
+ wake_up(&sc->send_io.credits.wait_queue);
+
/* Promptly send an immediate packet as defined in [MS-SMBD] 3.1.1.1 */
if (atomic_read(&sc->recv_io.credits.count) <
sc->recv_io.credits.target - 1) {
goto err_wait_credit;
}
+ new_credits = manage_credits_prior_sending(sc);
+ if (new_credits == 0 &&
+ atomic_read(&sc->send_io.credits.count) == 0 &&
+ atomic_read(&sc->recv_io.credits.count) == 0) {
+ queue_work(sc->workqueue, &sc->recv_io.posted.refill_work);
+ rc = wait_event_interruptible(sc->send_io.credits.wait_queue,
+ atomic_read(&sc->send_io.credits.count) >= 1 ||
+ atomic_read(&sc->recv_io.credits.available) >= 1 ||
+ sc->status != SMBDIRECT_SOCKET_CONNECTED);
+ if (sc->status != SMBDIRECT_SOCKET_CONNECTED)
+ rc = -ENOTCONN;
+ if (rc < 0) {
+ log_outgoing(ERR, "disconnected not sending on last credit\n");
+ rc = -EAGAIN;
+ goto err_wait_credit;
+ }
+
+ new_credits = manage_credits_prior_sending(sc);
+ }
+
request = smbd_alloc_send_io(sc);
if (IS_ERR(request)) {
rc = PTR_ERR(request);
/* Fill in the packet header */
packet->credits_requested = cpu_to_le16(sp->send_credit_target);
-
- new_credits = manage_credits_prior_sending(sc);
packet->credits_granted = cpu_to_le16(new_credits);
packet->flags = 0;