diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_fcp.c')
| -rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index f607314810a..1d7e76e8b44 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -158,6 +158,9 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lport, gfp_t gfp) fsp->timer.data = (unsigned long)fsp; INIT_LIST_HEAD(&fsp->list); spin_lock_init(&fsp->scsi_pkt_lock); + } else { + per_cpu_ptr(lport->stats, get_cpu())->FcpPktAllocFails++; + put_cpu(); } return fsp; } @@ -264,6 +267,9 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) if (!fsp->seq_ptr) return -EINVAL; + per_cpu_ptr(fsp->lp->stats, get_cpu())->FcpPktAborts++; + put_cpu(); + fsp->state |= FC_SRB_ABORT_PENDING; return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0); } @@ -420,6 +426,8 @@ static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport, if (likely(fp)) return fp; + per_cpu_ptr(lport->stats, get_cpu())->FcpFrameAllocFails++; + put_cpu(); /* error case */ fc_fcp_can_queue_ramp_down(lport); return NULL; @@ -434,7 +442,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) { struct scsi_cmnd *sc = fsp->cmd; struct fc_lport *lport = fsp->lp; - struct fcoe_dev_stats *stats; + struct fc_stats *stats; struct fc_frame_header *fh; size_t start_offset; size_t offset; @@ -485,18 +493,18 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, - &offset, KM_SOFTIRQ0, NULL); + &offset, NULL); } else { crc = crc32(~0, (u8 *) fh, sizeof(*fh)); copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, - &offset, KM_SOFTIRQ0, &crc); + &offset, &crc); buf = fc_frame_payload_get(fp, 0); if (len % 4) crc = crc32(crc, buf + len, 4 - (len % 4)); if (~crc != le32_to_cpu(fr_crc(fp))) { crc_err: - stats = per_cpu_ptr(lport->dev_stats, get_cpu()); + stats = per_cpu_ptr(lport->stats, get_cpu()); stats->ErrorFrames++; /* per cpu count, not total count, but OK for limit */ if (stats->InvalidCRCCount++ < FC_MAX_ERROR_CNT) @@ -650,10 +658,10 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, * The scatterlist item may be bigger than PAGE_SIZE, * but we must not cross pages inside the kmap. */ - page_addr = kmap_atomic(page, KM_SOFTIRQ0); + page_addr = kmap_atomic(page); memcpy(data, (char *)page_addr + (off & ~PAGE_MASK), sg_bytes); - kunmap_atomic(page_addr, KM_SOFTIRQ0); + kunmap_atomic(page_addr); data += sg_bytes; } offset += sg_bytes; @@ -843,7 +851,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); if (flags & FCP_RSP_LEN_VAL) { respl = ntohl(rp_ex->fr_rsp_len); - if (respl != sizeof(*fc_rp_info)) + if ((respl != FCP_RESP_RSP_INFO_LEN4) && + (respl != FCP_RESP_RSP_INFO_LEN8)) goto len_err; if (fsp->wait_for_comp) { /* Abuse cdb_status for rsp code */ @@ -893,7 +902,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) /* * Check for missing or extra data frames. */ - if (unlikely(fsp->xfer_len != expected_len)) { + if (unlikely(fsp->cdb_status == SAM_STAT_GOOD && + fsp->xfer_len != expected_len)) { if (fsp->xfer_len < expected_len) { /* * Some data may be queued locally, @@ -946,12 +956,11 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp) * Test for transport underrun, independent of response * underrun status. */ - if (fsp->xfer_len < fsp->data_len && !fsp->io_status && + if (fsp->cdb_status == SAM_STAT_GOOD && + fsp->xfer_len < fsp->data_len && !fsp->io_status && (!(fsp->scsi_comp_flags & FCP_RESID_UNDER) || - fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) { + fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) fsp->status_code = FC_DATA_UNDRUN; - fsp->io_status = 0; - } } seq = fsp->seq_ptr; @@ -1074,8 +1083,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; - int_to_scsilun(fsp->cmd->device->lun, - (struct scsi_lun *)fsp->cdb_cmd.fc_lun); + int_to_scsilun(fsp->cmd->device->lun, &fsp->cdb_cmd.fc_lun); memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); spin_lock_irqsave(&si->scsi_queue_lock, flags); @@ -1257,7 +1265,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp, fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET; - int_to_scsilun(lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun); + int_to_scsilun(lun, &fsp->cdb_cmd.fc_lun); fsp->wait_for_comp = 1; init_completion(&fsp->tm_done); @@ -1787,7 +1795,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) struct fc_rport_libfc_priv *rpriv; int rval; int rc = 0; - struct fcoe_dev_stats *stats; + struct fc_stats *stats; rval = fc_remote_port_chkready(rport); if (rval) { @@ -1836,7 +1844,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) /* * setup the data direction */ - stats = per_cpu_ptr(lport->dev_stats, get_cpu()); + stats = per_cpu_ptr(lport->stats, get_cpu()); if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { fsp->req_flags = FC_SRB_READ; stats->InputRequests++; @@ -2035,7 +2043,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) spin_unlock_irqrestore(&si->scsi_queue_lock, flags); return SUCCESS; } - /* grab a ref so the fsp and sc_cmd cannot be relased from under us */ + /* grab a ref so the fsp and sc_cmd cannot be released from under us */ fc_fcp_pkt_hold(fsp); spin_unlock_irqrestore(&si->scsi_queue_lock, flags); |
