Lines Matching refs:fsp
134 struct fc_fcp_pkt *fsp; in fc_fcp_pkt_alloc() local
136 fsp = mempool_alloc(si->scsi_pkt_pool, gfp); in fc_fcp_pkt_alloc()
137 if (fsp) { in fc_fcp_pkt_alloc()
138 memset(fsp, 0, sizeof(*fsp)); in fc_fcp_pkt_alloc()
139 fsp->lp = lport; in fc_fcp_pkt_alloc()
140 fsp->xfer_ddp = FC_XID_UNKNOWN; in fc_fcp_pkt_alloc()
141 refcount_set(&fsp->ref_cnt, 1); in fc_fcp_pkt_alloc()
142 timer_setup(&fsp->timer, NULL, 0); in fc_fcp_pkt_alloc()
143 INIT_LIST_HEAD(&fsp->list); in fc_fcp_pkt_alloc()
144 spin_lock_init(&fsp->scsi_pkt_lock); in fc_fcp_pkt_alloc()
148 return fsp; in fc_fcp_pkt_alloc()
158 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp) in fc_fcp_pkt_release() argument
160 if (refcount_dec_and_test(&fsp->ref_cnt)) { in fc_fcp_pkt_release()
161 struct fc_fcp_internal *si = fc_get_scsi_internal(fsp->lp); in fc_fcp_pkt_release()
163 mempool_free(fsp, si->scsi_pkt_pool); in fc_fcp_pkt_release()
171 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp) in fc_fcp_pkt_hold() argument
173 refcount_inc(&fsp->ref_cnt); in fc_fcp_pkt_hold()
187 static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp) in fc_fcp_pkt_destroy() argument
189 fc_fcp_pkt_release(fsp); in fc_fcp_pkt_destroy()
209 static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp) in fc_fcp_lock_pkt() argument
211 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_fcp_lock_pkt()
212 if (fsp->state & FC_SRB_COMPL) { in fc_fcp_lock_pkt()
213 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_fcp_lock_pkt()
217 fc_fcp_pkt_hold(fsp); in fc_fcp_lock_pkt()
226 static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp) in fc_fcp_unlock_pkt() argument
228 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_fcp_unlock_pkt()
229 fc_fcp_pkt_release(fsp); in fc_fcp_unlock_pkt()
237 static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay) in fc_fcp_timer_set() argument
239 if (!(fsp->state & FC_SRB_COMPL)) { in fc_fcp_timer_set()
240 mod_timer(&fsp->timer, jiffies + delay); in fc_fcp_timer_set()
241 fsp->timer_delay = delay; in fc_fcp_timer_set()
245 static void fc_fcp_abort_done(struct fc_fcp_pkt *fsp) in fc_fcp_abort_done() argument
247 fsp->state |= FC_SRB_ABORTED; in fc_fcp_abort_done()
248 fsp->state &= ~FC_SRB_ABORT_PENDING; in fc_fcp_abort_done()
250 if (fsp->wait_for_comp) in fc_fcp_abort_done()
251 complete(&fsp->tm_done); in fc_fcp_abort_done()
253 fc_fcp_complete_locked(fsp); in fc_fcp_abort_done()
261 static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) in fc_fcp_send_abort() argument
265 if (!fsp->seq_ptr) in fc_fcp_send_abort()
268 this_cpu_inc(fsp->lp->stats->FcpPktAborts); in fc_fcp_send_abort()
270 fsp->state |= FC_SRB_ABORT_PENDING; in fc_fcp_send_abort()
271 rc = fc_seq_exch_abort(fsp->seq_ptr, 0); in fc_fcp_send_abort()
277 fc_fcp_abort_done(fsp); in fc_fcp_send_abort()
293 static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp, int status_code) in fc_fcp_retry_cmd() argument
295 if (fsp->seq_ptr) { in fc_fcp_retry_cmd()
296 fc_exch_done(fsp->seq_ptr); in fc_fcp_retry_cmd()
297 fsp->seq_ptr = NULL; in fc_fcp_retry_cmd()
300 fsp->state &= ~FC_SRB_ABORT_PENDING; in fc_fcp_retry_cmd()
301 fsp->io_status = 0; in fc_fcp_retry_cmd()
302 fsp->status_code = status_code; in fc_fcp_retry_cmd()
303 fc_fcp_complete_locked(fsp); in fc_fcp_retry_cmd()
311 void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) in fc_fcp_ddp_setup() argument
315 lport = fsp->lp; in fc_fcp_ddp_setup()
316 if ((fsp->req_flags & FC_SRB_READ) && in fc_fcp_ddp_setup()
318 if (lport->tt.ddp_setup(lport, xid, scsi_sglist(fsp->cmd), in fc_fcp_ddp_setup()
319 scsi_sg_count(fsp->cmd))) in fc_fcp_ddp_setup()
320 fsp->xfer_ddp = xid; in fc_fcp_ddp_setup()
329 void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp) in fc_fcp_ddp_done() argument
333 if (!fsp) in fc_fcp_ddp_done()
336 if (fsp->xfer_ddp == FC_XID_UNKNOWN) in fc_fcp_ddp_done()
339 lport = fsp->lp; in fc_fcp_ddp_done()
341 fsp->xfer_len = lport->tt.ddp_done(lport, fsp->xfer_ddp); in fc_fcp_ddp_done()
342 fsp->xfer_ddp = FC_XID_UNKNOWN; in fc_fcp_ddp_done()
452 static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp) in get_fsp_rec_tov() argument
454 struct fc_rport_libfc_priv *rpriv = fsp->rport->dd_data; in get_fsp_rec_tov()
467 static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_recv_data() argument
469 struct scsi_cmnd *sc = fsp->cmd; in fc_fcp_recv_data()
470 struct fc_lport *lport = fsp->lp; in fc_fcp_recv_data()
495 if (fsp->xfer_ddp != FC_XID_UNKNOWN) { in fc_fcp_recv_data()
496 fc_fcp_ddp_done(fsp); in fc_fcp_recv_data()
497 FC_FCP_DBG(fsp, "DDP I/O in fc_fcp_recv_data set ERROR\n"); in fc_fcp_recv_data()
501 if (offset + len > fsp->data_len) { in fc_fcp_recv_data()
506 FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx " in fc_fcp_recv_data()
507 "data_len %x\n", len, offset, fsp->data_len); in fc_fcp_recv_data()
513 if (offset != fsp->xfer_len) in fc_fcp_recv_data()
514 fsp->state |= FC_SRB_DISCONTIG; in fc_fcp_recv_data()
545 if (fsp->state & FC_SRB_DISCONTIG) { in fc_fcp_recv_data()
553 if (fsp->xfer_contig_end == start_offset) in fc_fcp_recv_data()
554 fsp->xfer_contig_end += copy_len; in fc_fcp_recv_data()
555 fsp->xfer_len += copy_len; in fc_fcp_recv_data()
561 if (unlikely(fsp->state & FC_SRB_RCV_STATUS) && in fc_fcp_recv_data()
562 fsp->xfer_len == fsp->data_len - fsp->scsi_resid) { in fc_fcp_recv_data()
563 FC_FCP_DBG( fsp, "complete out-of-order sequence\n" ); in fc_fcp_recv_data()
564 fc_fcp_complete_locked(fsp); in fc_fcp_recv_data()
568 fc_fcp_recovery(fsp, host_bcode); in fc_fcp_recv_data()
584 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, in fc_fcp_send_data() argument
591 struct fc_lport *lport = fsp->lp; in fc_fcp_send_data()
606 if (unlikely(offset + seq_blen > fsp->data_len)) { in fc_fcp_send_data()
608 FC_FCP_DBG(fsp, "xfer-ready past end. seq_blen %zx " in fc_fcp_send_data()
610 fc_fcp_send_abort(fsp); in fc_fcp_send_data()
612 } else if (offset != fsp->xfer_len) { in fc_fcp_send_data()
614 FC_FCP_DBG(fsp, "xfer-ready non-contiguous. " in fc_fcp_send_data()
623 t_blen = fsp->max_payload; in fc_fcp_send_data()
626 FC_FCP_DBG(fsp, "fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n", in fc_fcp_send_data()
627 fsp, seq_blen, lport->lso_max, t_blen); in fc_fcp_send_data()
632 sc = fsp->cmd; in fc_fcp_send_data()
665 fr_max_payload(fp) = fsp->max_payload; in fc_fcp_send_data()
722 fsp->xfer_len += seq_blen; /* premature count? */ in fc_fcp_send_data()
731 static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_abts_resp() argument
756 fc_fcp_abort_done(fsp); in fc_fcp_abts_resp()
770 struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)arg; in fc_fcp_recv() local
771 struct fc_lport *lport = fsp->lp; in fc_fcp_recv()
778 fc_fcp_error(fsp, fp); in fc_fcp_recv()
786 FC_FCP_DBG(fsp, "lport state %d, ignoring r_ctl %x\n", in fc_fcp_recv()
790 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_recv()
794 fc_fcp_abts_resp(fsp, fp); in fc_fcp_recv()
798 if (fsp->state & (FC_SRB_ABORTED | FC_SRB_ABORT_PENDING)) { in fc_fcp_recv()
799 FC_FCP_DBG(fsp, "command aborted, ignoring r_ctl %x\n", r_ctl); in fc_fcp_recv()
812 rc = fc_fcp_send_data(fsp, seq, in fc_fcp_recv()
816 seq->rec_data = fsp->xfer_len; in fc_fcp_recv()
823 fc_fcp_recv_data(fsp, fp); in fc_fcp_recv()
824 seq->rec_data = fsp->xfer_contig_end; in fc_fcp_recv()
828 fc_fcp_resp(fsp, fp); in fc_fcp_recv()
830 FC_FCP_DBG(fsp, "unexpected frame. r_ctl %x\n", r_ctl); in fc_fcp_recv()
833 fc_fcp_unlock_pkt(fsp); in fc_fcp_recv()
843 static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_resp() argument
861 fsp->cdb_status = fc_rp->fr_status; in fc_fcp_resp()
863 fsp->scsi_comp_flags = flags; in fc_fcp_resp()
864 expected_len = fsp->data_len; in fc_fcp_resp()
867 fc_fcp_ddp_done(fsp); in fc_fcp_resp()
880 if (fsp->wait_for_comp) { in fc_fcp_resp()
882 fsp->cdb_status = fc_rp_info->rsp_code; in fc_fcp_resp()
883 complete(&fsp->tm_done); in fc_fcp_resp()
895 memcpy(fsp->cmd->sense_buffer, in fc_fcp_resp()
903 fsp->scsi_resid = ntohl(rp_ex->fr_resid); in fc_fcp_resp()
914 (scsi_bufflen(fsp->cmd) - in fc_fcp_resp()
915 fsp->scsi_resid) < fsp->cmd->underflow) in fc_fcp_resp()
917 expected_len -= fsp->scsi_resid; in fc_fcp_resp()
919 fsp->status_code = FC_ERROR; in fc_fcp_resp()
923 fsp->state |= FC_SRB_RCV_STATUS; in fc_fcp_resp()
928 if (unlikely(fsp->cdb_status == SAM_STAT_GOOD && in fc_fcp_resp()
929 fsp->xfer_len != expected_len)) { in fc_fcp_resp()
930 if (fsp->xfer_len < expected_len) { in fc_fcp_resp()
936 if (fsp->lp->qfull) { in fc_fcp_resp()
937 FC_FCP_DBG(fsp, "tgt %6.6x queue busy retry\n", in fc_fcp_resp()
938 fsp->rport->port_id); in fc_fcp_resp()
941 FC_FCP_DBG(fsp, "tgt %6.6x xfer len %zx data underrun " in fc_fcp_resp()
943 fsp->rport->port_id, in fc_fcp_resp()
944 fsp->xfer_len, expected_len, fsp->data_len); in fc_fcp_resp()
945 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_fcp_resp()
948 fsp->status_code = FC_DATA_OVRRUN; in fc_fcp_resp()
949 FC_FCP_DBG(fsp, "tgt %6.6x xfer len %zx greater than expected, " in fc_fcp_resp()
951 fsp->rport->port_id, in fc_fcp_resp()
952 fsp->xfer_len, expected_len, fsp->data_len); in fc_fcp_resp()
954 fc_fcp_complete_locked(fsp); in fc_fcp_resp()
958 FC_FCP_DBG(fsp, "short FCP response. flags 0x%x len %u respl %u " in fc_fcp_resp()
961 fsp->status_code = FC_ERROR; in fc_fcp_resp()
962 fc_fcp_complete_locked(fsp); in fc_fcp_resp()
973 static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp) in fc_fcp_complete_locked() argument
975 struct fc_lport *lport = fsp->lp; in fc_fcp_complete_locked()
980 if (fsp->state & FC_SRB_ABORT_PENDING) in fc_fcp_complete_locked()
983 if (fsp->state & FC_SRB_ABORTED) { in fc_fcp_complete_locked()
984 if (!fsp->status_code) in fc_fcp_complete_locked()
985 fsp->status_code = FC_CMD_ABORTED; in fc_fcp_complete_locked()
991 if (fsp->cdb_status == SAM_STAT_GOOD && in fc_fcp_complete_locked()
992 fsp->xfer_len < fsp->data_len && !fsp->io_status && in fc_fcp_complete_locked()
993 (!(fsp->scsi_comp_flags & FCP_RESID_UNDER) || in fc_fcp_complete_locked()
994 fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) { in fc_fcp_complete_locked()
995 FC_FCP_DBG(fsp, "data underrun, xfer %zx data %x\n", in fc_fcp_complete_locked()
996 fsp->xfer_len, fsp->data_len); in fc_fcp_complete_locked()
997 fsp->status_code = FC_DATA_UNDRUN; in fc_fcp_complete_locked()
1001 seq = fsp->seq_ptr; in fc_fcp_complete_locked()
1003 fsp->seq_ptr = NULL; in fc_fcp_complete_locked()
1004 if (unlikely(fsp->scsi_comp_flags & FCP_CONF_REQ)) { in fc_fcp_complete_locked()
1009 conf_frame = fc_fcp_frame_alloc(fsp->lp, 0); in fc_fcp_complete_locked()
1027 if (fsp->cmd) in fc_fcp_complete_locked()
1028 fc_io_compl(fsp); in fc_fcp_complete_locked()
1036 static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error) in fc_fcp_cleanup_cmd() argument
1038 if (fsp->seq_ptr) { in fc_fcp_cleanup_cmd()
1039 fc_exch_done(fsp->seq_ptr); in fc_fcp_cleanup_cmd()
1040 fsp->seq_ptr = NULL; in fc_fcp_cleanup_cmd()
1042 fsp->status_code = error; in fc_fcp_cleanup_cmd()
1058 struct fc_fcp_pkt *fsp; in fc_fcp_cleanup_each_cmd() local
1064 list_for_each_entry(fsp, &si->scsi_pkt_queue, list) { in fc_fcp_cleanup_each_cmd()
1065 sc_cmd = fsp->cmd; in fc_fcp_cleanup_each_cmd()
1072 fc_fcp_pkt_hold(fsp); in fc_fcp_cleanup_each_cmd()
1075 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_fcp_cleanup_each_cmd()
1076 if (!(fsp->state & FC_SRB_COMPL)) { in fc_fcp_cleanup_each_cmd()
1077 fsp->state |= FC_SRB_COMPL; in fc_fcp_cleanup_each_cmd()
1087 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_fcp_cleanup_each_cmd()
1089 fc_fcp_cleanup_cmd(fsp, error); in fc_fcp_cleanup_each_cmd()
1091 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_fcp_cleanup_each_cmd()
1092 fc_io_compl(fsp); in fc_fcp_cleanup_each_cmd()
1094 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_fcp_cleanup_each_cmd()
1096 fc_fcp_pkt_release(fsp); in fc_fcp_cleanup_each_cmd()
1124 static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) in fc_fcp_pkt_send() argument
1130 libfc_priv(fsp->cmd)->fsp = fsp; in fc_fcp_pkt_send()
1131 fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); in fc_fcp_pkt_send()
1132 fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; in fc_fcp_pkt_send()
1134 int_to_scsilun(fsp->cmd->device->lun, &fsp->cdb_cmd.fc_lun); in fc_fcp_pkt_send()
1135 memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); in fc_fcp_pkt_send()
1138 list_add_tail(&fsp->list, &si->scsi_pkt_queue); in fc_fcp_pkt_send()
1140 rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv); in fc_fcp_pkt_send()
1143 libfc_priv(fsp->cmd)->fsp = NULL; in fc_fcp_pkt_send()
1144 list_del(&fsp->list); in fc_fcp_pkt_send()
1157 static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp, in fc_fcp_cmd_send() argument
1166 const size_t len = sizeof(fsp->cdb_cmd); in fc_fcp_cmd_send()
1169 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_cmd_send()
1172 fp = fc_fcp_frame_alloc(lport, sizeof(fsp->cdb_cmd)); in fc_fcp_cmd_send()
1178 memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len); in fc_fcp_cmd_send()
1179 fr_fsp(fp) = fsp; in fc_fcp_cmd_send()
1180 rport = fsp->rport; in fc_fcp_cmd_send()
1181 fsp->max_payload = rport->maxframe_size; in fc_fcp_cmd_send()
1188 seq = fc_exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy, fsp, 0); in fc_fcp_cmd_send()
1193 fsp->seq_ptr = seq; in fc_fcp_cmd_send()
1194 fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */ in fc_fcp_cmd_send()
1196 fsp->timer.function = fc_fcp_timeout; in fc_fcp_cmd_send()
1198 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_fcp_cmd_send()
1201 fc_fcp_unlock_pkt(fsp); in fc_fcp_cmd_send()
1210 static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_error() argument
1214 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_error()
1218 fc_fcp_retry_cmd(fsp, FC_ERROR); in fc_fcp_error()
1226 fsp->state &= ~FC_SRB_ABORT_PENDING; in fc_fcp_error()
1227 fsp->status_code = FC_CMD_PLOGO; in fc_fcp_error()
1228 fc_fcp_complete_locked(fsp); in fc_fcp_error()
1230 fc_fcp_unlock_pkt(fsp); in fc_fcp_error()
1239 static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp) in fc_fcp_pkt_abort() argument
1244 FC_FCP_DBG(fsp, "pkt abort state %x\n", fsp->state); in fc_fcp_pkt_abort()
1245 if (fc_fcp_send_abort(fsp)) { in fc_fcp_pkt_abort()
1246 FC_FCP_DBG(fsp, "failed to send abort\n"); in fc_fcp_pkt_abort()
1250 if (fsp->state & FC_SRB_ABORTED) { in fc_fcp_pkt_abort()
1251 FC_FCP_DBG(fsp, "target abort cmd completed\n"); in fc_fcp_pkt_abort()
1255 init_completion(&fsp->tm_done); in fc_fcp_pkt_abort()
1256 fsp->wait_for_comp = 1; in fc_fcp_pkt_abort()
1258 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_fcp_pkt_abort()
1259 ticks_left = wait_for_completion_timeout(&fsp->tm_done, in fc_fcp_pkt_abort()
1261 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_fcp_pkt_abort()
1262 fsp->wait_for_comp = 0; in fc_fcp_pkt_abort()
1265 FC_FCP_DBG(fsp, "target abort cmd failed\n"); in fc_fcp_pkt_abort()
1266 } else if (fsp->state & FC_SRB_ABORTED) { in fc_fcp_pkt_abort()
1267 FC_FCP_DBG(fsp, "target abort cmd passed\n"); in fc_fcp_pkt_abort()
1269 fc_fcp_complete_locked(fsp); in fc_fcp_pkt_abort()
1281 struct fc_fcp_pkt *fsp = from_timer(fsp, t, timer); in fc_lun_reset_send() local
1282 struct fc_lport *lport = fsp->lp; in fc_lun_reset_send()
1284 if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) { in fc_lun_reset_send()
1285 if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY) in fc_lun_reset_send()
1287 if (fc_fcp_lock_pkt(fsp)) in fc_lun_reset_send()
1289 fsp->timer.function = fc_lun_reset_send; in fc_lun_reset_send()
1290 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_lun_reset_send()
1291 fc_fcp_unlock_pkt(fsp); in fc_lun_reset_send()
1303 static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp, in fc_lun_reset() argument
1308 fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); in fc_lun_reset()
1309 fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET; in fc_lun_reset()
1310 int_to_scsilun(lun, &fsp->cdb_cmd.fc_lun); in fc_lun_reset()
1312 fsp->wait_for_comp = 1; in fc_lun_reset()
1313 init_completion(&fsp->tm_done); in fc_lun_reset()
1315 fc_lun_reset_send(&fsp->timer); in fc_lun_reset()
1321 rc = wait_for_completion_timeout(&fsp->tm_done, FC_SCSI_TM_TOV); in fc_lun_reset()
1323 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_lun_reset()
1324 fsp->state |= FC_SRB_COMPL; in fc_lun_reset()
1325 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_lun_reset()
1327 del_timer_sync(&fsp->timer); in fc_lun_reset()
1329 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_lun_reset()
1330 if (fsp->seq_ptr) { in fc_lun_reset()
1331 fc_exch_done(fsp->seq_ptr); in fc_lun_reset()
1332 fsp->seq_ptr = NULL; in fc_lun_reset()
1334 fsp->wait_for_comp = 0; in fc_lun_reset()
1335 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_lun_reset()
1343 if (fsp->cdb_status != FCP_TMF_CMPL) in fc_lun_reset()
1359 struct fc_fcp_pkt *fsp = arg; in fc_tm_done() local
1372 if (fc_fcp_lock_pkt(fsp)) in fc_tm_done()
1378 if (!fsp->seq_ptr || !fsp->wait_for_comp) in fc_tm_done()
1383 fc_fcp_resp(fsp, fp); in fc_tm_done()
1384 fsp->seq_ptr = NULL; in fc_tm_done()
1387 fc_fcp_unlock_pkt(fsp); in fc_tm_done()
1414 struct fc_fcp_pkt *fsp = from_timer(fsp, t, timer); in fc_fcp_timeout() local
1415 struct fc_rport *rport = fsp->rport; in fc_fcp_timeout()
1418 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_timeout()
1421 if (fsp->cdb_cmd.fc_tm_flags) in fc_fcp_timeout()
1424 if (fsp->lp->qfull) { in fc_fcp_timeout()
1425 FC_FCP_DBG(fsp, "fcp timeout, resetting timer delay %d\n", in fc_fcp_timeout()
1426 fsp->timer_delay); in fc_fcp_timeout()
1427 fsp->timer.function = fc_fcp_timeout; in fc_fcp_timeout()
1428 fc_fcp_timer_set(fsp, fsp->timer_delay); in fc_fcp_timeout()
1431 FC_FCP_DBG(fsp, "fcp timeout, delay %d flags %x state %x\n", in fc_fcp_timeout()
1432 fsp->timer_delay, rpriv->flags, fsp->state); in fc_fcp_timeout()
1433 fsp->state |= FC_SRB_FCP_PROCESSING_TMO; in fc_fcp_timeout()
1436 fc_fcp_rec(fsp); in fc_fcp_timeout()
1437 else if (fsp->state & FC_SRB_RCV_STATUS) in fc_fcp_timeout()
1438 fc_fcp_complete_locked(fsp); in fc_fcp_timeout()
1440 fc_fcp_recovery(fsp, FC_TIMED_OUT); in fc_fcp_timeout()
1441 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; in fc_fcp_timeout()
1443 fc_fcp_unlock_pkt(fsp); in fc_fcp_timeout()
1450 static void fc_fcp_rec(struct fc_fcp_pkt *fsp) in fc_fcp_rec() argument
1457 lport = fsp->lp; in fc_fcp_rec()
1458 rport = fsp->rport; in fc_fcp_rec()
1460 if (!fsp->seq_ptr || rpriv->rp_state != RPORT_ST_READY) { in fc_fcp_rec()
1461 fsp->status_code = FC_HRD_ERROR; in fc_fcp_rec()
1462 fsp->io_status = 0; in fc_fcp_rec()
1463 fc_fcp_complete_locked(fsp); in fc_fcp_rec()
1471 fr_seq(fp) = fsp->seq_ptr; in fc_fcp_rec()
1476 fc_fcp_rec_resp, fsp, in fc_fcp_rec()
1478 fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */ in fc_fcp_rec()
1482 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) in fc_fcp_rec()
1483 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_fcp_rec()
1485 fc_fcp_recovery(fsp, FC_TIMED_OUT); in fc_fcp_rec()
1501 struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)arg; in fc_fcp_rec_resp() local
1512 fc_fcp_rec_error(fsp, fp); in fc_fcp_rec_resp()
1516 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_rec_resp()
1519 fsp->recov_retry = 0; in fc_fcp_rec_resp()
1525 FC_FCP_DBG(fsp, in fc_fcp_rec_resp()
1527 fsp->rport->port_id, rjt->er_reason, in fc_fcp_rec_resp()
1531 FC_FCP_DBG(fsp, "device does not support REC\n"); in fc_fcp_rec_resp()
1532 rpriv = fsp->rport->dd_data; in fc_fcp_rec_resp()
1542 FC_FCP_DBG(fsp, "device %x REC reject %d/%d\n", in fc_fcp_rec_resp()
1543 fsp->rport->port_id, rjt->er_reason, in fc_fcp_rec_resp()
1552 struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr); in fc_fcp_rec_resp()
1554 fsp->state |= FC_SRB_ABORTED; in fc_fcp_rec_resp()
1555 fc_fcp_retry_cmd(fsp, FC_TRANS_RESET); in fc_fcp_rec_resp()
1558 fc_fcp_recovery(fsp, FC_TRANS_RESET); in fc_fcp_rec_resp()
1562 if (fsp->state & FC_SRB_ABORTED) in fc_fcp_rec_resp()
1565 data_dir = fsp->cmd->sc_data_direction; in fc_fcp_rec_resp()
1588 } else if (fsp->xfer_contig_end == offset) { in fc_fcp_rec_resp()
1591 offset = fsp->xfer_contig_end; in fc_fcp_rec_resp()
1594 fc_fcp_srr(fsp, r_ctl, offset); in fc_fcp_rec_resp()
1600 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_fcp_rec_resp()
1621 if (offset < fsp->data_len) in fc_fcp_rec_resp()
1623 } else if (offset == fsp->xfer_contig_end) { in fc_fcp_rec_resp()
1625 } else if (fsp->xfer_contig_end < offset) { in fc_fcp_rec_resp()
1626 offset = fsp->xfer_contig_end; in fc_fcp_rec_resp()
1628 fc_fcp_srr(fsp, r_ctl, offset); in fc_fcp_rec_resp()
1632 fc_fcp_unlock_pkt(fsp); in fc_fcp_rec_resp()
1634 fc_fcp_pkt_release(fsp); /* drop hold for outstanding REC */ in fc_fcp_rec_resp()
1643 static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_rec_error() argument
1647 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_rec_error()
1652 FC_FCP_DBG(fsp, "REC %p fid %6.6x exchange closed\n", in fc_fcp_rec_error()
1653 fsp, fsp->rport->port_id); in fc_fcp_rec_error()
1654 fc_fcp_retry_cmd(fsp, FC_ERROR); in fc_fcp_rec_error()
1658 FC_FCP_DBG(fsp, "REC %p fid %6.6x error unexpected error %d\n", in fc_fcp_rec_error()
1659 fsp, fsp->rport->port_id, error); in fc_fcp_rec_error()
1660 fsp->status_code = FC_CMD_PLOGO; in fc_fcp_rec_error()
1668 FC_FCP_DBG(fsp, "REC %p fid %6.6x exchange timeout retry %d/%d\n", in fc_fcp_rec_error()
1669 fsp, fsp->rport->port_id, fsp->recov_retry, in fc_fcp_rec_error()
1671 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) in fc_fcp_rec_error()
1672 fc_fcp_rec(fsp); in fc_fcp_rec_error()
1674 fc_fcp_recovery(fsp, FC_ERROR); in fc_fcp_rec_error()
1677 fc_fcp_unlock_pkt(fsp); in fc_fcp_rec_error()
1679 fc_fcp_pkt_release(fsp); /* drop hold for outstanding REC */ in fc_fcp_rec_error()
1687 static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) in fc_fcp_recovery() argument
1689 FC_FCP_DBG(fsp, "start recovery code %x\n", code); in fc_fcp_recovery()
1690 fsp->status_code = code; in fc_fcp_recovery()
1691 fsp->cdb_status = 0; in fc_fcp_recovery()
1692 fsp->io_status = 0; in fc_fcp_recovery()
1697 fc_fcp_send_abort(fsp); in fc_fcp_recovery()
1708 static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset) in fc_fcp_srr() argument
1710 struct fc_lport *lport = fsp->lp; in fc_fcp_srr()
1713 struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr); in fc_fcp_srr()
1718 rport = fsp->rport; in fc_fcp_srr()
1742 fsp, get_fsp_rec_tov(fsp)); in fc_fcp_srr()
1746 fsp->recov_seq = seq; in fc_fcp_srr()
1747 fsp->xfer_len = offset; in fc_fcp_srr()
1748 fsp->xfer_contig_end = offset; in fc_fcp_srr()
1749 fsp->state &= ~FC_SRB_RCV_STATUS; in fc_fcp_srr()
1750 fc_fcp_pkt_hold(fsp); /* hold for outstanding SRR */ in fc_fcp_srr()
1753 fc_fcp_retry_cmd(fsp, FC_TRANS_RESET); in fc_fcp_srr()
1764 struct fc_fcp_pkt *fsp = arg; in fc_fcp_srr_resp() local
1768 fc_fcp_srr_error(fsp, fp); in fc_fcp_srr_resp()
1772 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_srr_resp()
1784 fc_fcp_unlock_pkt(fsp); in fc_fcp_srr_resp()
1790 fsp->recov_retry = 0; in fc_fcp_srr_resp()
1791 fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp)); in fc_fcp_srr_resp()
1795 fc_fcp_recovery(fsp, FC_ERROR); in fc_fcp_srr_resp()
1798 fc_fcp_unlock_pkt(fsp); in fc_fcp_srr_resp()
1809 static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) in fc_fcp_srr_error() argument
1811 if (fc_fcp_lock_pkt(fsp)) in fc_fcp_srr_error()
1815 FC_FCP_DBG(fsp, "SRR timeout, retries %d\n", fsp->recov_retry); in fc_fcp_srr_error()
1816 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) in fc_fcp_srr_error()
1817 fc_fcp_rec(fsp); in fc_fcp_srr_error()
1819 fc_fcp_recovery(fsp, FC_TIMED_OUT); in fc_fcp_srr_error()
1822 FC_FCP_DBG(fsp, "SRR error, exchange closed\n"); in fc_fcp_srr_error()
1825 fc_fcp_retry_cmd(fsp, FC_ERROR); in fc_fcp_srr_error()
1828 fc_fcp_unlock_pkt(fsp); in fc_fcp_srr_error()
1830 fc_exch_done(fsp->recov_seq); in fc_fcp_srr_error()
1855 struct fc_fcp_pkt *fsp; in fc_queuecommand() local
1888 fsp = fc_fcp_pkt_alloc(lport, GFP_ATOMIC); in fc_queuecommand()
1889 if (fsp == NULL) { in fc_queuecommand()
1897 fsp->cmd = sc_cmd; /* save the cmd */ in fc_queuecommand()
1898 fsp->rport = rport; /* set the remote port ptr */ in fc_queuecommand()
1903 fsp->data_len = scsi_bufflen(sc_cmd); in fc_queuecommand()
1904 fsp->xfer_len = 0; in fc_queuecommand()
1910 fsp->req_flags = FC_SRB_READ; in fc_queuecommand()
1912 this_cpu_add(lport->stats->InputBytes, fsp->data_len); in fc_queuecommand()
1914 fsp->req_flags = FC_SRB_WRITE; in fc_queuecommand()
1916 this_cpu_add(lport->stats->OutputBytes, fsp->data_len); in fc_queuecommand()
1918 fsp->req_flags = 0; in fc_queuecommand()
1927 rval = fc_fcp_pkt_send(lport, fsp); in fc_queuecommand()
1929 fsp->state = FC_SRB_FREE; in fc_queuecommand()
1930 fc_fcp_pkt_release(fsp); in fc_queuecommand()
1945 static void fc_io_compl(struct fc_fcp_pkt *fsp) in fc_io_compl() argument
1953 fc_fcp_ddp_done(fsp); in fc_io_compl()
1955 fsp->state |= FC_SRB_COMPL; in fc_io_compl()
1956 if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) { in fc_io_compl()
1957 spin_unlock_bh(&fsp->scsi_pkt_lock); in fc_io_compl()
1958 del_timer_sync(&fsp->timer); in fc_io_compl()
1959 spin_lock_bh(&fsp->scsi_pkt_lock); in fc_io_compl()
1962 lport = fsp->lp; in fc_io_compl()
1972 sc_cmd = fsp->cmd; in fc_io_compl()
1973 libfc_priv(sc_cmd)->status = fsp->cdb_status; in fc_io_compl()
1974 switch (fsp->status_code) { in fc_io_compl()
1976 if (fsp->cdb_status == 0) { in fc_io_compl()
1981 if (fsp->scsi_resid) in fc_io_compl()
1982 libfc_priv(sc_cmd)->resid_len = fsp->scsi_resid; in fc_io_compl()
1988 sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; in fc_io_compl()
1992 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " in fc_io_compl()
1997 if ((fsp->cdb_status == 0) && !(fsp->req_flags & FC_SRB_READ)) { in fc_io_compl()
2002 if (fsp->state & FC_SRB_RCV_STATUS) { in fc_io_compl()
2005 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml" in fc_io_compl()
2013 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " in fc_io_compl()
2015 libfc_priv(sc_cmd)->resid_len = fsp->scsi_resid; in fc_io_compl()
2016 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; in fc_io_compl()
2023 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " in fc_io_compl()
2025 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; in fc_io_compl()
2029 FC_FCP_DBG(fsp, "Returning DID_TIME_OUT to scsi-ml " in fc_io_compl()
2032 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " in fc_io_compl()
2036 sc_cmd->result |= fsp->io_status; in fc_io_compl()
2039 FC_FCP_DBG(fsp, "Returning DID_RESET to scsi-ml " in fc_io_compl()
2044 FC_FCP_DBG(fsp, "Returning DID_SOFT_ERROR to scsi-ml " in fc_io_compl()
2049 FC_FCP_DBG(fsp, "Returning DID_NO_CONNECT to scsi-ml " in fc_io_compl()
2054 FC_FCP_DBG(fsp, "Returning DID_PARITY to scsi-ml " in fc_io_compl()
2059 FC_FCP_DBG(fsp, "Returning DID_BUS_BUSY to scsi-ml " in fc_io_compl()
2061 sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; in fc_io_compl()
2064 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " in fc_io_compl()
2070 if (lport->state != LPORT_ST_READY && fsp->status_code != FC_COMPLETE) in fc_io_compl()
2074 list_del(&fsp->list); in fc_io_compl()
2075 libfc_priv(sc_cmd)->fsp = NULL; in fc_io_compl()
2080 fc_fcp_pkt_release(fsp); in fc_io_compl()
2092 struct fc_fcp_pkt *fsp; in fc_eh_abort() local
2111 fsp = libfc_priv(sc_cmd)->fsp; in fc_eh_abort()
2112 if (!fsp) { in fc_eh_abort()
2118 fc_fcp_pkt_hold(fsp); in fc_eh_abort()
2121 if (fc_fcp_lock_pkt(fsp)) { in fc_eh_abort()
2127 rc = fc_fcp_pkt_abort(fsp); in fc_eh_abort()
2128 fc_fcp_unlock_pkt(fsp); in fc_eh_abort()
2131 fc_fcp_pkt_release(fsp); in fc_eh_abort()
2146 struct fc_fcp_pkt *fsp; in fc_eh_device_reset() local
2162 fsp = fc_fcp_pkt_alloc(lport, GFP_NOIO); in fc_eh_device_reset()
2163 if (fsp == NULL) { in fc_eh_device_reset()
2173 fsp->rport = rport; /* set the remote port ptr */ in fc_eh_device_reset()
2178 rc = fc_lun_reset(lport, fsp, scmd_id(sc_cmd), sc_cmd->device->lun); in fc_eh_device_reset()
2179 fsp->state = FC_SRB_FREE; in fc_eh_device_reset()
2180 fc_fcp_pkt_release(fsp); in fc_eh_device_reset()