/* * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t * array in the adapter struct. * Cur_buf is the pointer array and count can be any number of required * buffers, the page-fitting arithmetic is done entirely within this funciton. * * returns: number of buffers allocated * locks: must only be called with zfcp_data.config_sema taken */ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **cur_buf, int count) { int buf_pos; int qdio_buffers_per_page; int page_pos = 0; struct qdio_buffer *first_in_page = NULL; qdio_buffers_per_page = PAGE_SIZE / sizeof (struct qdio_buffer); ZFCP_LOG_TRACE("buffers_per_page=%d\n", qdio_buffers_per_page); for (buf_pos = 0; buf_pos < count; buf_pos++) { if (page_pos == 0) { cur_buf[buf_pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL); if (cur_buf[buf_pos] == NULL) { ZFCP_LOG_INFO("error: allocation of " "QDIO buffer failed \n"); goto out; } first_in_page = cur_buf[buf_pos]; } else { cur_buf[buf_pos] = first_in_page + page_pos; } /* was initialised to zero */ page_pos++; page_pos %= qdio_buffers_per_page; } out: return buf_pos; }
/* * function: zfcp_qdio_handler_error_check * * purpose: called by the response handler to determine error condition * * returns: error flag * */ static int zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, unsigned int qdio_error, unsigned int siga_error, int first_element, int elements_processed) { int retval = 0; if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { retval = -EIO; ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, " "qdio_error=0x%x, siga_error=0x%x)\n", status, qdio_error, siga_error); zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error, first_element, elements_processed); /* * Restarting IO on the failed adapter from scratch. * Since we have been using this adapter, it is save to assume * that it is not failed but recoverable. The card seems to * report link-up events by self-initiated queue shutdown. * That is why we need to clear the link-down flag * which is set again in case we have missed by a mile. */ zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED, 140, NULL); } return retval; }
/* * function: zfcp_qdio_handler_error_check * * purpose: called by the response handler to determine error condition * * returns: error flag * */ static inline int zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, unsigned int qdio_error, unsigned int siga_error) { int retval = 0; if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) { if (status & QDIO_STATUS_INBOUND_INT) { ZFCP_LOG_TRACE("status is" " QDIO_STATUS_INBOUND_INT \n"); } if (status & QDIO_STATUS_OUTBOUND_INT) { ZFCP_LOG_TRACE("status is" " QDIO_STATUS_OUTBOUND_INT \n"); } } // if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { retval = -EIO; ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n"); ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, " "qdio_error=0x%x, siga_error=0x%x)\n", status, qdio_error, siga_error); if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n"); } if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n"); } if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n"); } if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) { ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n"); } if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) { ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n"); } switch (qdio_error) { case 0: ZFCP_LOG_FLAGS(3, "QDIO_OK"); break; case SLSB_P_INPUT_ERROR: ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n"); break; case SLSB_P_OUTPUT_ERROR: ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n"); break; default: ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n", qdio_error); break; } /* Restarting IO on the failed adapter from scratch */ debug_text_event(adapter->erp_dbf, 1, "qdio_err"); /* * Since we have been using this adapter, it is save to assume * that it is not failed but recoverable. The card seems to * report link-up events by self-initiated queue shutdown. * That is why we need to clear the the link-down flag * which is set again in case we have missed by a mile. */ zfcp_erp_adapter_reopen( adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED); } return retval; }