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 | ||