Commit 79fac9c9 authored by Michael Cyr's avatar Michael Cyr Committed by Martin K. Petersen

scsi: ibmvscsis: Rearrange functions for future patches

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: default avatarMichael Cyr <mikecyr@us.ibm.com>
Signed-off-by: default avatarBryant G. Ly <bryantly@linux.vnet.ibm.com>
Tested-by: default avatarSteven Royer <seroyer@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c1f7cf0a
...@@ -61,6 +61,8 @@ static long ibmvscsis_parse_command(struct scsi_info *vscsi, ...@@ -61,6 +61,8 @@ static long ibmvscsis_parse_command(struct scsi_info *vscsi,
static void ibmvscsis_adapter_idle(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, static void ibmvscsis_determine_resid(struct se_cmd *se_cmd,
struct srp_rsp *rsp) struct srp_rsp *rsp)
{ {
...@@ -396,166 +398,6 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format) ...@@ -396,166 +398,6 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)
return rc; 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_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 * ibmvscsis_disconnect() - Helper function to disconnect
* @work: Pointer to work_struct, gives access to our adapter structure * @work: Pointer to work_struct, gives access to our adapter structure
...@@ -711,98 +553,408 @@ static void ibmvscsis_disconnect(struct work_struct *work) ...@@ -711,98 +553,408 @@ static void ibmvscsis_disconnect(struct work_struct *work)
ibmvscsis_adapter_idle(vscsi); ibmvscsis_adapter_idle(vscsi);
} }
spin_unlock_bh(&vscsi->intr_lock); spin_unlock_bh(&vscsi->intr_lock);
}
/**
* ibmvscsis_post_disconnect() - Schedule the disconnect
* @vscsi: Pointer to our adapter structure
* @new_state: State to move to after disconnecting
* @flag_bits: Flags to turn on in adapter structure
*
* If it's already been scheduled, then see if we need to "upgrade"
* the new state (if the one passed in is more "severe" than the
* previous one).
*
* 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_post_disconnect() - Schedule the disconnect * ibmvscsis_free_cmd_resources() - Free command resources
* @vscsi: Pointer to our adapter structure * @vscsi: Pointer to our adapter structure
* @new_state: State to move to after disconnecting * @cmd: Command which is not longer in use
* @flag_bits: Flags to turn on in adapter structure
*
* If it's already been scheduled, then see if we need to "upgrade"
* the new state (if the one passed in is more "severe" than the
* previous one).
* *
* PRECONDITION: * Must be called with interrupt lock held.
* interrupt lock is held
*/ */
static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state, static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
uint flag_bits) 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:
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) { switch (cmd->type) {
case NO_QUEUE: case TASK_MANAGEMENT:
case UNCONFIGURING: 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; break;
case ADAPTER_MAD:
case ERR_DISCONNECTED: vscsi->flags &= ~PROCESSING_MAD;
case ERR_DISCONNECT:
case UNDEFINED:
if (new_state == UNCONFIGURING)
vscsi->new_state = new_state;
break; break;
case UNSET_TYPE:
case ERR_DISCONNECT_RECONNECT:
switch (new_state) {
case UNCONFIGURING:
case ERR_DISCONNECT:
vscsi->new_state = new_state;
break; break;
default: default:
dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n",
cmd->type);
break; break;
} }
break;
case WAIT_ENABLED: cmd->iue = NULL;
case PART_UP_WAIT_ENAB: list_add_tail(&cmd->list, &vscsi->free_cmd);
case WAIT_IDLE: srp_iu_put(iue);
case WAIT_CONNECTION:
case CONNECTED:
case SRP_PROCESSING:
vscsi->new_state = new_state;
break;
default: if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) &&
break; 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);
} }
/** /**
...@@ -1220,7 +1372,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi, ...@@ -1220,7 +1372,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,
* @iue: Information Unit containing the Adapter Info MAD request * @iue: Information Unit containing the Adapter Info MAD request
* *
* EXECUTION ENVIRONMENT: * EXECUTION ENVIRONMENT:
* Interrupt adpater lock is held * Interrupt adapter lock is held
*/ */
static long ibmvscsis_adapter_info(struct scsi_info *vscsi, static long ibmvscsis_adapter_info(struct scsi_info *vscsi,
struct iu_entry *iue) struct iu_entry *iue)
...@@ -1691,7 +1843,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi, ...@@ -1691,7 +1843,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,
* @crq: Pointer to the CRQ entry containing the MAD request * @crq: Pointer to the CRQ entry containing the MAD request
* *
* EXECUTION ENVIRONMENT: * 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) static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
{ {
...@@ -2186,156 +2338,6 @@ static long ibmvscsis_ping_response(struct scsi_info *vscsi) ...@@ -2186,156 +2338,6 @@ static long ibmvscsis_ping_response(struct scsi_info *vscsi)
return rc; return rc;
} }
/**
* 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. * ibmvscsis_parse_command() - Parse an element taken from the cmd rsp queue.
* @vscsi: Pointer to our adapter structure * @vscsi: Pointer to our adapter structure
...@@ -3314,7 +3316,7 @@ static void ibmvscsis_handle_crq(unsigned long data) ...@@ -3314,7 +3316,7 @@ static void ibmvscsis_handle_crq(unsigned long data)
* everything but transport events on the queue * everything but transport events on the queue
* *
* need to decrement the queue index so we can * need to decrement the queue index so we can
* look at the elment again * look at the element again
*/ */
if (vscsi->cmd_q.index) if (vscsi->cmd_q.index)
vscsi->cmd_q.index -= 1; vscsi->cmd_q.index -= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment