| From 5cef2384c1f080e5b10e95d18285a89c80cb4a9c Mon Sep 17 00:00:00 2001 |
| From: Michael Cyr <mikecyr@us.ibm.com> |
| Date: Thu, 13 Oct 2016 11:02:38 -0500 |
| Subject: [PATCH] scsi: ibmvscsis: Rearrange functions for future patches |
| |
| commit 79fac9c9b74f4951c9ce82b22e714bcc34ae4a56 upstream. |
| |
| This patch reorders functions in a manner necessary for a follow-on |
| patch. It also makes some minor styling changes (mostly removing extra |
| spaces) and fixes some typos. |
| |
| There are no code changes in this patch, with one exception: due to the |
| reordering of the functions, I needed to explicitly declare a function |
| at the top of the file. However, this will be removed in the next patch, |
| since the code requiring the predeclaration will be removed. |
| |
| Signed-off-by: Michael Cyr <mikecyr@us.ibm.com> |
| Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com> |
| Tested-by: Steven Royer <seroyer@linux.vnet.ibm.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
| index 55ce61f9c632..392723bd5fea 100644 |
| --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
| +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |
| @@ -22,7 +22,7 @@ |
| * |
| ****************************************************************************/ |
| |
| -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| |
| #include <linux/module.h> |
| #include <linux/kernel.h> |
| @@ -62,6 +62,8 @@ static long ibmvscsis_parse_command(struct scsi_info *vscsi, |
| |
| static void ibmvscsis_adapter_idle(struct scsi_info *vscsi); |
| |
| +static void ibmvscsis_reset_queue(struct scsi_info *vscsi, uint new_state); |
| + |
| static void ibmvscsis_determine_resid(struct se_cmd *se_cmd, |
| struct srp_rsp *rsp) |
| { |
| @@ -82,7 +84,7 @@ static void ibmvscsis_determine_resid(struct se_cmd *se_cmd, |
| } |
| } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { |
| if (se_cmd->data_direction == DMA_TO_DEVICE) { |
| - /* residual data from an overflow write */ |
| + /* residual data from an overflow write */ |
| rsp->flags = SRP_RSP_FLAG_DOOVER; |
| rsp->data_out_res_cnt = cpu_to_be32(residual_count); |
| } else if (se_cmd->data_direction == DMA_FROM_DEVICE) { |
| @@ -102,7 +104,7 @@ static void ibmvscsis_determine_resid(struct se_cmd *se_cmd, |
| * and the function returns TRUE. |
| * |
| * EXECUTION ENVIRONMENT: |
| - * Interrupt or Process environment |
| + * Interrupt or Process environment |
| */ |
| static bool connection_broken(struct scsi_info *vscsi) |
| { |
| @@ -325,7 +327,7 @@ static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask, |
| } |
| |
| /** |
| - * ibmvscsis_send_init_message() - send initialize message to the client |
| + * ibmvscsis_send_init_message() - send initialize message to the client |
| * @vscsi: Pointer to our adapter structure |
| * @format: Which Init Message format to send |
| * |
| @@ -383,13 +385,13 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format) |
| vscsi->cmd_q.base_addr); |
| if (crq) { |
| *format = (uint)(crq->format); |
| - rc = ERROR; |
| + rc = ERROR; |
| crq->valid = INVALIDATE_CMD_RESP_EL; |
| dma_rmb(); |
| } |
| } else { |
| *format = (uint)(crq->format); |
| - rc = ERROR; |
| + rc = ERROR; |
| crq->valid = INVALIDATE_CMD_RESP_EL; |
| dma_rmb(); |
| } |
| @@ -398,166 +400,6 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format) |
| } |
| |
| /** |
| - * ibmvscsis_establish_new_q() - Establish new CRQ queue |
| - * @vscsi: Pointer to our adapter structure |
| - * @new_state: New state being established after resetting the queue |
| - * |
| - * Must be called with interrupt lock held. |
| - */ |
| -static long ibmvscsis_establish_new_q(struct scsi_info *vscsi, uint new_state) |
| -{ |
| - long rc = ADAPT_SUCCESS; |
| - uint format; |
| - |
| - vscsi->flags &= PRESERVE_FLAG_FIELDS; |
| - vscsi->rsp_q_timer.timer_pops = 0; |
| - vscsi->debit = 0; |
| - vscsi->credit = 0; |
| - |
| - rc = vio_enable_interrupts(vscsi->dma_dev); |
| - if (rc) { |
| - pr_warn("reset_queue: failed to enable interrupts, rc %ld\n", |
| - rc); |
| - return rc; |
| - } |
| - |
| - rc = ibmvscsis_check_init_msg(vscsi, &format); |
| - if (rc) { |
| - dev_err(&vscsi->dev, "reset_queue: check_init_msg failed, rc %ld\n", |
| - rc); |
| - return rc; |
| - } |
| - |
| - if (format == UNUSED_FORMAT && new_state == WAIT_CONNECTION) { |
| - rc = ibmvscsis_send_init_message(vscsi, INIT_MSG); |
| - switch (rc) { |
| - case H_SUCCESS: |
| - case H_DROPPED: |
| - case H_CLOSED: |
| - rc = ADAPT_SUCCESS; |
| - break; |
| - |
| - case H_PARAMETER: |
| - case H_HARDWARE: |
| - break; |
| - |
| - default: |
| - vscsi->state = UNDEFINED; |
| - rc = H_HARDWARE; |
| - break; |
| - } |
| - } |
| - |
| - return rc; |
| -} |
| - |
| -/** |
| - * ibmvscsis_reset_queue() - Reset CRQ Queue |
| - * @vscsi: Pointer to our adapter structure |
| - * @new_state: New state to establish after resetting the queue |
| - * |
| - * This function calls h_free_q and then calls h_reg_q and does all |
| - * of the bookkeeping to get us back to where we can communicate. |
| - * |
| - * Actually, we don't always call h_free_crq. A problem was discovered |
| - * where one partition would close and reopen his queue, which would |
| - * cause his partner to get a transport event, which would cause him to |
| - * close and reopen his queue, which would cause the original partition |
| - * to get a transport event, etc., etc. To prevent this, we don't |
| - * actually close our queue if the client initiated the reset, (i.e. |
| - * either we got a transport event or we have detected that the client's |
| - * queue is gone) |
| - * |
| - * EXECUTION ENVIRONMENT: |
| - * Process environment, called with interrupt lock held |
| - */ |
| -static void ibmvscsis_reset_queue(struct scsi_info *vscsi, uint new_state) |
| -{ |
| - int bytes; |
| - long rc = ADAPT_SUCCESS; |
| - |
| - pr_debug("reset_queue: flags 0x%x\n", vscsi->flags); |
| - |
| - /* don't reset, the client did it for us */ |
| - if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) { |
| - vscsi->flags &= PRESERVE_FLAG_FIELDS; |
| - vscsi->rsp_q_timer.timer_pops = 0; |
| - vscsi->debit = 0; |
| - vscsi->credit = 0; |
| - vscsi->state = new_state; |
| - vio_enable_interrupts(vscsi->dma_dev); |
| - } else { |
| - rc = ibmvscsis_free_command_q(vscsi); |
| - if (rc == ADAPT_SUCCESS) { |
| - vscsi->state = new_state; |
| - |
| - bytes = vscsi->cmd_q.size * PAGE_SIZE; |
| - rc = h_reg_crq(vscsi->dds.unit_id, |
| - vscsi->cmd_q.crq_token, bytes); |
| - if (rc == H_CLOSED || rc == H_SUCCESS) { |
| - rc = ibmvscsis_establish_new_q(vscsi, |
| - new_state); |
| - } |
| - |
| - if (rc != ADAPT_SUCCESS) { |
| - pr_debug("reset_queue: reg_crq rc %ld\n", rc); |
| - |
| - vscsi->state = ERR_DISCONNECTED; |
| - vscsi->flags |= RESPONSE_Q_DOWN; |
| - ibmvscsis_free_command_q(vscsi); |
| - } |
| - } else { |
| - vscsi->state = ERR_DISCONNECTED; |
| - vscsi->flags |= RESPONSE_Q_DOWN; |
| - } |
| - } |
| -} |
| - |
| -/** |
| - * ibmvscsis_free_cmd_resources() - Free command resources |
| - * @vscsi: Pointer to our adapter structure |
| - * @cmd: Command which is not longer in use |
| - * |
| - * Must be called with interrupt lock held. |
| - */ |
| -static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi, |
| - struct ibmvscsis_cmd *cmd) |
| -{ |
| - struct iu_entry *iue = cmd->iue; |
| - |
| - switch (cmd->type) { |
| - case TASK_MANAGEMENT: |
| - case SCSI_CDB: |
| - /* |
| - * When the queue goes down this value is cleared, so it |
| - * cannot be cleared in this general purpose function. |
| - */ |
| - if (vscsi->debit) |
| - vscsi->debit -= 1; |
| - break; |
| - case ADAPTER_MAD: |
| - vscsi->flags &= ~PROCESSING_MAD; |
| - break; |
| - case UNSET_TYPE: |
| - break; |
| - default: |
| - dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n", |
| - cmd->type); |
| - break; |
| - } |
| - |
| - cmd->iue = NULL; |
| - list_add_tail(&cmd->list, &vscsi->free_cmd); |
| - srp_iu_put(iue); |
| - |
| - if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) && |
| - list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) { |
| - vscsi->flags &= ~WAIT_FOR_IDLE; |
| - complete(&vscsi->wait_idle); |
| - } |
| -} |
| - |
| -/** |
| * ibmvscsis_disconnect() - Helper function to disconnect |
| * @work: Pointer to work_struct, gives access to our adapter structure |
| * |
| @@ -590,7 +432,7 @@ static void ibmvscsis_disconnect(struct work_struct *work) |
| * should transitition to the new state |
| */ |
| switch (vscsi->state) { |
| - /* Should never be called while in this state. */ |
| + /* Should never be called while in this state. */ |
| case NO_QUEUE: |
| /* |
| * Can never transition from this state; |
| @@ -726,84 +568,394 @@ static void ibmvscsis_disconnect(struct work_struct *work) |
| * the new state (if the one passed in is more "severe" than the |
| * previous one). |
| * |
| - * PRECONDITION: |
| - * interrupt lock is held |
| + * PRECONDITION: |
| + * interrupt lock is held |
| + */ |
| +static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state, |
| + uint flag_bits) |
| +{ |
| + uint state; |
| + |
| + /* check the validity of the new state */ |
| + switch (new_state) { |
| + case UNCONFIGURING: |
| + case ERR_DISCONNECT: |
| + case ERR_DISCONNECT_RECONNECT: |
| + case WAIT_IDLE: |
| + break; |
| + |
| + default: |
| + dev_err(&vscsi->dev, "post_disconnect: Invalid new state %d\n", |
| + new_state); |
| + return; |
| + } |
| + |
| + vscsi->flags |= flag_bits; |
| + |
| + pr_debug("post_disconnect: new_state 0x%x, flag_bits 0x%x, vscsi->flags 0x%x, state %hx\n", |
| + new_state, flag_bits, vscsi->flags, vscsi->state); |
| + |
| + if (!(vscsi->flags & (DISCONNECT_SCHEDULED | SCHEDULE_DISCONNECT))) { |
| + vscsi->flags |= SCHEDULE_DISCONNECT; |
| + vscsi->new_state = new_state; |
| + |
| + INIT_WORK(&vscsi->proc_work, ibmvscsis_disconnect); |
| + (void)queue_work(vscsi->work_q, &vscsi->proc_work); |
| + } else { |
| + if (vscsi->new_state) |
| + state = vscsi->new_state; |
| + else |
| + state = vscsi->state; |
| + |
| + switch (state) { |
| + case NO_QUEUE: |
| + case UNCONFIGURING: |
| + break; |
| + |
| + case ERR_DISCONNECTED: |
| + case ERR_DISCONNECT: |
| + case UNDEFINED: |
| + if (new_state == UNCONFIGURING) |
| + vscsi->new_state = new_state; |
| + break; |
| + |
| + case ERR_DISCONNECT_RECONNECT: |
| + switch (new_state) { |
| + case UNCONFIGURING: |
| + case ERR_DISCONNECT: |
| + vscsi->new_state = new_state; |
| + break; |
| + default: |
| + break; |
| + } |
| + break; |
| + |
| + case WAIT_ENABLED: |
| + case PART_UP_WAIT_ENAB: |
| + case WAIT_IDLE: |
| + case WAIT_CONNECTION: |
| + case CONNECTED: |
| + case SRP_PROCESSING: |
| + vscsi->new_state = new_state; |
| + break; |
| + |
| + default: |
| + break; |
| + } |
| + } |
| + |
| + pr_debug("Leaving post_disconnect: flags 0x%x, new_state 0x%x\n", |
| + vscsi->flags, vscsi->new_state); |
| +} |
| + |
| +/** |
| + * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message |
| + * @vscsi: Pointer to our adapter structure |
| + * |
| + * Must be called with interrupt lock held. |
| + */ |
| +static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi) |
| +{ |
| + long rc = ADAPT_SUCCESS; |
| + |
| + switch (vscsi->state) { |
| + case NO_QUEUE: |
| + case ERR_DISCONNECT: |
| + case ERR_DISCONNECT_RECONNECT: |
| + case ERR_DISCONNECTED: |
| + case UNCONFIGURING: |
| + case UNDEFINED: |
| + rc = ERROR; |
| + break; |
| + |
| + case WAIT_CONNECTION: |
| + vscsi->state = CONNECTED; |
| + break; |
| + |
| + case WAIT_IDLE: |
| + case SRP_PROCESSING: |
| + case CONNECTED: |
| + case WAIT_ENABLED: |
| + case PART_UP_WAIT_ENAB: |
| + default: |
| + rc = ERROR; |
| + dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n", |
| + vscsi->state); |
| + ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| + break; |
| + } |
| + |
| + return rc; |
| +} |
| + |
| +/** |
| + * ibmvscsis_handle_init_msg() - Respond to an Init Message |
| + * @vscsi: Pointer to our adapter structure |
| + * |
| + * Must be called with interrupt lock held. |
| + */ |
| +static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi) |
| +{ |
| + long rc = ADAPT_SUCCESS; |
| + |
| + switch (vscsi->state) { |
| + case WAIT_ENABLED: |
| + vscsi->state = PART_UP_WAIT_ENAB; |
| + break; |
| + |
| + case WAIT_CONNECTION: |
| + rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG); |
| + switch (rc) { |
| + case H_SUCCESS: |
| + vscsi->state = CONNECTED; |
| + break; |
| + |
| + case H_PARAMETER: |
| + dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n", |
| + rc); |
| + ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0); |
| + break; |
| + |
| + case H_DROPPED: |
| + dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n", |
| + rc); |
| + rc = ERROR; |
| + ibmvscsis_post_disconnect(vscsi, |
| + ERR_DISCONNECT_RECONNECT, 0); |
| + break; |
| + |
| + case H_CLOSED: |
| + pr_warn("init_msg: failed to send, rc %ld\n", rc); |
| + rc = 0; |
| + break; |
| + } |
| + break; |
| + |
| + case UNDEFINED: |
| + rc = ERROR; |
| + break; |
| + |
| + case UNCONFIGURING: |
| + break; |
| + |
| + case PART_UP_WAIT_ENAB: |
| + case CONNECTED: |
| + case SRP_PROCESSING: |
| + case WAIT_IDLE: |
| + case NO_QUEUE: |
| + case ERR_DISCONNECT: |
| + case ERR_DISCONNECT_RECONNECT: |
| + case ERR_DISCONNECTED: |
| + default: |
| + rc = ERROR; |
| + dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n", |
| + vscsi->state); |
| + ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| + break; |
| + } |
| + |
| + return rc; |
| +} |
| + |
| +/** |
| + * ibmvscsis_init_msg() - Respond to an init message |
| + * @vscsi: Pointer to our adapter structure |
| + * @crq: Pointer to CRQ element containing the Init Message |
| + * |
| + * EXECUTION ENVIRONMENT: |
| + * Interrupt, interrupt lock held |
| + */ |
| +static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq) |
| +{ |
| + long rc = ADAPT_SUCCESS; |
| + |
| + pr_debug("init_msg: state 0x%hx\n", vscsi->state); |
| + |
| + rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO, |
| + (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0, |
| + 0); |
| + if (rc == H_SUCCESS) { |
| + vscsi->client_data.partition_number = |
| + be64_to_cpu(*(u64 *)vscsi->map_buf); |
| + pr_debug("init_msg, part num %d\n", |
| + vscsi->client_data.partition_number); |
| + } else { |
| + pr_debug("init_msg h_vioctl rc %ld\n", rc); |
| + rc = ADAPT_SUCCESS; |
| + } |
| + |
| + if (crq->format == INIT_MSG) { |
| + rc = ibmvscsis_handle_init_msg(vscsi); |
| + } else if (crq->format == INIT_COMPLETE_MSG) { |
| + rc = ibmvscsis_handle_init_compl_msg(vscsi); |
| + } else { |
| + rc = ERROR; |
| + dev_err(&vscsi->dev, "init_msg: invalid format %d\n", |
| + (uint)crq->format); |
| + ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| + } |
| + |
| + return rc; |
| +} |
| + |
| +/** |
| + * ibmvscsis_establish_new_q() - Establish new CRQ queue |
| + * @vscsi: Pointer to our adapter structure |
| + * @new_state: New state being established after resetting the queue |
| + * |
| + * Must be called with interrupt lock held. |
| + */ |
| +static long ibmvscsis_establish_new_q(struct scsi_info *vscsi, uint new_state) |
| +{ |
| + long rc = ADAPT_SUCCESS; |
| + uint format; |
| + |
| + vscsi->flags &= PRESERVE_FLAG_FIELDS; |
| + vscsi->rsp_q_timer.timer_pops = 0; |
| + vscsi->debit = 0; |
| + vscsi->credit = 0; |
| + |
| + rc = vio_enable_interrupts(vscsi->dma_dev); |
| + if (rc) { |
| + pr_warn("reset_queue: failed to enable interrupts, rc %ld\n", |
| + rc); |
| + return rc; |
| + } |
| + |
| + rc = ibmvscsis_check_init_msg(vscsi, &format); |
| + if (rc) { |
| + dev_err(&vscsi->dev, "reset_queue: check_init_msg failed, rc %ld\n", |
| + rc); |
| + return rc; |
| + } |
| + |
| + if (format == UNUSED_FORMAT && new_state == WAIT_CONNECTION) { |
| + rc = ibmvscsis_send_init_message(vscsi, INIT_MSG); |
| + switch (rc) { |
| + case H_SUCCESS: |
| + case H_DROPPED: |
| + case H_CLOSED: |
| + rc = ADAPT_SUCCESS; |
| + break; |
| + |
| + case H_PARAMETER: |
| + case H_HARDWARE: |
| + break; |
| + |
| + default: |
| + vscsi->state = UNDEFINED; |
| + rc = H_HARDWARE; |
| + break; |
| + } |
| + } |
| + |
| + return rc; |
| +} |
| + |
| +/** |
| + * ibmvscsis_reset_queue() - Reset CRQ Queue |
| + * @vscsi: Pointer to our adapter structure |
| + * @new_state: New state to establish after resetting the queue |
| + * |
| + * This function calls h_free_q and then calls h_reg_q and does all |
| + * of the bookkeeping to get us back to where we can communicate. |
| + * |
| + * Actually, we don't always call h_free_crq. A problem was discovered |
| + * where one partition would close and reopen his queue, which would |
| + * cause his partner to get a transport event, which would cause him to |
| + * close and reopen his queue, which would cause the original partition |
| + * to get a transport event, etc., etc. To prevent this, we don't |
| + * actually close our queue if the client initiated the reset, (i.e. |
| + * either we got a transport event or we have detected that the client's |
| + * queue is gone) |
| + * |
| + * EXECUTION ENVIRONMENT: |
| + * Process environment, called with interrupt lock held |
| + */ |
| +static void ibmvscsis_reset_queue(struct scsi_info *vscsi, uint new_state) |
| +{ |
| + int bytes; |
| + long rc = ADAPT_SUCCESS; |
| + |
| + pr_debug("reset_queue: flags 0x%x\n", vscsi->flags); |
| + |
| + /* don't reset, the client did it for us */ |
| + if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) { |
| + vscsi->flags &= PRESERVE_FLAG_FIELDS; |
| + vscsi->rsp_q_timer.timer_pops = 0; |
| + vscsi->debit = 0; |
| + vscsi->credit = 0; |
| + vscsi->state = new_state; |
| + vio_enable_interrupts(vscsi->dma_dev); |
| + } else { |
| + rc = ibmvscsis_free_command_q(vscsi); |
| + if (rc == ADAPT_SUCCESS) { |
| + vscsi->state = new_state; |
| + |
| + bytes = vscsi->cmd_q.size * PAGE_SIZE; |
| + rc = h_reg_crq(vscsi->dds.unit_id, |
| + vscsi->cmd_q.crq_token, bytes); |
| + if (rc == H_CLOSED || rc == H_SUCCESS) { |
| + rc = ibmvscsis_establish_new_q(vscsi, |
| + new_state); |
| + } |
| + |
| + if (rc != ADAPT_SUCCESS) { |
| + pr_debug("reset_queue: reg_crq rc %ld\n", rc); |
| + |
| + vscsi->state = ERR_DISCONNECTED; |
| + vscsi->flags |= RESPONSE_Q_DOWN; |
| + ibmvscsis_free_command_q(vscsi); |
| + } |
| + } else { |
| + vscsi->state = ERR_DISCONNECTED; |
| + vscsi->flags |= RESPONSE_Q_DOWN; |
| + } |
| + } |
| +} |
| + |
| +/** |
| + * ibmvscsis_free_cmd_resources() - Free command resources |
| + * @vscsi: Pointer to our adapter structure |
| + * @cmd: Command which is not longer in use |
| + * |
| + * Must be called with interrupt lock held. |
| */ |
| -static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state, |
| - uint flag_bits) |
| +static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi, |
| + struct ibmvscsis_cmd *cmd) |
| { |
| - uint state; |
| + struct iu_entry *iue = cmd->iue; |
| |
| - /* check the validity of the new state */ |
| - switch (new_state) { |
| - case UNCONFIGURING: |
| - case ERR_DISCONNECT: |
| - case ERR_DISCONNECT_RECONNECT: |
| - case WAIT_IDLE: |
| + switch (cmd->type) { |
| + case TASK_MANAGEMENT: |
| + case SCSI_CDB: |
| + /* |
| + * When the queue goes down this value is cleared, so it |
| + * cannot be cleared in this general purpose function. |
| + */ |
| + if (vscsi->debit) |
| + vscsi->debit -= 1; |
| + break; |
| + case ADAPTER_MAD: |
| + vscsi->flags &= ~PROCESSING_MAD; |
| + break; |
| + case UNSET_TYPE: |
| break; |
| - |
| default: |
| - dev_err(&vscsi->dev, "post_disconnect: Invalid new state %d\n", |
| - new_state); |
| - return; |
| + dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n", |
| + cmd->type); |
| + break; |
| } |
| |
| - vscsi->flags |= flag_bits; |
| - |
| - pr_debug("post_disconnect: new_state 0x%x, flag_bits 0x%x, vscsi->flags 0x%x, state %hx\n", |
| - new_state, flag_bits, vscsi->flags, vscsi->state); |
| - |
| - if (!(vscsi->flags & (DISCONNECT_SCHEDULED | SCHEDULE_DISCONNECT))) { |
| - vscsi->flags |= SCHEDULE_DISCONNECT; |
| - vscsi->new_state = new_state; |
| - |
| - INIT_WORK(&vscsi->proc_work, ibmvscsis_disconnect); |
| - (void)queue_work(vscsi->work_q, &vscsi->proc_work); |
| - } else { |
| - if (vscsi->new_state) |
| - state = vscsi->new_state; |
| - else |
| - state = vscsi->state; |
| - |
| - switch (state) { |
| - case NO_QUEUE: |
| - case UNCONFIGURING: |
| - break; |
| - |
| - case ERR_DISCONNECTED: |
| - case ERR_DISCONNECT: |
| - case UNDEFINED: |
| - if (new_state == UNCONFIGURING) |
| - vscsi->new_state = new_state; |
| - break; |
| - |
| - case ERR_DISCONNECT_RECONNECT: |
| - switch (new_state) { |
| - case UNCONFIGURING: |
| - case ERR_DISCONNECT: |
| - vscsi->new_state = new_state; |
| - break; |
| - default: |
| - break; |
| - } |
| - break; |
| - |
| - case WAIT_ENABLED: |
| - case PART_UP_WAIT_ENAB: |
| - case WAIT_IDLE: |
| - case WAIT_CONNECTION: |
| - case CONNECTED: |
| - case SRP_PROCESSING: |
| - vscsi->new_state = new_state; |
| - break; |
| + cmd->iue = NULL; |
| + list_add_tail(&cmd->list, &vscsi->free_cmd); |
| + srp_iu_put(iue); |
| |
| - default: |
| - break; |
| - } |
| + if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) && |
| + list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) { |
| + vscsi->flags &= ~WAIT_FOR_IDLE; |
| + complete(&vscsi->wait_idle); |
| } |
| - |
| - pr_debug("Leaving post_disconnect: flags 0x%x, new_state 0x%x\n", |
| - vscsi->flags, vscsi->new_state); |
| } |
| |
| /** |
| @@ -896,7 +1048,7 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi, |
| } |
| } |
| |
| - rc = vscsi->flags & SCHEDULE_DISCONNECT; |
| + rc = vscsi->flags & SCHEDULE_DISCONNECT; |
| |
| pr_debug("Leaving trans_event: flags 0x%x, state 0x%hx, rc %ld\n", |
| vscsi->flags, vscsi->state, rc); |
| @@ -1221,7 +1373,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi, |
| * @iue: Information Unit containing the Adapter Info MAD request |
| * |
| * EXECUTION ENVIRONMENT: |
| - * Interrupt adpater lock is held |
| + * Interrupt adapter lock is held |
| */ |
| static long ibmvscsis_adapter_info(struct scsi_info *vscsi, |
| struct iu_entry *iue) |
| @@ -1694,7 +1846,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi, |
| * @crq: Pointer to the CRQ entry containing the MAD request |
| * |
| * EXECUTION ENVIRONMENT: |
| - * Interrupt called with adapter lock held |
| + * Interrupt, called with adapter lock held |
| */ |
| static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq) |
| { |
| @@ -1860,7 +2012,7 @@ static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi, |
| break; |
| case H_PERMISSION: |
| if (connection_broken(vscsi)) |
| - flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED; |
| + flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED; |
| dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n", |
| rc); |
| ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, |
| @@ -2181,156 +2333,6 @@ static long ibmvscsis_ping_response(struct scsi_info *vscsi) |
| } |
| |
| /** |
| - * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message |
| - * @vscsi: Pointer to our adapter structure |
| - * |
| - * Must be called with interrupt lock held. |
| - */ |
| -static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi) |
| -{ |
| - long rc = ADAPT_SUCCESS; |
| - |
| - switch (vscsi->state) { |
| - case NO_QUEUE: |
| - case ERR_DISCONNECT: |
| - case ERR_DISCONNECT_RECONNECT: |
| - case ERR_DISCONNECTED: |
| - case UNCONFIGURING: |
| - case UNDEFINED: |
| - rc = ERROR; |
| - break; |
| - |
| - case WAIT_CONNECTION: |
| - vscsi->state = CONNECTED; |
| - break; |
| - |
| - case WAIT_IDLE: |
| - case SRP_PROCESSING: |
| - case CONNECTED: |
| - case WAIT_ENABLED: |
| - case PART_UP_WAIT_ENAB: |
| - default: |
| - rc = ERROR; |
| - dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n", |
| - vscsi->state); |
| - ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| - break; |
| - } |
| - |
| - return rc; |
| -} |
| - |
| -/** |
| - * ibmvscsis_handle_init_msg() - Respond to an Init Message |
| - * @vscsi: Pointer to our adapter structure |
| - * |
| - * Must be called with interrupt lock held. |
| - */ |
| -static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi) |
| -{ |
| - long rc = ADAPT_SUCCESS; |
| - |
| - switch (vscsi->state) { |
| - case WAIT_ENABLED: |
| - vscsi->state = PART_UP_WAIT_ENAB; |
| - break; |
| - |
| - case WAIT_CONNECTION: |
| - rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG); |
| - switch (rc) { |
| - case H_SUCCESS: |
| - vscsi->state = CONNECTED; |
| - break; |
| - |
| - case H_PARAMETER: |
| - dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n", |
| - rc); |
| - ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0); |
| - break; |
| - |
| - case H_DROPPED: |
| - dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n", |
| - rc); |
| - rc = ERROR; |
| - ibmvscsis_post_disconnect(vscsi, |
| - ERR_DISCONNECT_RECONNECT, 0); |
| - break; |
| - |
| - case H_CLOSED: |
| - pr_warn("init_msg: failed to send, rc %ld\n", rc); |
| - rc = 0; |
| - break; |
| - } |
| - break; |
| - |
| - case UNDEFINED: |
| - rc = ERROR; |
| - break; |
| - |
| - case UNCONFIGURING: |
| - break; |
| - |
| - case PART_UP_WAIT_ENAB: |
| - case CONNECTED: |
| - case SRP_PROCESSING: |
| - case WAIT_IDLE: |
| - case NO_QUEUE: |
| - case ERR_DISCONNECT: |
| - case ERR_DISCONNECT_RECONNECT: |
| - case ERR_DISCONNECTED: |
| - default: |
| - rc = ERROR; |
| - dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n", |
| - vscsi->state); |
| - ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| - break; |
| - } |
| - |
| - return rc; |
| -} |
| - |
| -/** |
| - * ibmvscsis_init_msg() - Respond to an init message |
| - * @vscsi: Pointer to our adapter structure |
| - * @crq: Pointer to CRQ element containing the Init Message |
| - * |
| - * EXECUTION ENVIRONMENT: |
| - * Interrupt, interrupt lock held |
| - */ |
| -static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq) |
| -{ |
| - long rc = ADAPT_SUCCESS; |
| - |
| - pr_debug("init_msg: state 0x%hx\n", vscsi->state); |
| - |
| - rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO, |
| - (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0, |
| - 0); |
| - if (rc == H_SUCCESS) { |
| - vscsi->client_data.partition_number = |
| - be64_to_cpu(*(u64 *)vscsi->map_buf); |
| - pr_debug("init_msg, part num %d\n", |
| - vscsi->client_data.partition_number); |
| - } else { |
| - pr_debug("init_msg h_vioctl rc %ld\n", rc); |
| - rc = ADAPT_SUCCESS; |
| - } |
| - |
| - if (crq->format == INIT_MSG) { |
| - rc = ibmvscsis_handle_init_msg(vscsi); |
| - } else if (crq->format == INIT_COMPLETE_MSG) { |
| - rc = ibmvscsis_handle_init_compl_msg(vscsi); |
| - } else { |
| - rc = ERROR; |
| - dev_err(&vscsi->dev, "init_msg: invalid format %d\n", |
| - (uint)crq->format); |
| - ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0); |
| - } |
| - |
| - return rc; |
| -} |
| - |
| -/** |
| * ibmvscsis_parse_command() - Parse an element taken from the cmd rsp queue. |
| * @vscsi: Pointer to our adapter structure |
| * @crq: Pointer to CRQ element containing the SRP request |
| @@ -2385,7 +2387,7 @@ static long ibmvscsis_parse_command(struct scsi_info *vscsi, |
| break; |
| |
| case VALID_TRANS_EVENT: |
| - rc = ibmvscsis_trans_event(vscsi, crq); |
| + rc = ibmvscsis_trans_event(vscsi, crq); |
| break; |
| |
| case VALID_INIT_MSG: |
| @@ -3282,7 +3284,7 @@ static void ibmvscsis_handle_crq(unsigned long data) |
| /* |
| * if we are in a path where we are waiting for all pending commands |
| * to complete because we received a transport event and anything in |
| - * the command queue is for a new connection, do nothing |
| + * the command queue is for a new connection, do nothing |
| */ |
| if (TARGET_STOP(vscsi)) { |
| vio_enable_interrupts(vscsi->dma_dev); |
| @@ -3329,7 +3331,7 @@ cmd_work: |
| |
| /* |
| * need to decrement the queue index so we can |
| - * look at the elment again |
| + * look at the element again |
| */ |
| if (vscsi->cmd_q.index) |
| vscsi->cmd_q.index -= 1; |
| @@ -4011,10 +4013,10 @@ static struct attribute *ibmvscsis_dev_attrs[] = { |
| ATTRIBUTE_GROUPS(ibmvscsis_dev); |
| |
| static struct class ibmvscsis_class = { |
| - .name = "ibmvscsis", |
| - .dev_release = ibmvscsis_dev_release, |
| - .class_attrs = ibmvscsis_class_attrs, |
| - .dev_groups = ibmvscsis_dev_groups, |
| + .name = "ibmvscsis", |
| + .dev_release = ibmvscsis_dev_release, |
| + .class_attrs = ibmvscsis_class_attrs, |
| + .dev_groups = ibmvscsis_dev_groups, |
| }; |
| |
| static struct vio_device_id ibmvscsis_device_table[] = { |
| -- |
| 2.12.0 |
| |