aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-07-27 14:32:06 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-28 03:45:19 -0400
commit744469542951d32979a8dcb1dbed560bfed1745e (patch)
treed6be8757d3804b19fcc7cd498e215d8a232d2904 /drivers/scsi
parent6c5a7ce4f176b641fd11e59be4df31ee3e6202dd (diff)
[SCSI] bnx2fc: REC/SRR link service request and response handling
Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h12
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_els.c417
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c9
3 files changed, 421 insertions, 17 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 45d5391229e..cd506c0ee2f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -141,6 +141,9 @@
141 141
142#define BNX2FC_RNID_HBA 0x7 142#define BNX2FC_RNID_HBA 0x7
143 143
144#define SRR_RETRY_COUNT 5
145#define REC_RETRY_COUNT 1
146
144/* bnx2fc driver uses only one instance of fcoe_percpu_s */ 147/* bnx2fc driver uses only one instance of fcoe_percpu_s */
145extern struct fcoe_percpu_s bnx2fc_global; 148extern struct fcoe_percpu_s bnx2fc_global;
146 149
@@ -386,6 +389,7 @@ struct bnx2fc_cmd {
386 struct completion tm_done; 389 struct completion tm_done;
387 int wait_for_comp; 390 int wait_for_comp;
388 u16 xid; 391 u16 xid;
392 struct fcoe_err_report_entry err_entry;
389 struct fcoe_task_ctx_entry *task; 393 struct fcoe_task_ctx_entry *task;
390 struct io_bdt *bd_tbl; 394 struct io_bdt *bd_tbl;
391 struct fcp_rsp *rsp; 395 struct fcp_rsp *rsp;
@@ -402,6 +406,12 @@ struct bnx2fc_cmd {
402#define BNX2FC_FLAG_IO_COMPL 0x9 406#define BNX2FC_FLAG_IO_COMPL 0x9
403#define BNX2FC_FLAG_ELS_DONE 0xa 407#define BNX2FC_FLAG_ELS_DONE 0xa
404#define BNX2FC_FLAG_ELS_TIMEOUT 0xb 408#define BNX2FC_FLAG_ELS_TIMEOUT 0xb
409#define BNX2FC_FLAG_CMD_LOST 0xc
410#define BNX2FC_FLAG_SRR_SENT 0xd
411 u8 rec_retry;
412 u8 srr_retry;
413 u32 srr_offset;
414 u8 srr_rctl;
405 u32 fcp_resid; 415 u32 fcp_resid;
406 u32 fcp_rsp_len; 416 u32 fcp_rsp_len;
407 u32 fcp_sns_len; 417 u32 fcp_sns_len;
@@ -432,6 +442,7 @@ struct bnx2fc_unsol_els {
432 442
433 443
434 444
445struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt);
435struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type); 446struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type);
436void bnx2fc_cmd_release(struct kref *ref); 447void bnx2fc_cmd_release(struct kref *ref);
437int bnx2fc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd); 448int bnx2fc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd);
@@ -522,6 +533,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt,
522 unsigned char *buf, 533 unsigned char *buf,
523 u32 frame_len, u16 l2_oxid); 534 u32 frame_len, u16 l2_oxid);
524int bnx2fc_send_stat_req(struct bnx2fc_hba *hba); 535int bnx2fc_send_stat_req(struct bnx2fc_hba *hba);
536int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, struct bnx2fc_cmd *io_req);
525int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req); 537int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req);
526int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl); 538int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl);
527void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnup_req, 539void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnup_req,
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c
index 75d0b6ac6c2..296c6aa62ac 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -253,25 +253,409 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
253 return rc; 253 return rc;
254} 254}
255 255
256void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
257{
258 struct bnx2fc_mp_req *mp_req;
259 struct fc_frame_header *fc_hdr, *fh;
260 struct bnx2fc_cmd *srr_req;
261 struct bnx2fc_cmd *orig_io_req;
262 struct fc_frame *fp;
263 unsigned char *buf;
264 void *resp_buf;
265 u32 resp_len, hdr_len;
266 u8 opcode;
267 int rc = 0;
268
269 orig_io_req = cb_arg->aborted_io_req;
270 srr_req = cb_arg->io_req;
271 if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
272 BNX2FC_IO_DBG(srr_req, "srr_compl: xid - 0x%x completed",
273 orig_io_req->xid);
274 goto srr_compl_done;
275 }
276 if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
277 BNX2FC_IO_DBG(srr_req, "rec abts in prog "
278 "orig_io - 0x%x\n",
279 orig_io_req->xid);
280 goto srr_compl_done;
281 }
282 if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) {
283 /* SRR timedout */
284 BNX2FC_IO_DBG(srr_req, "srr timed out, abort "
285 "orig_io - 0x%x\n",
286 orig_io_req->xid);
287 rc = bnx2fc_initiate_abts(srr_req);
288 if (rc != SUCCESS) {
289 BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
290 "failed. issue cleanup\n");
291 bnx2fc_initiate_cleanup(srr_req);
292 }
293 orig_io_req->srr_retry++;
294 if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
295 struct bnx2fc_rport *tgt = orig_io_req->tgt;
296 spin_unlock_bh(&tgt->tgt_lock);
297 rc = bnx2fc_send_srr(orig_io_req,
298 orig_io_req->srr_offset,
299 orig_io_req->srr_rctl);
300 spin_lock_bh(&tgt->tgt_lock);
301 if (!rc)
302 goto srr_compl_done;
303 }
304
305 rc = bnx2fc_initiate_abts(orig_io_req);
306 if (rc != SUCCESS) {
307 BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
308 "failed xid = 0x%x. issue cleanup\n",
309 orig_io_req->xid);
310 bnx2fc_initiate_cleanup(orig_io_req);
311 }
312 goto srr_compl_done;
313 }
314 mp_req = &(srr_req->mp_req);
315 fc_hdr = &(mp_req->resp_fc_hdr);
316 resp_len = mp_req->resp_len;
317 resp_buf = mp_req->resp_buf;
318
319 hdr_len = sizeof(*fc_hdr);
320 buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
321 if (!buf) {
322 printk(KERN_ERR PFX "srr buf: mem alloc failure\n");
323 goto srr_compl_done;
324 }
325 memcpy(buf, fc_hdr, hdr_len);
326 memcpy(buf + hdr_len, resp_buf, resp_len);
327
328 fp = fc_frame_alloc(NULL, resp_len);
329 if (!fp) {
330 printk(KERN_ERR PFX "fc_frame_alloc failure\n");
331 goto free_buf;
332 }
333
334 fh = (struct fc_frame_header *) fc_frame_header_get(fp);
335 /* Copy FC Frame header and payload into the frame */
336 memcpy(fh, buf, hdr_len + resp_len);
337
338 opcode = fc_frame_payload_op(fp);
339 switch (opcode) {
340 case ELS_LS_ACC:
341 BNX2FC_IO_DBG(srr_req, "SRR success\n");
342 break;
343 case ELS_LS_RJT:
344 BNX2FC_IO_DBG(srr_req, "SRR rejected\n");
345 rc = bnx2fc_initiate_abts(orig_io_req);
346 if (rc != SUCCESS) {
347 BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
348 "failed xid = 0x%x. issue cleanup\n",
349 orig_io_req->xid);
350 bnx2fc_initiate_cleanup(orig_io_req);
351 }
352 break;
353 default:
354 BNX2FC_IO_DBG(srr_req, "srr compl - invalid opcode = %d\n",
355 opcode);
356 break;
357 }
358 fc_frame_free(fp);
359free_buf:
360 kfree(buf);
361srr_compl_done:
362 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
363}
364
365void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
366{
367 struct bnx2fc_cmd *orig_io_req, *new_io_req;
368 struct bnx2fc_cmd *rec_req;
369 struct bnx2fc_mp_req *mp_req;
370 struct fc_frame_header *fc_hdr, *fh;
371 struct fc_els_ls_rjt *rjt;
372 struct fc_els_rec_acc *acc;
373 struct bnx2fc_rport *tgt;
374 struct fcoe_err_report_entry *err_entry;
375 struct scsi_cmnd *sc_cmd;
376 enum fc_rctl r_ctl;
377 unsigned char *buf;
378 void *resp_buf;
379 struct fc_frame *fp;
380 u8 opcode;
381 u32 offset;
382 u32 e_stat;
383 u32 resp_len, hdr_len;
384 int rc = 0;
385 bool send_seq_clnp = false;
386 bool abort_io = false;
387
388 BNX2FC_MISC_DBG("Entered rec_compl callback\n");
389 rec_req = cb_arg->io_req;
390 orig_io_req = cb_arg->aborted_io_req;
391 BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid);
392 tgt = orig_io_req->tgt;
393
394 if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
395 BNX2FC_IO_DBG(rec_req, "completed"
396 "orig_io - 0x%x\n",
397 orig_io_req->xid);
398 goto rec_compl_done;
399 }
400 if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
401 BNX2FC_IO_DBG(rec_req, "abts in prog "
402 "orig_io - 0x%x\n",
403 orig_io_req->xid);
404 goto rec_compl_done;
405 }
406 /* Handle REC timeout case */
407 if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) {
408 BNX2FC_IO_DBG(rec_req, "timed out, abort "
409 "orig_io - 0x%x\n",
410 orig_io_req->xid);
411 /* els req is timed out. send abts for els */
412 rc = bnx2fc_initiate_abts(rec_req);
413 if (rc != SUCCESS) {
414 BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
415 "failed. issue cleanup\n");
416 bnx2fc_initiate_cleanup(rec_req);
417 }
418 orig_io_req->rec_retry++;
419 /* REC timedout. send ABTS to the orig IO req */
420 if (orig_io_req->rec_retry <= REC_RETRY_COUNT) {
421 spin_unlock_bh(&tgt->tgt_lock);
422 rc = bnx2fc_send_rec(orig_io_req);
423 spin_lock_bh(&tgt->tgt_lock);
424 if (!rc)
425 goto rec_compl_done;
426 }
427 rc = bnx2fc_initiate_abts(orig_io_req);
428 if (rc != SUCCESS) {
429 BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
430 "failed xid = 0x%x. issue cleanup\n",
431 orig_io_req->xid);
432 bnx2fc_initiate_cleanup(orig_io_req);
433 }
434 goto rec_compl_done;
435 }
436 mp_req = &(rec_req->mp_req);
437 fc_hdr = &(mp_req->resp_fc_hdr);
438 resp_len = mp_req->resp_len;
439 acc = resp_buf = mp_req->resp_buf;
440
441 hdr_len = sizeof(*fc_hdr);
442
443 buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
444 if (!buf) {
445 printk(KERN_ERR PFX "rec buf: mem alloc failure\n");
446 goto rec_compl_done;
447 }
448 memcpy(buf, fc_hdr, hdr_len);
449 memcpy(buf + hdr_len, resp_buf, resp_len);
450
451 fp = fc_frame_alloc(NULL, resp_len);
452 if (!fp) {
453 printk(KERN_ERR PFX "fc_frame_alloc failure\n");
454 goto free_buf;
455 }
456
457 fh = (struct fc_frame_header *) fc_frame_header_get(fp);
458 /* Copy FC Frame header and payload into the frame */
459 memcpy(fh, buf, hdr_len + resp_len);
460
461 opcode = fc_frame_payload_op(fp);
462 if (opcode == ELS_LS_RJT) {
463 BNX2FC_IO_DBG(rec_req, "opcode is RJT\n");
464 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
465 if ((rjt->er_reason == ELS_RJT_LOGIC ||
466 rjt->er_reason == ELS_RJT_UNAB) &&
467 rjt->er_explan == ELS_EXPL_OXID_RXID) {
468 BNX2FC_IO_DBG(rec_req, "handle CMD LOST case\n");
469 new_io_req = bnx2fc_cmd_alloc(tgt);
470 if (!new_io_req)
471 goto abort_io;
472 new_io_req->sc_cmd = orig_io_req->sc_cmd;
473 /* cleanup orig_io_req that is with the FW */
474 set_bit(BNX2FC_FLAG_CMD_LOST,
475 &orig_io_req->req_flags);
476 bnx2fc_initiate_cleanup(orig_io_req);
477 /* Post a new IO req with the same sc_cmd */
478 BNX2FC_IO_DBG(rec_req, "Post IO request again\n");
479 spin_unlock_bh(&tgt->tgt_lock);
480 rc = bnx2fc_post_io_req(tgt, new_io_req);
481 spin_lock_bh(&tgt->tgt_lock);
482 if (!rc)
483 goto free_frame;
484 BNX2FC_IO_DBG(rec_req, "REC: io post err\n");
485 }
486abort_io:
487 rc = bnx2fc_initiate_abts(orig_io_req);
488 if (rc != SUCCESS) {
489 BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
490 "failed. issue cleanup\n");
491 bnx2fc_initiate_cleanup(orig_io_req);
492 }
493 } else if (opcode == ELS_LS_ACC) {
494 /* REVISIT: Check if the exchange is already aborted */
495 offset = ntohl(acc->reca_fc4value);
496 e_stat = ntohl(acc->reca_e_stat);
497 if (e_stat & ESB_ST_SEQ_INIT) {
498 BNX2FC_IO_DBG(rec_req, "target has the seq init\n");
499 goto free_frame;
500 }
501 BNX2FC_IO_DBG(rec_req, "e_stat = 0x%x, offset = 0x%x\n",
502 e_stat, offset);
503 /* Seq initiative is with us */
504 err_entry = (struct fcoe_err_report_entry *)
505 &orig_io_req->err_entry;
506 sc_cmd = orig_io_req->sc_cmd;
507 if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
508 /* SCSI WRITE command */
509 if (offset == orig_io_req->data_xfer_len) {
510 BNX2FC_IO_DBG(rec_req, "WRITE - resp lost\n");
511 /* FCP_RSP lost */
512 r_ctl = FC_RCTL_DD_CMD_STATUS;
513 offset = 0;
514 } else {
515 /* start transmitting from offset */
516 BNX2FC_IO_DBG(rec_req, "XFER_RDY/DATA lost\n");
517 send_seq_clnp = true;
518 r_ctl = FC_RCTL_DD_DATA_DESC;
519 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
520 offset, r_ctl))
521 abort_io = true;
522 /* XFER_RDY */
523 }
524 } else {
525 /* SCSI READ command */
526 if (err_entry->data.rx_buf_off ==
527 orig_io_req->data_xfer_len) {
528 /* FCP_RSP lost */
529 BNX2FC_IO_DBG(rec_req, "READ - resp lost\n");
530 r_ctl = FC_RCTL_DD_CMD_STATUS;
531 offset = 0;
532 } else {
533 /* request retransmission from this offset */
534 send_seq_clnp = true;
535 offset = err_entry->data.rx_buf_off;
536 BNX2FC_IO_DBG(rec_req, "RD DATA lost\n");
537 /* FCP_DATA lost */
538 r_ctl = FC_RCTL_DD_SOL_DATA;
539 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
540 offset, r_ctl))
541 abort_io = true;
542 }
543 }
544 if (abort_io) {
545 rc = bnx2fc_initiate_abts(orig_io_req);
546 if (rc != SUCCESS) {
547 BNX2FC_IO_DBG(rec_req, "rec_compl:initiate_abts"
548 " failed. issue cleanup\n");
549 bnx2fc_initiate_cleanup(orig_io_req);
550 }
551 } else if (!send_seq_clnp) {
552 BNX2FC_IO_DBG(rec_req, "Send SRR - FCP_RSP\n");
553 spin_unlock_bh(&tgt->tgt_lock);
554 rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl);
555 spin_lock_bh(&tgt->tgt_lock);
556
557 if (rc) {
558 BNX2FC_IO_DBG(rec_req, "Unable to send SRR"
559 " IO will abort\n");
560 }
561 }
562 }
563free_frame:
564 fc_frame_free(fp);
565free_buf:
566 kfree(buf);
567rec_compl_done:
568 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
569 kfree(cb_arg);
570}
571
256int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req) 572int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req)
257{ 573{
258 /* 574 struct fc_els_rec rec;
259 * Dummy function to enable compiling individual patches. Real function 575 struct bnx2fc_rport *tgt = orig_io_req->tgt;
260 * is in the next patch. 576 struct fc_lport *lport = tgt->rdata->local_port;
261 */ 577 struct bnx2fc_els_cb_arg *cb_arg = NULL;
262 return 0; 578 u32 sid = tgt->sid;
579 u32 r_a_tov = lport->r_a_tov;
580 int rc;
581
582 BNX2FC_IO_DBG(orig_io_req, "Sending REC\n");
583 memset(&rec, 0, sizeof(rec));
584
585 cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
586 if (!cb_arg) {
587 printk(KERN_ERR PFX "Unable to allocate cb_arg for REC\n");
588 rc = -ENOMEM;
589 goto rec_err;
590 }
591 kref_get(&orig_io_req->refcount);
592
593 cb_arg->aborted_io_req = orig_io_req;
594
595 rec.rec_cmd = ELS_REC;
596 hton24(rec.rec_s_id, sid);
597 rec.rec_ox_id = htons(orig_io_req->xid);
598 rec.rec_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
599
600 rc = bnx2fc_initiate_els(tgt, ELS_REC, &rec, sizeof(rec),
601 bnx2fc_rec_compl, cb_arg,
602 r_a_tov);
603rec_err:
604 if (rc) {
605 BNX2FC_IO_DBG(orig_io_req, "REC failed - release\n");
606 spin_lock_bh(&tgt->tgt_lock);
607 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
608 spin_unlock_bh(&tgt->tgt_lock);
609 kfree(cb_arg);
610 }
611 return rc;
263} 612}
264 613
265int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl) 614int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl)
266{ 615{
267 /* 616 struct fcp_srr srr;
268 * Dummy function to enable compiling individual patches. Real function 617 struct bnx2fc_rport *tgt = orig_io_req->tgt;
269 * is in the next patch. 618 struct fc_lport *lport = tgt->rdata->local_port;
270 */ 619 struct bnx2fc_els_cb_arg *cb_arg = NULL;
271 return 0; 620 u32 r_a_tov = lport->r_a_tov;
272} 621 int rc;
273 622
623 BNX2FC_IO_DBG(orig_io_req, "Sending SRR\n");
624 memset(&srr, 0, sizeof(srr));
274 625
626 cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
627 if (!cb_arg) {
628 printk(KERN_ERR PFX "Unable to allocate cb_arg for SRR\n");
629 rc = -ENOMEM;
630 goto srr_err;
631 }
632 kref_get(&orig_io_req->refcount);
633
634 cb_arg->aborted_io_req = orig_io_req;
635
636 srr.srr_op = ELS_SRR;
637 srr.srr_ox_id = htons(orig_io_req->xid);
638 srr.srr_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
639 srr.srr_rel_off = htonl(offset);
640 srr.srr_r_ctl = r_ctl;
641 orig_io_req->srr_offset = offset;
642 orig_io_req->srr_rctl = r_ctl;
643
644 rc = bnx2fc_initiate_els(tgt, ELS_SRR, &srr, sizeof(srr),
645 bnx2fc_srr_compl, cb_arg,
646 r_a_tov);
647srr_err:
648 if (rc) {
649 BNX2FC_IO_DBG(orig_io_req, "SRR failed - release\n");
650 spin_lock_bh(&tgt->tgt_lock);
651 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
652 spin_unlock_bh(&tgt->tgt_lock);
653 kfree(cb_arg);
654 } else
655 set_bit(BNX2FC_FLAG_SRR_SENT, &orig_io_req->req_flags);
656
657 return rc;
658}
275 659
276static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, 660static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
277 void *data, u32 data_len, 661 void *data, u32 data_len,
@@ -362,9 +746,14 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
362 did = tgt->rport->port_id; 746 did = tgt->rport->port_id;
363 sid = tgt->sid; 747 sid = tgt->sid;
364 748
365 __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid, 749 if (op == ELS_SRR)
366 FC_TYPE_ELS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ | 750 __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS4_REQ, did, sid,
367 FC_FC_SEQ_INIT, 0); 751 FC_TYPE_FCP, FC_FC_FIRST_SEQ |
752 FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
753 else
754 __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid,
755 FC_TYPE_ELS, FC_FC_FIRST_SEQ |
756 FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
368 757
369 /* Obtain exchange id */ 758 /* Obtain exchange id */
370 xid = els_req->xid; 759 xid = els_req->xid;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 9820d3060cd..797b0051b6f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -18,8 +18,6 @@ static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len,
18 int bd_index); 18 int bd_index);
19static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); 19static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req);
20static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); 20static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req);
21static int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
22 struct bnx2fc_cmd *io_req);
23static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req); 21static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req);
24static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); 22static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req);
25static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, 23static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
@@ -218,6 +216,11 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
218 return; 216 return;
219 217
220 BNX2FC_IO_DBG(io_req, "scsi_done. err_code = 0x%x\n", err_code); 218 BNX2FC_IO_DBG(io_req, "scsi_done. err_code = 0x%x\n", err_code);
219 if (test_bit(BNX2FC_FLAG_CMD_LOST, &io_req->req_flags)) {
220 /* Do not call scsi done for this IO */
221 return;
222 }
223
221 bnx2fc_unmap_sg_list(io_req); 224 bnx2fc_unmap_sg_list(io_req);
222 io_req->sc_cmd = NULL; 225 io_req->sc_cmd = NULL;
223 if (!sc_cmd) { 226 if (!sc_cmd) {
@@ -1902,7 +1905,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
1902 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1905 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1903} 1906}
1904 1907
1905static int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, 1908int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
1906 struct bnx2fc_cmd *io_req) 1909 struct bnx2fc_cmd *io_req)
1907{ 1910{
1908 struct fcoe_task_ctx_entry *task; 1911 struct fcoe_task_ctx_entry *task;