summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_fcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_fcp.c')
-rw-r--r--drivers/scsi/libfc/fc_fcp.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index ec1f66c4a9d4..e340373b509b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -58,8 +58,7 @@ struct kmem_cache *scsi_pkt_cachep;
#define FC_SRB_WRITE (1 << 0)
/*
- * The SCp.ptr should be tested and set under the host lock. NULL indicates
- * that the command has been retruned to the scsi layer.
+ * The SCp.ptr should be tested and set under the scsi_pkt_queue lock
*/
#define CMD_SP(Cmnd) ((struct fc_fcp_pkt *)(Cmnd)->SCp.ptr)
#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
@@ -580,10 +579,8 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
fsp, seq_blen, lport->lso_max, t_blen);
}
- WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
if (t_blen > 512)
t_blen &= ~(512 - 1); /* round down to block size */
- WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD); /* won't go below 256 */
sc = fsp->cmd;
remaining = seq_blen;
@@ -745,7 +742,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
fh = fc_frame_header_get(fp);
r_ctl = fh->fh_r_ctl;
- if (!(lport->state & LPORT_ST_READY))
+ if (lport->state != LPORT_ST_READY)
goto out;
if (fc_fcp_lock_pkt(fsp))
goto out;
@@ -1110,7 +1107,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
rpriv->local_port->port_id, FC_TYPE_FCP,
- FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
+ FC_FCTL_REQ, 0);
seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy,
fsp, 0);
@@ -1383,7 +1380,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
fr_seq(fp) = fsp->seq_ptr;
fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
rpriv->local_port->port_id, FC_TYPE_ELS,
- FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
+ FC_FCTL_REQ, 0);
if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
fc_fcp_rec_resp, fsp,
jiffies_to_msecs(FC_SCSI_REC_TOV))) {
@@ -1641,7 +1638,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
rpriv->local_port->port_id, FC_TYPE_FCP,
- FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
+ FC_FCTL_REQ, 0);
seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
@@ -1767,14 +1764,14 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
struct fcoe_dev_stats *stats;
lport = shost_priv(sc_cmd->device->host);
- spin_unlock_irq(lport->host->host_lock);
rval = fc_remote_port_chkready(rport);
if (rval) {
sc_cmd->result = rval;
done(sc_cmd);
- goto out;
+ return 0;
}
+ spin_unlock_irq(lport->host->host_lock);
if (!*(struct fc_remote_port **)rport->dd_data) {
/*
@@ -1882,8 +1879,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
lport = fsp->lp;
si = fc_get_scsi_internal(lport);
- if (!fsp->cmd)
- return;
/*
* if can_queue ramp down is done then try can_queue ramp up
@@ -1893,11 +1888,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
fc_fcp_can_queue_ramp_up(lport);
sc_cmd = fsp->cmd;
- fsp->cmd = NULL;
-
- if (!sc_cmd->SCp.ptr)
- return;
-
CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status;
switch (fsp->status_code) {
case FC_COMPLETE:
@@ -1973,10 +1963,13 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
break;
}
+ if (lport->state != LPORT_ST_READY && fsp->status_code != FC_COMPLETE)
+ sc_cmd->result = (DID_TRANSPORT_DISRUPTED << 16);
+
spin_lock_irqsave(&si->scsi_queue_lock, flags);
list_del(&fsp->list);
- spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
sc_cmd->SCp.ptr = NULL;
+ spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
sc_cmd->scsi_done(sc_cmd);
/* release ref from initial allocation in queue command */
@@ -1994,6 +1987,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
{
struct fc_fcp_pkt *fsp;
struct fc_lport *lport;
+ struct fc_fcp_internal *si;
int rc = FAILED;
unsigned long flags;
@@ -2003,7 +1997,8 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
else if (!lport->link_up)
return rc;
- spin_lock_irqsave(lport->host->host_lock, flags);
+ si = fc_get_scsi_internal(lport);
+ spin_lock_irqsave(&si->scsi_queue_lock, flags);
fsp = CMD_SP(sc_cmd);
if (!fsp) {
/* command completed while scsi eh was setting up */
@@ -2012,7 +2007,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
}
/* grab a ref so the fsp and sc_cmd cannot be relased from under us */
fc_fcp_pkt_hold(fsp);
- spin_unlock_irqrestore(lport->host->host_lock, flags);
+ spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
if (fc_fcp_lock_pkt(fsp)) {
/* completed while we were waiting for timer to be deleted */