-
- write_lock_irq(&adapter->request_queue.queue_lock);
- atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
- write_unlock_irq(&adapter->request_queue.queue_lock);
-
- debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
- while (qdio_shutdown(adapter->ccw_device,
- QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
- msleep(1000);
- debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
+ /* Note:
+ * We need the request_queue lock here, otherwise there exists the
+ * following race:
+ *
+ * queuecommand calls create_fcp_commmand_task...calls req_create,
+ * gets sbal x to x+y - meanwhile adapter reopen is called, completes
+ * - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices.
+ *
+ * with lock:
+ * queuecommand calls create_fcp_commmand_task...calls req_create,
+ * gets sbal x to x+y - meanwhile adapter reopen is called, waits
+ * - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices
+ * but do_QDIO fails as adapter_reopen is still waiting for the lock
+ * OR
+ * queuecommand calls create_fcp_commmand_task...calls req_create
+ * - meanwhile adapter reopen is called...completes,
+ * - gets sbal 0 to 0+y, - req_send calls do_QDIO for sbal 0 to 0+y,
+ * i.e. correct indices...though an fcp command is called before
+ * exchange config data...that should be fine, however
+ */
+ if (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR)) {
+ /*
+ * FIXME(design):
+ * What went wrong? What to do best? Proper retval?
+ */
+ ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed on "
+ "adapter %s\n",
+ zfcp_get_busid_by_adapter(adapter));
+ } else
+ ZFCP_LOG_DEBUG("queues cleaned up\n");