/* * Send a synchronous operation. This function is expected to * block, returning only when the response has arrived, (or when an * error is detected. The return value is the result of the * operation. */ int gb_operation_request_send_sync_timeout(struct gb_operation *operation, unsigned int timeout) { int ret; unsigned long timeout_jiffies; ret = gb_operation_request_send(operation, gb_operation_sync_callback, GFP_KERNEL); if (ret) return ret; if (timeout) timeout_jiffies = msecs_to_jiffies(timeout); else timeout_jiffies = MAX_SCHEDULE_TIMEOUT; ret = wait_for_completion_interruptible_timeout(&operation->completion, timeout_jiffies); if (ret < 0) { /* Cancel the operation if interrupted */ gb_operation_cancel(operation, -ECANCELED); } else if (ret == 0) { /* Cancel the operation if op timed out */ gb_operation_cancel(operation, -ETIMEDOUT); } return gb_operation_result(operation); }
/* * Cancel all active operations on a connection. * * Should only be called during connection tear down. */ static void gb_connection_cancel_operations(struct gb_connection *connection, int errno) { struct gb_operation *operation; spin_lock_irq(&connection->lock); while (!list_empty(&connection->operations)) { operation = list_last_entry(&connection->operations, struct gb_operation, links); gb_operation_get(operation); spin_unlock_irq(&connection->lock); if (gb_operation_is_incoming(operation)) gb_operation_cancel_incoming(operation, errno); else gb_operation_cancel(operation, errno); gb_operation_put(operation); spin_lock_irq(&connection->lock); } spin_unlock_irq(&connection->lock); }