diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
| commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
| tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/scsi/libfc | |
| parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) | |
Patched in Tegra support.
Diffstat (limited to 'drivers/scsi/libfc')
| -rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_elsct.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 170 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 44 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_frame.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_libfc.c | 9 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_libfc.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 412 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_npiv.c | 1 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 11 |
10 files changed, 184 insertions, 486 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 8e561e6a557..b9cb8140b39 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/err.h> | 37 | #include <linux/err.h> |
| 38 | #include <linux/export.h> | ||
| 39 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
| 40 | 39 | ||
| 41 | #include <scsi/fc/fc_gs.h> | 40 | #include <scsi/fc/fc_gs.h> |
| @@ -61,7 +60,7 @@ static void fc_disc_restart(struct fc_disc *); | |||
| 61 | * Locking Note: This function expects that the lport mutex is locked before | 60 | * Locking Note: This function expects that the lport mutex is locked before |
| 62 | * calling it. | 61 | * calling it. |
| 63 | */ | 62 | */ |
| 64 | static void fc_disc_stop_rports(struct fc_disc *disc) | 63 | void fc_disc_stop_rports(struct fc_disc *disc) |
| 65 | { | 64 | { |
| 66 | struct fc_lport *lport; | 65 | struct fc_lport *lport; |
| 67 | struct fc_rport_priv *rdata; | 66 | struct fc_rport_priv *rdata; |
| @@ -337,13 +336,6 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) | |||
| 337 | schedule_delayed_work(&disc->disc_work, delay); | 336 | schedule_delayed_work(&disc->disc_work, delay); |
| 338 | } else | 337 | } else |
| 339 | fc_disc_done(disc, DISC_EV_FAILED); | 338 | fc_disc_done(disc, DISC_EV_FAILED); |
| 340 | } else if (PTR_ERR(fp) == -FC_EX_CLOSED) { | ||
| 341 | /* | ||
| 342 | * if discovery fails due to lport reset, clear | ||
| 343 | * pending flag so that subsequent discovery can | ||
| 344 | * continue | ||
| 345 | */ | ||
| 346 | disc->pending = 0; | ||
| 347 | } | 339 | } |
| 348 | } | 340 | } |
| 349 | 341 | ||
| @@ -689,7 +681,7 @@ static int fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp) | |||
| 689 | * fc_disc_stop() - Stop discovery for a given lport | 681 | * fc_disc_stop() - Stop discovery for a given lport |
| 690 | * @lport: The local port that discovery should stop on | 682 | * @lport: The local port that discovery should stop on |
| 691 | */ | 683 | */ |
| 692 | static void fc_disc_stop(struct fc_lport *lport) | 684 | void fc_disc_stop(struct fc_lport *lport) |
| 693 | { | 685 | { |
| 694 | struct fc_disc *disc = &lport->disc; | 686 | struct fc_disc *disc = &lport->disc; |
| 695 | 687 | ||
| @@ -705,7 +697,7 @@ static void fc_disc_stop(struct fc_lport *lport) | |||
| 705 | * This function will block until discovery has been | 697 | * This function will block until discovery has been |
| 706 | * completely stopped and all rports have been deleted. | 698 | * completely stopped and all rports have been deleted. |
| 707 | */ | 699 | */ |
| 708 | static void fc_disc_stop_final(struct fc_lport *lport) | 700 | void fc_disc_stop_final(struct fc_lport *lport) |
| 709 | { | 701 | { |
| 710 | fc_disc_stop(lport); | 702 | fc_disc_stop(lport); |
| 711 | lport->tt.rport_flush_queue(); | 703 | lport->tt.rport_flush_queue(); |
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c index c2384d50147..9b25969e2ad 100644 --- a/drivers/scsi/libfc/fc_elsct.c +++ b/drivers/scsi/libfc/fc_elsct.c | |||
| @@ -21,14 +21,12 @@ | |||
| 21 | * Provide interface to send ELS/CT FC frames | 21 | * Provide interface to send ELS/CT FC frames |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include <linux/export.h> | ||
| 25 | #include <asm/unaligned.h> | 24 | #include <asm/unaligned.h> |
| 26 | #include <scsi/fc/fc_gs.h> | 25 | #include <scsi/fc/fc_gs.h> |
| 27 | #include <scsi/fc/fc_ns.h> | 26 | #include <scsi/fc/fc_ns.h> |
| 28 | #include <scsi/fc/fc_els.h> | 27 | #include <scsi/fc/fc_els.h> |
| 29 | #include <scsi/libfc.h> | 28 | #include <scsi/libfc.h> |
| 30 | #include <scsi/fc_encode.h> | 29 | #include <scsi/fc_encode.h> |
| 31 | #include "fc_libfc.h" | ||
| 32 | 30 | ||
| 33 | /** | 31 | /** |
| 34 | * fc_elsct_send() - Send an ELS or CT frame | 32 | * fc_elsct_send() - Send an ELS or CT frame |
| @@ -56,7 +54,8 @@ struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did, | |||
| 56 | rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type); | 54 | rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type); |
| 57 | else { | 55 | else { |
| 58 | /* CT requests */ | 56 | /* CT requests */ |
| 59 | rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did); | 57 | rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type); |
| 58 | did = FC_FID_DIR_SERV; | ||
| 60 | } | 59 | } |
| 61 | 60 | ||
| 62 | if (rc) { | 61 | if (rc) { |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index c772d8d2715..d261e982a2f 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/timer.h> | 26 | #include <linux/timer.h> |
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
| 29 | #include <linux/export.h> | ||
| 30 | 29 | ||
| 31 | #include <scsi/fc/fc_fc2.h> | 30 | #include <scsi/fc/fc_fc2.h> |
| 32 | 31 | ||
| @@ -66,15 +65,16 @@ static struct workqueue_struct *fc_exch_workqueue; | |||
| 66 | * assigned range of exchanges to per cpu pool. | 65 | * assigned range of exchanges to per cpu pool. |
| 67 | */ | 66 | */ |
| 68 | struct fc_exch_pool { | 67 | struct fc_exch_pool { |
| 69 | spinlock_t lock; | ||
| 70 | struct list_head ex_list; | ||
| 71 | u16 next_index; | 68 | u16 next_index; |
| 72 | u16 total_exches; | 69 | u16 total_exches; |
| 73 | 70 | ||
| 74 | /* two cache of free slot in exch array */ | 71 | /* two cache of free slot in exch array */ |
| 75 | u16 left; | 72 | u16 left; |
| 76 | u16 right; | 73 | u16 right; |
| 77 | } ____cacheline_aligned_in_smp; | 74 | |
| 75 | spinlock_t lock; | ||
| 76 | struct list_head ex_list; | ||
| 77 | }; | ||
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * struct fc_exch_mgr - The Exchange Manager (EM). | 80 | * struct fc_exch_mgr - The Exchange Manager (EM). |
| @@ -91,14 +91,19 @@ struct fc_exch_pool { | |||
| 91 | * It manages the allocation of exchange IDs. | 91 | * It manages the allocation of exchange IDs. |
| 92 | */ | 92 | */ |
| 93 | struct fc_exch_mgr { | 93 | struct fc_exch_mgr { |
| 94 | struct fc_exch_pool __percpu *pool; | ||
| 95 | mempool_t *ep_pool; | ||
| 96 | enum fc_class class; | 94 | enum fc_class class; |
| 97 | struct kref kref; | 95 | struct kref kref; |
| 98 | u16 min_xid; | 96 | u16 min_xid; |
| 99 | u16 max_xid; | 97 | u16 max_xid; |
| 98 | mempool_t *ep_pool; | ||
| 100 | u16 pool_max_index; | 99 | u16 pool_max_index; |
| 100 | struct fc_exch_pool *pool; | ||
| 101 | 101 | ||
| 102 | /* | ||
| 103 | * currently exchange mgr stats are updated but not used. | ||
| 104 | * either stats can be expose via sysfs or remove them | ||
| 105 | * all together if not used XXX | ||
| 106 | */ | ||
| 102 | struct { | 107 | struct { |
| 103 | atomic_t no_free_exch; | 108 | atomic_t no_free_exch; |
| 104 | atomic_t no_free_exch_xid; | 109 | atomic_t no_free_exch_xid; |
| @@ -119,7 +124,7 @@ struct fc_exch_mgr { | |||
| 119 | * for each anchor to determine if that EM should be used. The last | 124 | * for each anchor to determine if that EM should be used. The last |
| 120 | * anchor in the list will always match to handle any exchanges not | 125 | * anchor in the list will always match to handle any exchanges not |
| 121 | * handled by other EMs. The non-default EMs would be added to the | 126 | * handled by other EMs. The non-default EMs would be added to the |
| 122 | * anchor list by HW that provides offloads. | 127 | * anchor list by HW that provides FCoE offloads. |
| 123 | */ | 128 | */ |
| 124 | struct fc_exch_mgr_anchor { | 129 | struct fc_exch_mgr_anchor { |
| 125 | struct list_head ema_list; | 130 | struct list_head ema_list; |
| @@ -334,52 +339,6 @@ static void fc_exch_release(struct fc_exch *ep) | |||
| 334 | } | 339 | } |
| 335 | 340 | ||
| 336 | /** | 341 | /** |
| 337 | * fc_exch_timer_cancel() - cancel exch timer | ||
| 338 | * @ep: The exchange whose timer to be canceled | ||
| 339 | */ | ||
| 340 | static inline void fc_exch_timer_cancel(struct fc_exch *ep) | ||
| 341 | { | ||
| 342 | if (cancel_delayed_work(&ep->timeout_work)) { | ||
| 343 | FC_EXCH_DBG(ep, "Exchange timer canceled\n"); | ||
| 344 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | /** | ||
| 349 | * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the | ||
| 350 | * the exchange lock held | ||
| 351 | * @ep: The exchange whose timer will start | ||
| 352 | * @timer_msec: The timeout period | ||
| 353 | * | ||
| 354 | * Used for upper level protocols to time out the exchange. | ||
| 355 | * The timer is cancelled when it fires or when the exchange completes. | ||
| 356 | */ | ||
| 357 | static inline void fc_exch_timer_set_locked(struct fc_exch *ep, | ||
| 358 | unsigned int timer_msec) | ||
| 359 | { | ||
| 360 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) | ||
| 361 | return; | ||
| 362 | |||
| 363 | FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); | ||
| 364 | |||
| 365 | if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, | ||
| 366 | msecs_to_jiffies(timer_msec))) | ||
| 367 | fc_exch_hold(ep); /* hold for timer */ | ||
| 368 | } | ||
| 369 | |||
| 370 | /** | ||
| 371 | * fc_exch_timer_set() - Lock the exchange and set the timer | ||
| 372 | * @ep: The exchange whose timer will start | ||
| 373 | * @timer_msec: The timeout period | ||
| 374 | */ | ||
| 375 | static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) | ||
| 376 | { | ||
| 377 | spin_lock_bh(&ep->ex_lock); | ||
| 378 | fc_exch_timer_set_locked(ep, timer_msec); | ||
| 379 | spin_unlock_bh(&ep->ex_lock); | ||
| 380 | } | ||
| 381 | |||
| 382 | /** | ||
| 383 | * fc_exch_done_locked() - Complete an exchange with the exchange lock held | 342 | * fc_exch_done_locked() - Complete an exchange with the exchange lock held |
| 384 | * @ep: The exchange that is complete | 343 | * @ep: The exchange that is complete |
| 385 | */ | 344 | */ |
| @@ -400,7 +359,8 @@ static int fc_exch_done_locked(struct fc_exch *ep) | |||
| 400 | 359 | ||
| 401 | if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { | 360 | if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { |
| 402 | ep->state |= FC_EX_DONE; | 361 | ep->state |= FC_EX_DONE; |
| 403 | fc_exch_timer_cancel(ep); | 362 | if (cancel_delayed_work(&ep->timeout_work)) |
| 363 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
| 404 | rc = 0; | 364 | rc = 0; |
| 405 | } | 365 | } |
| 406 | return rc; | 366 | return rc; |
| @@ -464,6 +424,40 @@ static void fc_exch_delete(struct fc_exch *ep) | |||
| 464 | } | 424 | } |
| 465 | 425 | ||
| 466 | /** | 426 | /** |
| 427 | * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the | ||
| 428 | * the exchange lock held | ||
| 429 | * @ep: The exchange whose timer will start | ||
| 430 | * @timer_msec: The timeout period | ||
| 431 | * | ||
| 432 | * Used for upper level protocols to time out the exchange. | ||
| 433 | * The timer is cancelled when it fires or when the exchange completes. | ||
| 434 | */ | ||
| 435 | static inline void fc_exch_timer_set_locked(struct fc_exch *ep, | ||
| 436 | unsigned int timer_msec) | ||
| 437 | { | ||
| 438 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) | ||
| 439 | return; | ||
| 440 | |||
| 441 | FC_EXCH_DBG(ep, "Exchange timer armed\n"); | ||
| 442 | |||
| 443 | if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, | ||
| 444 | msecs_to_jiffies(timer_msec))) | ||
| 445 | fc_exch_hold(ep); /* hold for timer */ | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 449 | * fc_exch_timer_set() - Lock the exchange and set the timer | ||
| 450 | * @ep: The exchange whose timer will start | ||
| 451 | * @timer_msec: The timeout period | ||
| 452 | */ | ||
| 453 | static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) | ||
| 454 | { | ||
| 455 | spin_lock_bh(&ep->ex_lock); | ||
| 456 | fc_exch_timer_set_locked(ep, timer_msec); | ||
| 457 | spin_unlock_bh(&ep->ex_lock); | ||
| 458 | } | ||
| 459 | |||
| 460 | /** | ||
| 467 | * fc_seq_send() - Send a frame using existing sequence/exchange pair | 461 | * fc_seq_send() - Send a frame using existing sequence/exchange pair |
| 468 | * @lport: The local port that the exchange will be sent on | 462 | * @lport: The local port that the exchange will be sent on |
| 469 | * @sp: The sequence to be sent | 463 | * @sp: The sequence to be sent |
| @@ -476,7 +470,6 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
| 476 | struct fc_frame_header *fh = fc_frame_header_get(fp); | 470 | struct fc_frame_header *fh = fc_frame_header_get(fp); |
| 477 | int error; | 471 | int error; |
| 478 | u32 f_ctl; | 472 | u32 f_ctl; |
| 479 | u8 fh_type = fh->fh_type; | ||
| 480 | 473 | ||
| 481 | ep = fc_seq_exch(sp); | 474 | ep = fc_seq_exch(sp); |
| 482 | WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); | 475 | WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); |
| @@ -501,7 +494,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
| 501 | */ | 494 | */ |
| 502 | error = lport->tt.frame_send(lport, fp); | 495 | error = lport->tt.frame_send(lport, fp); |
| 503 | 496 | ||
| 504 | if (fh_type == FC_TYPE_BLS) | 497 | if (fh->fh_type == FC_TYPE_BLS) |
| 505 | return error; | 498 | return error; |
| 506 | 499 | ||
| 507 | /* | 500 | /* |
| @@ -992,7 +985,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport, | |||
| 992 | /* | 985 | /* |
| 993 | * Update sequence_id based on incoming last | 986 | * Update sequence_id based on incoming last |
| 994 | * frame of sequence exchange. This is needed | 987 | * frame of sequence exchange. This is needed |
| 995 | * for FC target where DDP has been used | 988 | * for FCoE target where DDP has been used |
| 996 | * on target where, stack is indicated only | 989 | * on target where, stack is indicated only |
| 997 | * about last frame's (payload _header) header. | 990 | * about last frame's (payload _header) header. |
| 998 | * Whereas "seq_id" which is part of | 991 | * Whereas "seq_id" which is part of |
| @@ -1555,10 +1548,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) | |||
| 1555 | FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, | 1548 | FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, |
| 1556 | fc_exch_rctl_name(fh->fh_r_ctl)); | 1549 | fc_exch_rctl_name(fh->fh_r_ctl)); |
| 1557 | 1550 | ||
| 1558 | if (cancel_delayed_work_sync(&ep->timeout_work)) { | 1551 | if (cancel_delayed_work_sync(&ep->timeout_work)) |
| 1559 | FC_EXCH_DBG(ep, "Exchange timer canceled\n"); | ||
| 1560 | fc_exch_release(ep); /* release from pending timer hold */ | 1552 | fc_exch_release(ep); /* release from pending timer hold */ |
| 1561 | } | ||
| 1562 | 1553 | ||
| 1563 | spin_lock_bh(&ep->ex_lock); | 1554 | spin_lock_bh(&ep->ex_lock); |
| 1564 | switch (fh->fh_r_ctl) { | 1555 | switch (fh->fh_r_ctl) { |
| @@ -1650,10 +1641,9 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
| 1650 | case FC_RCTL_ACK_0: | 1641 | case FC_RCTL_ACK_0: |
| 1651 | break; | 1642 | break; |
| 1652 | default: | 1643 | default: |
| 1653 | if (ep) | 1644 | FC_EXCH_DBG(ep, "BLS rctl %x - %s received", |
| 1654 | FC_EXCH_DBG(ep, "BLS rctl %x - %s received", | 1645 | fh->fh_r_ctl, |
| 1655 | fh->fh_r_ctl, | 1646 | fc_exch_rctl_name(fh->fh_r_ctl)); |
| 1656 | fc_exch_rctl_name(fh->fh_r_ctl)); | ||
| 1657 | break; | 1647 | break; |
| 1658 | } | 1648 | } |
| 1659 | fc_frame_free(fp); | 1649 | fc_frame_free(fp); |
| @@ -1745,7 +1735,8 @@ static void fc_exch_reset(struct fc_exch *ep) | |||
| 1745 | spin_lock_bh(&ep->ex_lock); | 1735 | spin_lock_bh(&ep->ex_lock); |
| 1746 | fc_exch_abort_locked(ep, 0); | 1736 | fc_exch_abort_locked(ep, 0); |
| 1747 | ep->state |= FC_EX_RST_CLEANUP; | 1737 | ep->state |= FC_EX_RST_CLEANUP; |
| 1748 | fc_exch_timer_cancel(ep); | 1738 | if (cancel_delayed_work(&ep->timeout_work)) |
| 1739 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
| 1749 | resp = ep->resp; | 1740 | resp = ep->resp; |
| 1750 | ep->resp = NULL; | 1741 | ep->resp = NULL; |
| 1751 | if (ep->esb_stat & ESB_ST_REC_QUAL) | 1742 | if (ep->esb_stat & ESB_ST_REC_QUAL) |
| @@ -1802,9 +1793,6 @@ restart: | |||
| 1802 | goto restart; | 1793 | goto restart; |
| 1803 | } | 1794 | } |
| 1804 | } | 1795 | } |
| 1805 | pool->next_index = 0; | ||
| 1806 | pool->left = FC_XID_UNKNOWN; | ||
| 1807 | pool->right = FC_XID_UNKNOWN; | ||
| 1808 | spin_unlock_bh(&pool->lock); | 1796 | spin_unlock_bh(&pool->lock); |
| 1809 | } | 1797 | } |
| 1810 | 1798 | ||
| @@ -2140,8 +2128,10 @@ static void fc_exch_els_rrq(struct fc_frame *fp) | |||
| 2140 | ep->esb_stat &= ~ESB_ST_REC_QUAL; | 2128 | ep->esb_stat &= ~ESB_ST_REC_QUAL; |
| 2141 | atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ | 2129 | atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ |
| 2142 | } | 2130 | } |
| 2143 | if (ep->esb_stat & ESB_ST_COMPLETE) | 2131 | if (ep->esb_stat & ESB_ST_COMPLETE) { |
| 2144 | fc_exch_timer_cancel(ep); | 2132 | if (cancel_delayed_work(&ep->timeout_work)) |
| 2133 | atomic_dec(&ep->ex_refcnt); /* drop timer hold */ | ||
| 2134 | } | ||
| 2145 | 2135 | ||
| 2146 | spin_unlock_bh(&ep->ex_lock); | 2136 | spin_unlock_bh(&ep->ex_lock); |
| 2147 | 2137 | ||
| @@ -2161,31 +2151,6 @@ out: | |||
| 2161 | } | 2151 | } |
| 2162 | 2152 | ||
| 2163 | /** | 2153 | /** |
| 2164 | * fc_exch_update_stats() - update exches stats to lport | ||
| 2165 | * @lport: The local port to update exchange manager stats | ||
| 2166 | */ | ||
| 2167 | void fc_exch_update_stats(struct fc_lport *lport) | ||
| 2168 | { | ||
| 2169 | struct fc_host_statistics *st; | ||
| 2170 | struct fc_exch_mgr_anchor *ema; | ||
| 2171 | struct fc_exch_mgr *mp; | ||
| 2172 | |||
| 2173 | st = &lport->host_stats; | ||
| 2174 | |||
| 2175 | list_for_each_entry(ema, &lport->ema_list, ema_list) { | ||
| 2176 | mp = ema->mp; | ||
| 2177 | st->fc_no_free_exch += atomic_read(&mp->stats.no_free_exch); | ||
| 2178 | st->fc_no_free_exch_xid += | ||
| 2179 | atomic_read(&mp->stats.no_free_exch_xid); | ||
| 2180 | st->fc_xid_not_found += atomic_read(&mp->stats.xid_not_found); | ||
| 2181 | st->fc_xid_busy += atomic_read(&mp->stats.xid_busy); | ||
| 2182 | st->fc_seq_not_found += atomic_read(&mp->stats.seq_not_found); | ||
| 2183 | st->fc_non_bls_resp += atomic_read(&mp->stats.non_bls_resp); | ||
| 2184 | } | ||
| 2185 | } | ||
| 2186 | EXPORT_SYMBOL(fc_exch_update_stats); | ||
| 2187 | |||
| 2188 | /** | ||
| 2189 | * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs | 2154 | * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs |
| 2190 | * @lport: The local port to add the exchange manager to | 2155 | * @lport: The local port to add the exchange manager to |
| 2191 | * @mp: The exchange manager to be added to the local port | 2156 | * @mp: The exchange manager to be added to the local port |
| @@ -2293,18 +2258,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, | |||
| 2293 | mp->class = class; | 2258 | mp->class = class; |
| 2294 | /* adjust em exch xid range for offload */ | 2259 | /* adjust em exch xid range for offload */ |
| 2295 | mp->min_xid = min_xid; | 2260 | mp->min_xid = min_xid; |
| 2296 | 2261 | mp->max_xid = max_xid; | |
| 2297 | /* reduce range so per cpu pool fits into PCPU_MIN_UNIT_SIZE pool */ | ||
| 2298 | pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) / | ||
| 2299 | sizeof(struct fc_exch *); | ||
| 2300 | if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) { | ||
| 2301 | mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) + | ||
| 2302 | min_xid - 1; | ||
| 2303 | } else { | ||
| 2304 | mp->max_xid = max_xid; | ||
| 2305 | pool_exch_range = (mp->max_xid - mp->min_xid + 1) / | ||
| 2306 | (fc_cpu_mask + 1); | ||
| 2307 | } | ||
| 2308 | 2262 | ||
| 2309 | mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); | 2263 | mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); |
| 2310 | if (!mp->ep_pool) | 2264 | if (!mp->ep_pool) |
| @@ -2315,6 +2269,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, | |||
| 2315 | * divided across all cpus. The exch pointers array memory is | 2269 | * divided across all cpus. The exch pointers array memory is |
| 2316 | * allocated for exch range per pool. | 2270 | * allocated for exch range per pool. |
| 2317 | */ | 2271 | */ |
| 2272 | pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1); | ||
| 2318 | mp->pool_max_index = pool_exch_range - 1; | 2273 | mp->pool_max_index = pool_exch_range - 1; |
| 2319 | 2274 | ||
| 2320 | /* | 2275 | /* |
| @@ -2326,7 +2281,6 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, | |||
| 2326 | goto free_mempool; | 2281 | goto free_mempool; |
| 2327 | for_each_possible_cpu(cpu) { | 2282 | for_each_possible_cpu(cpu) { |
| 2328 | pool = per_cpu_ptr(mp->pool, cpu); | 2283 | pool = per_cpu_ptr(mp->pool, cpu); |
| 2329 | pool->next_index = 0; | ||
| 2330 | pool->left = FC_XID_UNKNOWN; | 2284 | pool->left = FC_XID_UNKNOWN; |
| 2331 | pool->right = FC_XID_UNKNOWN; | 2285 | pool->right = FC_XID_UNKNOWN; |
| 2332 | spin_lock_init(&pool->lock); | 2286 | spin_lock_init(&pool->lock); |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index fcb9d0b20ee..4c41ee816f0 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
| @@ -155,12 +155,8 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lport, gfp_t gfp) | |||
| 155 | fsp->xfer_ddp = FC_XID_UNKNOWN; | 155 | fsp->xfer_ddp = FC_XID_UNKNOWN; |
| 156 | atomic_set(&fsp->ref_cnt, 1); | 156 | atomic_set(&fsp->ref_cnt, 1); |
| 157 | init_timer(&fsp->timer); | 157 | init_timer(&fsp->timer); |
| 158 | fsp->timer.data = (unsigned long)fsp; | ||
| 159 | INIT_LIST_HEAD(&fsp->list); | 158 | INIT_LIST_HEAD(&fsp->list); |
| 160 | spin_lock_init(&fsp->scsi_pkt_lock); | 159 | spin_lock_init(&fsp->scsi_pkt_lock); |
| 161 | } else { | ||
| 162 | per_cpu_ptr(lport->stats, get_cpu())->FcpPktAllocFails++; | ||
| 163 | put_cpu(); | ||
| 164 | } | 160 | } |
| 165 | return fsp; | 161 | return fsp; |
| 166 | } | 162 | } |
| @@ -267,9 +263,6 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) | |||
| 267 | if (!fsp->seq_ptr) | 263 | if (!fsp->seq_ptr) |
| 268 | return -EINVAL; | 264 | return -EINVAL; |
| 269 | 265 | ||
| 270 | per_cpu_ptr(fsp->lp->stats, get_cpu())->FcpPktAborts++; | ||
| 271 | put_cpu(); | ||
| 272 | |||
| 273 | fsp->state |= FC_SRB_ABORT_PENDING; | 266 | fsp->state |= FC_SRB_ABORT_PENDING; |
| 274 | return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0); | 267 | return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0); |
| 275 | } | 268 | } |
| @@ -426,8 +419,6 @@ static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport, | |||
| 426 | if (likely(fp)) | 419 | if (likely(fp)) |
| 427 | return fp; | 420 | return fp; |
| 428 | 421 | ||
| 429 | per_cpu_ptr(lport->stats, get_cpu())->FcpFrameAllocFails++; | ||
| 430 | put_cpu(); | ||
| 431 | /* error case */ | 422 | /* error case */ |
| 432 | fc_fcp_can_queue_ramp_down(lport); | 423 | fc_fcp_can_queue_ramp_down(lport); |
| 433 | return NULL; | 424 | return NULL; |
| @@ -442,7 +433,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
| 442 | { | 433 | { |
| 443 | struct scsi_cmnd *sc = fsp->cmd; | 434 | struct scsi_cmnd *sc = fsp->cmd; |
| 444 | struct fc_lport *lport = fsp->lp; | 435 | struct fc_lport *lport = fsp->lp; |
| 445 | struct fc_stats *stats; | 436 | struct fcoe_dev_stats *stats; |
| 446 | struct fc_frame_header *fh; | 437 | struct fc_frame_header *fh; |
| 447 | size_t start_offset; | 438 | size_t start_offset; |
| 448 | size_t offset; | 439 | size_t offset; |
| @@ -493,18 +484,18 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
| 493 | 484 | ||
| 494 | if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { | 485 | if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { |
| 495 | copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, | 486 | copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, |
| 496 | &offset, NULL); | 487 | &offset, KM_SOFTIRQ0, NULL); |
| 497 | } else { | 488 | } else { |
| 498 | crc = crc32(~0, (u8 *) fh, sizeof(*fh)); | 489 | crc = crc32(~0, (u8 *) fh, sizeof(*fh)); |
| 499 | copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, | 490 | copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, |
| 500 | &offset, &crc); | 491 | &offset, KM_SOFTIRQ0, &crc); |
| 501 | buf = fc_frame_payload_get(fp, 0); | 492 | buf = fc_frame_payload_get(fp, 0); |
| 502 | if (len % 4) | 493 | if (len % 4) |
| 503 | crc = crc32(crc, buf + len, 4 - (len % 4)); | 494 | crc = crc32(crc, buf + len, 4 - (len % 4)); |
| 504 | 495 | ||
| 505 | if (~crc != le32_to_cpu(fr_crc(fp))) { | 496 | if (~crc != le32_to_cpu(fr_crc(fp))) { |
| 506 | crc_err: | 497 | crc_err: |
| 507 | stats = per_cpu_ptr(lport->stats, get_cpu()); | 498 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
| 508 | stats->ErrorFrames++; | 499 | stats->ErrorFrames++; |
| 509 | /* per cpu count, not total count, but OK for limit */ | 500 | /* per cpu count, not total count, but OK for limit */ |
| 510 | if (stats->InvalidCRCCount++ < FC_MAX_ERROR_CNT) | 501 | if (stats->InvalidCRCCount++ < FC_MAX_ERROR_CNT) |
| @@ -658,10 +649,10 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, | |||
| 658 | * The scatterlist item may be bigger than PAGE_SIZE, | 649 | * The scatterlist item may be bigger than PAGE_SIZE, |
| 659 | * but we must not cross pages inside the kmap. | 650 | * but we must not cross pages inside the kmap. |
| 660 | */ | 651 | */ |
| 661 | page_addr = kmap_atomic(page); | 652 | page_addr = kmap_atomic(page, KM_SOFTIRQ0); |
| 662 | memcpy(data, (char *)page_addr + (off & ~PAGE_MASK), | 653 | memcpy(data, (char *)page_addr + (off & ~PAGE_MASK), |
| 663 | sg_bytes); | 654 | sg_bytes); |
| 664 | kunmap_atomic(page_addr); | 655 | kunmap_atomic(page_addr, KM_SOFTIRQ0); |
| 665 | data += sg_bytes; | 656 | data += sg_bytes; |
| 666 | } | 657 | } |
| 667 | offset += sg_bytes; | 658 | offset += sg_bytes; |
| @@ -768,6 +759,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg) | |||
| 768 | goto out; | 759 | goto out; |
| 769 | if (fc_fcp_lock_pkt(fsp)) | 760 | if (fc_fcp_lock_pkt(fsp)) |
| 770 | goto out; | 761 | goto out; |
| 762 | fsp->last_pkt_time = jiffies; | ||
| 771 | 763 | ||
| 772 | if (fh->fh_type == FC_TYPE_BLS) { | 764 | if (fh->fh_type == FC_TYPE_BLS) { |
| 773 | fc_fcp_abts_resp(fsp, fp); | 765 | fc_fcp_abts_resp(fsp, fp); |
| @@ -851,8 +843,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
| 851 | fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); | 843 | fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); |
| 852 | if (flags & FCP_RSP_LEN_VAL) { | 844 | if (flags & FCP_RSP_LEN_VAL) { |
| 853 | respl = ntohl(rp_ex->fr_rsp_len); | 845 | respl = ntohl(rp_ex->fr_rsp_len); |
| 854 | if ((respl != FCP_RESP_RSP_INFO_LEN4) && | 846 | if (respl != sizeof(*fc_rp_info)) |
| 855 | (respl != FCP_RESP_RSP_INFO_LEN8)) | ||
| 856 | goto len_err; | 847 | goto len_err; |
| 857 | if (fsp->wait_for_comp) { | 848 | if (fsp->wait_for_comp) { |
| 858 | /* Abuse cdb_status for rsp code */ | 849 | /* Abuse cdb_status for rsp code */ |
| @@ -1083,7 +1074,8 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) | |||
| 1083 | fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); | 1074 | fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); |
| 1084 | fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; | 1075 | fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; |
| 1085 | 1076 | ||
| 1086 | int_to_scsilun(fsp->cmd->device->lun, &fsp->cdb_cmd.fc_lun); | 1077 | int_to_scsilun(fsp->cmd->device->lun, |
| 1078 | (struct scsi_lun *)fsp->cdb_cmd.fc_lun); | ||
| 1087 | memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); | 1079 | memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); |
| 1088 | 1080 | ||
| 1089 | spin_lock_irqsave(&si->scsi_queue_lock, flags); | 1081 | spin_lock_irqsave(&si->scsi_queue_lock, flags); |
| @@ -1156,6 +1148,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp, | |||
| 1156 | rc = -1; | 1148 | rc = -1; |
| 1157 | goto unlock; | 1149 | goto unlock; |
| 1158 | } | 1150 | } |
| 1151 | fsp->last_pkt_time = jiffies; | ||
| 1159 | fsp->seq_ptr = seq; | 1152 | fsp->seq_ptr = seq; |
| 1160 | fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */ | 1153 | fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */ |
| 1161 | 1154 | ||
| @@ -1265,7 +1258,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp, | |||
| 1265 | 1258 | ||
| 1266 | fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); | 1259 | fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); |
| 1267 | fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET; | 1260 | fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET; |
| 1268 | int_to_scsilun(lun, &fsp->cdb_cmd.fc_lun); | 1261 | int_to_scsilun(lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun); |
| 1269 | 1262 | ||
| 1270 | fsp->wait_for_comp = 1; | 1263 | fsp->wait_for_comp = 1; |
| 1271 | init_completion(&fsp->tm_done); | 1264 | init_completion(&fsp->tm_done); |
| @@ -1381,10 +1374,10 @@ static void fc_fcp_timeout(unsigned long data) | |||
| 1381 | 1374 | ||
| 1382 | fsp->state |= FC_SRB_FCP_PROCESSING_TMO; | 1375 | fsp->state |= FC_SRB_FCP_PROCESSING_TMO; |
| 1383 | 1376 | ||
| 1384 | if (fsp->state & FC_SRB_RCV_STATUS) | 1377 | if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED) |
| 1385 | fc_fcp_complete_locked(fsp); | ||
| 1386 | else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED) | ||
| 1387 | fc_fcp_rec(fsp); | 1378 | fc_fcp_rec(fsp); |
| 1379 | else if (fsp->state & FC_SRB_RCV_STATUS) | ||
| 1380 | fc_fcp_complete_locked(fsp); | ||
| 1388 | else | 1381 | else |
| 1389 | fc_fcp_recovery(fsp, FC_TIMED_OUT); | 1382 | fc_fcp_recovery(fsp, FC_TIMED_OUT); |
| 1390 | fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; | 1383 | fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; |
| @@ -1795,7 +1788,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) | |||
| 1795 | struct fc_rport_libfc_priv *rpriv; | 1788 | struct fc_rport_libfc_priv *rpriv; |
| 1796 | int rval; | 1789 | int rval; |
| 1797 | int rc = 0; | 1790 | int rc = 0; |
| 1798 | struct fc_stats *stats; | 1791 | struct fcoe_dev_stats *stats; |
| 1799 | 1792 | ||
| 1800 | rval = fc_remote_port_chkready(rport); | 1793 | rval = fc_remote_port_chkready(rport); |
| 1801 | if (rval) { | 1794 | if (rval) { |
| @@ -1844,7 +1837,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) | |||
| 1844 | /* | 1837 | /* |
| 1845 | * setup the data direction | 1838 | * setup the data direction |
| 1846 | */ | 1839 | */ |
| 1847 | stats = per_cpu_ptr(lport->stats, get_cpu()); | 1840 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
| 1848 | if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { | 1841 | if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { |
| 1849 | fsp->req_flags = FC_SRB_READ; | 1842 | fsp->req_flags = FC_SRB_READ; |
| 1850 | stats->InputRequests++; | 1843 | stats->InputRequests++; |
| @@ -1859,6 +1852,9 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) | |||
| 1859 | } | 1852 | } |
| 1860 | put_cpu(); | 1853 | put_cpu(); |
| 1861 | 1854 | ||
| 1855 | init_timer(&fsp->timer); | ||
| 1856 | fsp->timer.data = (unsigned long)fsp; | ||
| 1857 | |||
| 1862 | /* | 1858 | /* |
| 1863 | * send it to the lower layer | 1859 | * send it to the lower layer |
| 1864 | * if we get -1 return then put the request in the pending | 1860 | * if we get -1 return then put the request in the pending |
diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c index 0382ac06906..981329a17c4 100644 --- a/drivers/scsi/libfc/fc_frame.c +++ b/drivers/scsi/libfc/fc_frame.c | |||
| @@ -49,7 +49,7 @@ u32 fc_frame_crc_check(struct fc_frame *fp) | |||
| 49 | EXPORT_SYMBOL(fc_frame_crc_check); | 49 | EXPORT_SYMBOL(fc_frame_crc_check); |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | * Allocate a frame intended to be sent. | 52 | * Allocate a frame intended to be sent via fcoe_xmit. |
| 53 | * Get an sk_buff for the frame and set the length. | 53 | * Get an sk_buff for the frame and set the length. |
| 54 | */ | 54 | */ |
| 55 | struct fc_frame *_fc_frame_alloc(size_t len) | 55 | struct fc_frame *_fc_frame_alloc(size_t len) |
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c index 8d65a51a759..b7735129f1f 100644 --- a/drivers/scsi/libfc/fc_libfc.c +++ b/drivers/scsi/libfc/fc_libfc.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
| 23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
| 24 | #include <linux/module.h> | ||
| 25 | 24 | ||
| 26 | #include <scsi/libfc.h> | 25 | #include <scsi/libfc.h> |
| 27 | #include <scsi/fc_encode.h> | 26 | #include <scsi/fc_encode.h> |
| @@ -105,13 +104,14 @@ module_exit(libfc_exit); | |||
| 105 | * @sg: pointer to the pointer of the SG list. | 104 | * @sg: pointer to the pointer of the SG list. |
| 106 | * @nents: pointer to the remaining number of entries in the SG list. | 105 | * @nents: pointer to the remaining number of entries in the SG list. |
| 107 | * @offset: pointer to the current offset in the SG list. | 106 | * @offset: pointer to the current offset in the SG list. |
| 107 | * @km_type: dedicated page table slot type for kmap_atomic. | ||
| 108 | * @crc: pointer to the 32-bit crc value. | 108 | * @crc: pointer to the 32-bit crc value. |
| 109 | * If crc is NULL, CRC is not calculated. | 109 | * If crc is NULL, CRC is not calculated. |
| 110 | */ | 110 | */ |
| 111 | u32 fc_copy_buffer_to_sglist(void *buf, size_t len, | 111 | u32 fc_copy_buffer_to_sglist(void *buf, size_t len, |
| 112 | struct scatterlist *sg, | 112 | struct scatterlist *sg, |
| 113 | u32 *nents, size_t *offset, | 113 | u32 *nents, size_t *offset, |
| 114 | u32 *crc) | 114 | enum km_type km_type, u32 *crc) |
| 115 | { | 115 | { |
| 116 | size_t remaining = len; | 116 | size_t remaining = len; |
| 117 | u32 copy_len = 0; | 117 | u32 copy_len = 0; |
| @@ -141,11 +141,12 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len, | |||
| 141 | off = *offset + sg->offset; | 141 | off = *offset + sg->offset; |
| 142 | sg_bytes = min(sg_bytes, | 142 | sg_bytes = min(sg_bytes, |
| 143 | (size_t)(PAGE_SIZE - (off & ~PAGE_MASK))); | 143 | (size_t)(PAGE_SIZE - (off & ~PAGE_MASK))); |
| 144 | page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT)); | 144 | page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT), |
| 145 | km_type); | ||
| 145 | if (crc) | 146 | if (crc) |
| 146 | *crc = crc32(*crc, buf, sg_bytes); | 147 | *crc = crc32(*crc, buf, sg_bytes); |
| 147 | memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes); | 148 | memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes); |
| 148 | kunmap_atomic(page_addr); | 149 | kunmap_atomic(page_addr, km_type); |
| 149 | buf += sg_bytes; | 150 | buf += sg_bytes; |
| 150 | *offset += sg_bytes; | 151 | *offset += sg_bytes; |
| 151 | remaining -= sg_bytes; | 152 | remaining -= sg_bytes; |
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h index c2830cc66d6..c7d071289af 100644 --- a/drivers/scsi/libfc/fc_libfc.h +++ b/drivers/scsi/libfc/fc_libfc.h | |||
| @@ -134,6 +134,6 @@ extern void fc_fc4_conf_lport_params(struct fc_lport *, enum fc_fh_type); | |||
| 134 | u32 fc_copy_buffer_to_sglist(void *buf, size_t len, | 134 | u32 fc_copy_buffer_to_sglist(void *buf, size_t len, |
| 135 | struct scatterlist *sg, | 135 | struct scatterlist *sg, |
| 136 | u32 *nents, size_t *offset, | 136 | u32 *nents, size_t *offset, |
| 137 | u32 *crc); | 137 | enum km_type km_type, u32 *crc); |
| 138 | 138 | ||
| 139 | #endif /* _FC_LIBFC_H_ */ | 139 | #endif /* _FC_LIBFC_H_ */ |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index f04d15c67df..628f347404f 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
| @@ -89,7 +89,6 @@ | |||
| 89 | 89 | ||
| 90 | #include <linux/timer.h> | 90 | #include <linux/timer.h> |
| 91 | #include <linux/delay.h> | 91 | #include <linux/delay.h> |
| 92 | #include <linux/module.h> | ||
| 93 | #include <linux/slab.h> | 92 | #include <linux/slab.h> |
| 94 | #include <asm/unaligned.h> | 93 | #include <asm/unaligned.h> |
| 95 | 94 | ||
| @@ -116,8 +115,6 @@ static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state); | |||
| 116 | static void fc_lport_enter_scr(struct fc_lport *); | 115 | static void fc_lport_enter_scr(struct fc_lport *); |
| 117 | static void fc_lport_enter_ready(struct fc_lport *); | 116 | static void fc_lport_enter_ready(struct fc_lport *); |
| 118 | static void fc_lport_enter_logo(struct fc_lport *); | 117 | static void fc_lport_enter_logo(struct fc_lport *); |
| 119 | static void fc_lport_enter_fdmi(struct fc_lport *lport); | ||
| 120 | static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state); | ||
| 121 | 118 | ||
| 122 | static const char *fc_lport_state_names[] = { | 119 | static const char *fc_lport_state_names[] = { |
| 123 | [LPORT_ST_DISABLED] = "disabled", | 120 | [LPORT_ST_DISABLED] = "disabled", |
| @@ -128,11 +125,6 @@ static const char *fc_lport_state_names[] = { | |||
| 128 | [LPORT_ST_RSPN_ID] = "RSPN_ID", | 125 | [LPORT_ST_RSPN_ID] = "RSPN_ID", |
| 129 | [LPORT_ST_RFT_ID] = "RFT_ID", | 126 | [LPORT_ST_RFT_ID] = "RFT_ID", |
| 130 | [LPORT_ST_RFF_ID] = "RFF_ID", | 127 | [LPORT_ST_RFF_ID] = "RFF_ID", |
| 131 | [LPORT_ST_FDMI] = "FDMI", | ||
| 132 | [LPORT_ST_RHBA] = "RHBA", | ||
| 133 | [LPORT_ST_RPA] = "RPA", | ||
| 134 | [LPORT_ST_DHBA] = "DHBA", | ||
| 135 | [LPORT_ST_DPRT] = "DPRT", | ||
| 136 | [LPORT_ST_SCR] = "SCR", | 128 | [LPORT_ST_SCR] = "SCR", |
| 137 | [LPORT_ST_READY] = "Ready", | 129 | [LPORT_ST_READY] = "Ready", |
| 138 | [LPORT_ST_LOGO] = "LOGO", | 130 | [LPORT_ST_LOGO] = "LOGO", |
| @@ -190,14 +182,11 @@ static void fc_lport_rport_callback(struct fc_lport *lport, | |||
| 190 | if (lport->state == LPORT_ST_DNS) { | 182 | if (lport->state == LPORT_ST_DNS) { |
| 191 | lport->dns_rdata = rdata; | 183 | lport->dns_rdata = rdata; |
| 192 | fc_lport_enter_ns(lport, LPORT_ST_RNN_ID); | 184 | fc_lport_enter_ns(lport, LPORT_ST_RNN_ID); |
| 193 | } else if (lport->state == LPORT_ST_FDMI) { | ||
| 194 | lport->ms_rdata = rdata; | ||
| 195 | fc_lport_enter_ms(lport, LPORT_ST_DHBA); | ||
| 196 | } else { | 185 | } else { |
| 197 | FC_LPORT_DBG(lport, "Received an READY event " | 186 | FC_LPORT_DBG(lport, "Received an READY event " |
| 198 | "on port (%6.6x) for the directory " | 187 | "on port (%6.6x) for the directory " |
| 199 | "server, but the lport is not " | 188 | "server, but the lport is not " |
| 200 | "in the DNS or FDMI state, it's in the " | 189 | "in the DNS state, it's in the " |
| 201 | "%d state", rdata->ids.port_id, | 190 | "%d state", rdata->ids.port_id, |
| 202 | lport->state); | 191 | lport->state); |
| 203 | lport->tt.rport_logoff(rdata); | 192 | lport->tt.rport_logoff(rdata); |
| @@ -206,10 +195,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport, | |||
| 206 | case RPORT_EV_LOGO: | 195 | case RPORT_EV_LOGO: |
| 207 | case RPORT_EV_FAILED: | 196 | case RPORT_EV_FAILED: |
| 208 | case RPORT_EV_STOP: | 197 | case RPORT_EV_STOP: |
| 209 | if (rdata->ids.port_id == FC_FID_DIR_SERV) | 198 | lport->dns_rdata = NULL; |
| 210 | lport->dns_rdata = NULL; | ||
| 211 | else if (rdata->ids.port_id == FC_FID_MGMT_SERV) | ||
| 212 | lport->ms_rdata = NULL; | ||
| 213 | break; | 199 | break; |
| 214 | case RPORT_EV_NONE: | 200 | case RPORT_EV_NONE: |
| 215 | break; | 201 | break; |
| @@ -299,54 +285,47 @@ EXPORT_SYMBOL(fc_get_host_speed); | |||
| 299 | */ | 285 | */ |
| 300 | struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) | 286 | struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) |
| 301 | { | 287 | { |
| 302 | struct fc_host_statistics *fc_stats; | 288 | struct fc_host_statistics *fcoe_stats; |
| 303 | struct fc_lport *lport = shost_priv(shost); | 289 | struct fc_lport *lport = shost_priv(shost); |
| 304 | struct timespec v0, v1; | 290 | struct timespec v0, v1; |
| 305 | unsigned int cpu; | 291 | unsigned int cpu; |
| 306 | u64 fcp_in_bytes = 0; | 292 | u64 fcp_in_bytes = 0; |
| 307 | u64 fcp_out_bytes = 0; | 293 | u64 fcp_out_bytes = 0; |
| 308 | 294 | ||
| 309 | fc_stats = &lport->host_stats; | 295 | fcoe_stats = &lport->host_stats; |
| 310 | memset(fc_stats, 0, sizeof(struct fc_host_statistics)); | 296 | memset(fcoe_stats, 0, sizeof(struct fc_host_statistics)); |
| 311 | 297 | ||
| 312 | jiffies_to_timespec(jiffies, &v0); | 298 | jiffies_to_timespec(jiffies, &v0); |
| 313 | jiffies_to_timespec(lport->boot_time, &v1); | 299 | jiffies_to_timespec(lport->boot_time, &v1); |
| 314 | fc_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); | 300 | fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); |
| 315 | 301 | ||
| 316 | for_each_possible_cpu(cpu) { | 302 | for_each_possible_cpu(cpu) { |
| 317 | struct fc_stats *stats; | 303 | struct fcoe_dev_stats *stats; |
| 318 | 304 | ||
| 319 | stats = per_cpu_ptr(lport->stats, cpu); | 305 | stats = per_cpu_ptr(lport->dev_stats, cpu); |
| 320 | 306 | ||
| 321 | fc_stats->tx_frames += stats->TxFrames; | 307 | fcoe_stats->tx_frames += stats->TxFrames; |
| 322 | fc_stats->tx_words += stats->TxWords; | 308 | fcoe_stats->tx_words += stats->TxWords; |
| 323 | fc_stats->rx_frames += stats->RxFrames; | 309 | fcoe_stats->rx_frames += stats->RxFrames; |
| 324 | fc_stats->rx_words += stats->RxWords; | 310 | fcoe_stats->rx_words += stats->RxWords; |
| 325 | fc_stats->error_frames += stats->ErrorFrames; | 311 | fcoe_stats->error_frames += stats->ErrorFrames; |
| 326 | fc_stats->invalid_crc_count += stats->InvalidCRCCount; | 312 | fcoe_stats->invalid_crc_count += stats->InvalidCRCCount; |
| 327 | fc_stats->fcp_input_requests += stats->InputRequests; | 313 | fcoe_stats->fcp_input_requests += stats->InputRequests; |
| 328 | fc_stats->fcp_output_requests += stats->OutputRequests; | 314 | fcoe_stats->fcp_output_requests += stats->OutputRequests; |
| 329 | fc_stats->fcp_control_requests += stats->ControlRequests; | 315 | fcoe_stats->fcp_control_requests += stats->ControlRequests; |
| 330 | fcp_in_bytes += stats->InputBytes; | 316 | fcp_in_bytes += stats->InputBytes; |
| 331 | fcp_out_bytes += stats->OutputBytes; | 317 | fcp_out_bytes += stats->OutputBytes; |
| 332 | fc_stats->fcp_packet_alloc_failures += stats->FcpPktAllocFails; | 318 | fcoe_stats->link_failure_count += stats->LinkFailureCount; |
| 333 | fc_stats->fcp_packet_aborts += stats->FcpPktAborts; | ||
| 334 | fc_stats->fcp_frame_alloc_failures += stats->FcpFrameAllocFails; | ||
| 335 | fc_stats->link_failure_count += stats->LinkFailureCount; | ||
| 336 | } | 319 | } |
| 337 | fc_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000); | 320 | fcoe_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000); |
| 338 | fc_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000); | 321 | fcoe_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000); |
| 339 | fc_stats->lip_count = -1; | 322 | fcoe_stats->lip_count = -1; |
| 340 | fc_stats->nos_count = -1; | 323 | fcoe_stats->nos_count = -1; |
| 341 | fc_stats->loss_of_sync_count = -1; | 324 | fcoe_stats->loss_of_sync_count = -1; |
| 342 | fc_stats->loss_of_signal_count = -1; | 325 | fcoe_stats->loss_of_signal_count = -1; |
| 343 | fc_stats->prim_seq_protocol_err_count = -1; | 326 | fcoe_stats->prim_seq_protocol_err_count = -1; |
| 344 | fc_stats->dumped_frames = -1; | 327 | fcoe_stats->dumped_frames = -1; |
| 345 | 328 | return fcoe_stats; | |
| 346 | /* update exches stats */ | ||
| 347 | fc_exch_update_stats(lport); | ||
| 348 | |||
| 349 | return fc_stats; | ||
| 350 | } | 329 | } |
| 351 | EXPORT_SYMBOL(fc_get_host_stats); | 330 | EXPORT_SYMBOL(fc_get_host_stats); |
| 352 | 331 | ||
| @@ -655,7 +634,6 @@ int fc_lport_destroy(struct fc_lport *lport) | |||
| 655 | lport->tt.fcp_abort_io(lport); | 634 | lport->tt.fcp_abort_io(lport); |
| 656 | lport->tt.disc_stop_final(lport); | 635 | lport->tt.disc_stop_final(lport); |
| 657 | lport->tt.exch_mgr_reset(lport, 0, 0); | 636 | lport->tt.exch_mgr_reset(lport, 0, 0); |
| 658 | cancel_delayed_work_sync(&lport->retry_work); | ||
| 659 | fc_fc4_del_lport(lport); | 637 | fc_fc4_del_lport(lport); |
| 660 | return 0; | 638 | return 0; |
| 661 | } | 639 | } |
| @@ -698,8 +676,7 @@ EXPORT_SYMBOL(fc_set_mfs); | |||
| 698 | * @lport: The local port receiving the event | 676 | * @lport: The local port receiving the event |
| 699 | * @event: The discovery event | 677 | * @event: The discovery event |
| 700 | */ | 678 | */ |
| 701 | static void fc_lport_disc_callback(struct fc_lport *lport, | 679 | void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) |
| 702 | enum fc_disc_event event) | ||
| 703 | { | 680 | { |
| 704 | switch (event) { | 681 | switch (event) { |
| 705 | case DISC_EV_SUCCESS: | 682 | case DISC_EV_SUCCESS: |
| @@ -980,8 +957,7 @@ drop: | |||
| 980 | rcu_read_unlock(); | 957 | rcu_read_unlock(); |
| 981 | FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type); | 958 | FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type); |
| 982 | fc_frame_free(fp); | 959 | fc_frame_free(fp); |
| 983 | if (sp) | 960 | lport->tt.exch_done(sp); |
| 984 | lport->tt.exch_done(sp); | ||
| 985 | } | 961 | } |
| 986 | 962 | ||
| 987 | /** | 963 | /** |
| @@ -1054,8 +1030,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport) | |||
| 1054 | FCH_EVT_LIPRESET, 0); | 1030 | FCH_EVT_LIPRESET, 0); |
| 1055 | fc_vports_linkchange(lport); | 1031 | fc_vports_linkchange(lport); |
| 1056 | fc_lport_reset_locked(lport); | 1032 | fc_lport_reset_locked(lport); |
| 1057 | if (lport->link_up) | 1033 | if (lport->link_up) { |
| 1034 | /* | ||
| 1035 | * Wait upto resource allocation time out before | ||
| 1036 | * doing re-login since incomplete FIP exchanged | ||
| 1037 | * from last session may collide with exchanges | ||
| 1038 | * in new session. | ||
| 1039 | */ | ||
| 1040 | msleep(lport->r_a_tov); | ||
| 1058 | fc_lport_enter_flogi(lport); | 1041 | fc_lport_enter_flogi(lport); |
| 1042 | } | ||
| 1059 | } | 1043 | } |
| 1060 | 1044 | ||
| 1061 | /** | 1045 | /** |
| @@ -1170,96 +1154,14 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
| 1170 | fc_lport_enter_ns(lport, LPORT_ST_RFF_ID); | 1154 | fc_lport_enter_ns(lport, LPORT_ST_RFF_ID); |
| 1171 | break; | 1155 | break; |
| 1172 | case LPORT_ST_RFF_ID: | 1156 | case LPORT_ST_RFF_ID: |
| 1173 | if (lport->fdmi_enabled) | ||
| 1174 | fc_lport_enter_fdmi(lport); | ||
| 1175 | else | ||
| 1176 | fc_lport_enter_scr(lport); | ||
| 1177 | break; | ||
| 1178 | default: | ||
| 1179 | /* should have already been caught by state checks */ | ||
| 1180 | break; | ||
| 1181 | } | ||
| 1182 | else | ||
| 1183 | fc_lport_error(lport, fp); | ||
| 1184 | out: | ||
| 1185 | fc_frame_free(fp); | ||
| 1186 | err: | ||
| 1187 | mutex_unlock(&lport->lp_mutex); | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | /** | ||
| 1191 | * fc_lport_ms_resp() - Handle response to a management server | ||
| 1192 | * exchange | ||
| 1193 | * @sp: current sequence in exchange | ||
| 1194 | * @fp: response frame | ||
| 1195 | * @lp_arg: Fibre Channel host port instance | ||
| 1196 | * | ||
| 1197 | * Locking Note: This function will be called without the lport lock | ||
| 1198 | * held, but it will lock, call an _enter_* function or fc_lport_error() | ||
| 1199 | * and then unlock the lport. | ||
| 1200 | */ | ||
| 1201 | static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp, | ||
| 1202 | void *lp_arg) | ||
| 1203 | { | ||
| 1204 | struct fc_lport *lport = lp_arg; | ||
| 1205 | struct fc_frame_header *fh; | ||
| 1206 | struct fc_ct_hdr *ct; | ||
| 1207 | |||
| 1208 | FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp)); | ||
| 1209 | |||
| 1210 | if (fp == ERR_PTR(-FC_EX_CLOSED)) | ||
| 1211 | return; | ||
| 1212 | |||
| 1213 | mutex_lock(&lport->lp_mutex); | ||
| 1214 | |||
| 1215 | if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) { | ||
| 1216 | FC_LPORT_DBG(lport, "Received a management server response, " | ||
| 1217 | "but in state %s\n", fc_lport_state(lport)); | ||
| 1218 | if (IS_ERR(fp)) | ||
| 1219 | goto err; | ||
| 1220 | goto out; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | if (IS_ERR(fp)) { | ||
| 1224 | fc_lport_error(lport, fp); | ||
| 1225 | goto err; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | fh = fc_frame_header_get(fp); | ||
| 1229 | ct = fc_frame_payload_get(fp, sizeof(*ct)); | ||
| 1230 | |||
| 1231 | if (fh && ct && fh->fh_type == FC_TYPE_CT && | ||
| 1232 | ct->ct_fs_type == FC_FST_MGMT && | ||
| 1233 | ct->ct_fs_subtype == FC_FDMI_SUBTYPE) { | ||
| 1234 | FC_LPORT_DBG(lport, "Received a management server response, " | ||
| 1235 | "reason=%d explain=%d\n", | ||
| 1236 | ct->ct_reason, | ||
| 1237 | ct->ct_explan); | ||
| 1238 | |||
| 1239 | switch (lport->state) { | ||
| 1240 | case LPORT_ST_RHBA: | ||
| 1241 | if (ntohs(ct->ct_cmd) == FC_FS_ACC) | ||
| 1242 | fc_lport_enter_ms(lport, LPORT_ST_RPA); | ||
| 1243 | else /* Error Skip RPA */ | ||
| 1244 | fc_lport_enter_scr(lport); | ||
| 1245 | break; | ||
| 1246 | case LPORT_ST_RPA: | ||
| 1247 | fc_lport_enter_scr(lport); | 1157 | fc_lport_enter_scr(lport); |
| 1248 | break; | 1158 | break; |
| 1249 | case LPORT_ST_DPRT: | ||
| 1250 | fc_lport_enter_ms(lport, LPORT_ST_RHBA); | ||
| 1251 | break; | ||
| 1252 | case LPORT_ST_DHBA: | ||
| 1253 | fc_lport_enter_ms(lport, LPORT_ST_DPRT); | ||
| 1254 | break; | ||
| 1255 | default: | 1159 | default: |
| 1256 | /* should have already been caught by state checks */ | 1160 | /* should have already been caught by state checks */ |
| 1257 | break; | 1161 | break; |
| 1258 | } | 1162 | } |
| 1259 | } else { | 1163 | else |
| 1260 | /* Invalid Frame? */ | ||
| 1261 | fc_lport_error(lport, fp); | 1164 | fc_lport_error(lport, fp); |
| 1262 | } | ||
| 1263 | out: | 1165 | out: |
| 1264 | fc_frame_free(fp); | 1166 | fc_frame_free(fp); |
| 1265 | err: | 1167 | err: |
| @@ -1443,123 +1345,6 @@ err: | |||
| 1443 | } | 1345 | } |
| 1444 | 1346 | ||
| 1445 | /** | 1347 | /** |
| 1446 | * fc_lport_enter_ms() - management server commands | ||
| 1447 | * @lport: Fibre Channel local port to register | ||
| 1448 | * | ||
| 1449 | * Locking Note: The lport lock is expected to be held before calling | ||
| 1450 | * this routine. | ||
| 1451 | */ | ||
| 1452 | static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) | ||
| 1453 | { | ||
| 1454 | struct fc_frame *fp; | ||
| 1455 | enum fc_fdmi_req cmd; | ||
| 1456 | int size = sizeof(struct fc_ct_hdr); | ||
| 1457 | size_t len; | ||
| 1458 | int numattrs; | ||
| 1459 | |||
| 1460 | FC_LPORT_DBG(lport, "Entered %s state from %s state\n", | ||
| 1461 | fc_lport_state_names[state], | ||
| 1462 | fc_lport_state(lport)); | ||
| 1463 | |||
| 1464 | fc_lport_state_enter(lport, state); | ||
| 1465 | |||
| 1466 | switch (state) { | ||
| 1467 | case LPORT_ST_RHBA: | ||
| 1468 | cmd = FC_FDMI_RHBA; | ||
| 1469 | /* Number of HBA Attributes */ | ||
| 1470 | numattrs = 10; | ||
| 1471 | len = sizeof(struct fc_fdmi_rhba); | ||
| 1472 | len -= sizeof(struct fc_fdmi_attr_entry); | ||
| 1473 | len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); | ||
| 1474 | len += FC_FDMI_HBA_ATTR_NODENAME_LEN; | ||
| 1475 | len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; | ||
| 1476 | len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; | ||
| 1477 | len += FC_FDMI_HBA_ATTR_MODEL_LEN; | ||
| 1478 | len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN; | ||
| 1479 | len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN; | ||
| 1480 | len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN; | ||
| 1481 | len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; | ||
| 1482 | len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; | ||
| 1483 | len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; | ||
| 1484 | |||
| 1485 | size += len; | ||
| 1486 | break; | ||
| 1487 | case LPORT_ST_RPA: | ||
| 1488 | cmd = FC_FDMI_RPA; | ||
| 1489 | /* Number of Port Attributes */ | ||
| 1490 | numattrs = 6; | ||
| 1491 | len = sizeof(struct fc_fdmi_rpa); | ||
| 1492 | len -= sizeof(struct fc_fdmi_attr_entry); | ||
| 1493 | len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); | ||
| 1494 | len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; | ||
| 1495 | len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; | ||
| 1496 | len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; | ||
| 1497 | len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN; | ||
| 1498 | len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; | ||
| 1499 | len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; | ||
| 1500 | |||
| 1501 | size += len; | ||
| 1502 | break; | ||
| 1503 | case LPORT_ST_DPRT: | ||
| 1504 | cmd = FC_FDMI_DPRT; | ||
| 1505 | len = sizeof(struct fc_fdmi_dprt); | ||
| 1506 | size += len; | ||
| 1507 | break; | ||
| 1508 | case LPORT_ST_DHBA: | ||
| 1509 | cmd = FC_FDMI_DHBA; | ||
| 1510 | len = sizeof(struct fc_fdmi_dhba); | ||
| 1511 | size += len; | ||
| 1512 | break; | ||
| 1513 | default: | ||
| 1514 | fc_lport_error(lport, NULL); | ||
| 1515 | return; | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n", | ||
| 1519 | cmd, (int)len, size); | ||
| 1520 | fp = fc_frame_alloc(lport, size); | ||
| 1521 | if (!fp) { | ||
| 1522 | fc_lport_error(lport, fp); | ||
| 1523 | return; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd, | ||
| 1527 | fc_lport_ms_resp, | ||
| 1528 | lport, 3 * lport->r_a_tov)) | ||
| 1529 | fc_lport_error(lport, fp); | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | /** | ||
| 1533 | * fc_rport_enter_fdmi() - Create a fc_rport for the management server | ||
| 1534 | * @lport: The local port requesting a remote port for the management server | ||
| 1535 | * | ||
| 1536 | * Locking Note: The lport lock is expected to be held before calling | ||
| 1537 | * this routine. | ||
| 1538 | */ | ||
| 1539 | static void fc_lport_enter_fdmi(struct fc_lport *lport) | ||
| 1540 | { | ||
| 1541 | struct fc_rport_priv *rdata; | ||
| 1542 | |||
| 1543 | FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n", | ||
| 1544 | fc_lport_state(lport)); | ||
| 1545 | |||
| 1546 | fc_lport_state_enter(lport, LPORT_ST_FDMI); | ||
| 1547 | |||
| 1548 | mutex_lock(&lport->disc.disc_mutex); | ||
| 1549 | rdata = lport->tt.rport_create(lport, FC_FID_MGMT_SERV); | ||
| 1550 | mutex_unlock(&lport->disc.disc_mutex); | ||
| 1551 | if (!rdata) | ||
| 1552 | goto err; | ||
| 1553 | |||
| 1554 | rdata->ops = &fc_lport_rport_ops; | ||
| 1555 | lport->tt.rport_login(rdata); | ||
| 1556 | return; | ||
| 1557 | |||
| 1558 | err: | ||
| 1559 | fc_lport_error(lport, NULL); | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | /** | ||
| 1563 | * fc_lport_timeout() - Handler for the retry_work timer | 1348 | * fc_lport_timeout() - Handler for the retry_work timer |
| 1564 | * @work: The work struct of the local port | 1349 | * @work: The work struct of the local port |
| 1565 | */ | 1350 | */ |
| @@ -1573,6 +1358,7 @@ static void fc_lport_timeout(struct work_struct *work) | |||
| 1573 | 1358 | ||
| 1574 | switch (lport->state) { | 1359 | switch (lport->state) { |
| 1575 | case LPORT_ST_DISABLED: | 1360 | case LPORT_ST_DISABLED: |
| 1361 | WARN_ON(1); | ||
| 1576 | break; | 1362 | break; |
| 1577 | case LPORT_ST_READY: | 1363 | case LPORT_ST_READY: |
| 1578 | break; | 1364 | break; |
| @@ -1591,16 +1377,6 @@ static void fc_lport_timeout(struct work_struct *work) | |||
| 1591 | case LPORT_ST_RFF_ID: | 1377 | case LPORT_ST_RFF_ID: |
| 1592 | fc_lport_enter_ns(lport, lport->state); | 1378 | fc_lport_enter_ns(lport, lport->state); |
| 1593 | break; | 1379 | break; |
| 1594 | case LPORT_ST_FDMI: | ||
| 1595 | fc_lport_enter_fdmi(lport); | ||
| 1596 | break; | ||
| 1597 | case LPORT_ST_RHBA: | ||
| 1598 | case LPORT_ST_RPA: | ||
| 1599 | case LPORT_ST_DHBA: | ||
| 1600 | case LPORT_ST_DPRT: | ||
| 1601 | FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n", | ||
| 1602 | fc_lport_state(lport)); | ||
| 1603 | /* fall thru */ | ||
| 1604 | case LPORT_ST_SCR: | 1380 | case LPORT_ST_SCR: |
| 1605 | fc_lport_enter_scr(lport); | 1381 | fc_lport_enter_scr(lport); |
| 1606 | break; | 1382 | break; |
| @@ -1705,7 +1481,6 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
| 1705 | void *lp_arg) | 1481 | void *lp_arg) |
| 1706 | { | 1482 | { |
| 1707 | struct fc_lport *lport = lp_arg; | 1483 | struct fc_lport *lport = lp_arg; |
| 1708 | struct fc_frame_header *fh; | ||
| 1709 | struct fc_els_flogi *flp; | 1484 | struct fc_els_flogi *flp; |
| 1710 | u32 did; | 1485 | u32 did; |
| 1711 | u16 csp_flags; | 1486 | u16 csp_flags; |
| @@ -1733,66 +1508,49 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
| 1733 | goto err; | 1508 | goto err; |
| 1734 | } | 1509 | } |
| 1735 | 1510 | ||
| 1736 | fh = fc_frame_header_get(fp); | ||
| 1737 | did = fc_frame_did(fp); | 1511 | did = fc_frame_did(fp); |
| 1738 | if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 || | 1512 | if (fc_frame_payload_op(fp) == ELS_LS_ACC && did) { |
| 1739 | fc_frame_payload_op(fp) != ELS_LS_ACC) { | 1513 | flp = fc_frame_payload_get(fp, sizeof(*flp)); |
| 1740 | FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n"); | 1514 | if (flp) { |
| 1741 | fc_lport_error(lport, fp); | 1515 | mfs = ntohs(flp->fl_csp.sp_bb_data) & |
| 1742 | goto err; | 1516 | FC_SP_BB_DATA_MASK; |
| 1743 | } | 1517 | if (mfs >= FC_SP_MIN_MAX_PAYLOAD && |
| 1744 | 1518 | mfs < lport->mfs) | |
| 1745 | flp = fc_frame_payload_get(fp, sizeof(*flp)); | 1519 | lport->mfs = mfs; |
| 1746 | if (!flp) { | 1520 | csp_flags = ntohs(flp->fl_csp.sp_features); |
| 1747 | FC_LPORT_DBG(lport, "FLOGI bad response\n"); | 1521 | r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); |
| 1748 | fc_lport_error(lport, fp); | 1522 | e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); |
| 1749 | goto err; | 1523 | if (csp_flags & FC_SP_FT_EDTR) |
| 1750 | } | 1524 | e_d_tov /= 1000000; |
| 1751 | 1525 | ||
| 1752 | mfs = ntohs(flp->fl_csp.sp_bb_data) & | 1526 | lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC); |
| 1753 | FC_SP_BB_DATA_MASK; | 1527 | |
| 1754 | 1528 | if ((csp_flags & FC_SP_FT_FPORT) == 0) { | |
| 1755 | if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { | 1529 | if (e_d_tov > lport->e_d_tov) |
| 1756 | FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " | 1530 | lport->e_d_tov = e_d_tov; |
| 1757 | "lport->mfs:%hu\n", mfs, lport->mfs); | 1531 | lport->r_a_tov = 2 * e_d_tov; |
| 1758 | fc_lport_error(lport, fp); | 1532 | fc_lport_set_port_id(lport, did, fp); |
| 1759 | goto err; | 1533 | printk(KERN_INFO "host%d: libfc: " |
| 1760 | } | 1534 | "Port (%6.6x) entered " |
| 1761 | 1535 | "point-to-point mode\n", | |
| 1762 | if (mfs <= lport->mfs) { | 1536 | lport->host->host_no, did); |
| 1763 | lport->mfs = mfs; | 1537 | fc_lport_ptp_setup(lport, fc_frame_sid(fp), |
| 1764 | fc_host_maxframe_size(lport->host) = mfs; | 1538 | get_unaligned_be64( |
| 1765 | } | 1539 | &flp->fl_wwpn), |
| 1766 | 1540 | get_unaligned_be64( | |
| 1767 | csp_flags = ntohs(flp->fl_csp.sp_features); | 1541 | &flp->fl_wwnn)); |
| 1768 | r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); | 1542 | } else { |
| 1769 | e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); | 1543 | lport->e_d_tov = e_d_tov; |
| 1770 | if (csp_flags & FC_SP_FT_EDTR) | 1544 | lport->r_a_tov = r_a_tov; |
| 1771 | e_d_tov /= 1000000; | 1545 | fc_host_fabric_name(lport->host) = |
| 1772 | 1546 | get_unaligned_be64(&flp->fl_wwnn); | |
| 1773 | lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC); | 1547 | fc_lport_set_port_id(lport, did, fp); |
| 1774 | 1548 | fc_lport_enter_dns(lport); | |
| 1775 | if ((csp_flags & FC_SP_FT_FPORT) == 0) { | 1549 | } |
| 1776 | if (e_d_tov > lport->e_d_tov) | 1550 | } |
| 1777 | lport->e_d_tov = e_d_tov; | ||
| 1778 | lport->r_a_tov = 2 * e_d_tov; | ||
| 1779 | fc_lport_set_port_id(lport, did, fp); | ||
| 1780 | printk(KERN_INFO "host%d: libfc: " | ||
| 1781 | "Port (%6.6x) entered " | ||
| 1782 | "point-to-point mode\n", | ||
| 1783 | lport->host->host_no, did); | ||
| 1784 | fc_lport_ptp_setup(lport, fc_frame_sid(fp), | ||
| 1785 | get_unaligned_be64( | ||
| 1786 | &flp->fl_wwpn), | ||
| 1787 | get_unaligned_be64( | ||
| 1788 | &flp->fl_wwnn)); | ||
| 1789 | } else { | 1551 | } else { |
| 1790 | lport->e_d_tov = e_d_tov; | 1552 | FC_LPORT_DBG(lport, "FLOGI RJT or bad response\n"); |
| 1791 | lport->r_a_tov = r_a_tov; | 1553 | fc_lport_error(lport, fp); |
| 1792 | fc_host_fabric_name(lport->host) = | ||
| 1793 | get_unaligned_be64(&flp->fl_wwnn); | ||
| 1794 | fc_lport_set_port_id(lport, did, fp); | ||
| 1795 | fc_lport_enter_dns(lport); | ||
| 1796 | } | 1554 | } |
| 1797 | 1555 | ||
| 1798 | out: | 1556 | out: |
| @@ -1809,7 +1567,7 @@ EXPORT_SYMBOL(fc_lport_flogi_resp); | |||
| 1809 | * Locking Note: The lport lock is expected to be held before calling | 1567 | * Locking Note: The lport lock is expected to be held before calling |
| 1810 | * this routine. | 1568 | * this routine. |
| 1811 | */ | 1569 | */ |
| 1812 | static void fc_lport_enter_flogi(struct fc_lport *lport) | 1570 | void fc_lport_enter_flogi(struct fc_lport *lport) |
| 1813 | { | 1571 | { |
| 1814 | struct fc_frame *fp; | 1572 | struct fc_frame *fp; |
| 1815 | 1573 | ||
| @@ -1938,7 +1696,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
| 1938 | 1696 | ||
| 1939 | job->reply->reply_payload_rcv_len += | 1697 | job->reply->reply_payload_rcv_len += |
| 1940 | fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents, | 1698 | fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents, |
| 1941 | &info->offset, NULL); | 1699 | &info->offset, KM_BIO_SRC_IRQ, NULL); |
| 1942 | 1700 | ||
| 1943 | if (fr_eof(fp) == FC_EOF_T && | 1701 | if (fr_eof(fp) == FC_EOF_T && |
| 1944 | (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == | 1702 | (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == |
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c index 9fbf78ed821..f33b897e478 100644 --- a/drivers/scsi/libfc/fc_npiv.c +++ b/drivers/scsi/libfc/fc_npiv.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include <scsi/libfc.h> | 24 | #include <scsi/libfc.h> |
| 25 | #include <linux/export.h> | ||
| 26 | 25 | ||
| 27 | /** | 26 | /** |
| 28 | * fc_vport_create() - Create a new NPIV vport instance | 27 | * fc_vport_create() - Create a new NPIV vport instance |
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 83aa1efec87..760db761944 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
| @@ -51,7 +51,6 @@ | |||
| 51 | #include <linux/rcupdate.h> | 51 | #include <linux/rcupdate.h> |
| 52 | #include <linux/timer.h> | 52 | #include <linux/timer.h> |
| 53 | #include <linux/workqueue.h> | 53 | #include <linux/workqueue.h> |
| 54 | #include <linux/export.h> | ||
| 55 | #include <asm/unaligned.h> | 54 | #include <asm/unaligned.h> |
| 56 | 55 | ||
| 57 | #include <scsi/libfc.h> | 56 | #include <scsi/libfc.h> |
| @@ -391,7 +390,7 @@ static void fc_rport_work(struct work_struct *work) | |||
| 391 | * If it appears we are already logged in, ADISC is used to verify | 390 | * If it appears we are already logged in, ADISC is used to verify |
| 392 | * the setup. | 391 | * the setup. |
| 393 | */ | 392 | */ |
| 394 | static int fc_rport_login(struct fc_rport_priv *rdata) | 393 | int fc_rport_login(struct fc_rport_priv *rdata) |
| 395 | { | 394 | { |
| 396 | mutex_lock(&rdata->rp_mutex); | 395 | mutex_lock(&rdata->rp_mutex); |
| 397 | 396 | ||
| @@ -451,7 +450,7 @@ static void fc_rport_enter_delete(struct fc_rport_priv *rdata, | |||
| 451 | * function will hold the rport lock, call an _enter_* | 450 | * function will hold the rport lock, call an _enter_* |
| 452 | * function and then unlock the rport. | 451 | * function and then unlock the rport. |
| 453 | */ | 452 | */ |
| 454 | static int fc_rport_logoff(struct fc_rport_priv *rdata) | 453 | int fc_rport_logoff(struct fc_rport_priv *rdata) |
| 455 | { | 454 | { |
| 456 | mutex_lock(&rdata->rp_mutex); | 455 | mutex_lock(&rdata->rp_mutex); |
| 457 | 456 | ||
| @@ -653,8 +652,8 @@ static int fc_rport_login_complete(struct fc_rport_priv *rdata, | |||
| 653 | * @fp: The FLOGI response frame | 652 | * @fp: The FLOGI response frame |
| 654 | * @rp_arg: The remote port that received the FLOGI response | 653 | * @rp_arg: The remote port that received the FLOGI response |
| 655 | */ | 654 | */ |
| 656 | static void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | 655 | void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, |
| 657 | void *rp_arg) | 656 | void *rp_arg) |
| 658 | { | 657 | { |
| 659 | struct fc_rport_priv *rdata = rp_arg; | 658 | struct fc_rport_priv *rdata = rp_arg; |
| 660 | struct fc_lport *lport = rdata->local_port; | 659 | struct fc_lport *lport = rdata->local_port; |
| @@ -1520,7 +1519,7 @@ reject: | |||
| 1520 | * | 1519 | * |
| 1521 | * Locking Note: Called with the lport lock held. | 1520 | * Locking Note: Called with the lport lock held. |
| 1522 | */ | 1521 | */ |
| 1523 | static void fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp) | 1522 | void fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp) |
| 1524 | { | 1523 | { |
| 1525 | struct fc_seq_els_data els_data; | 1524 | struct fc_seq_els_data els_data; |
| 1526 | 1525 | ||
