diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_exch.c')
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 992af05aacf1..2bc22be5f849 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -32,18 +32,7 @@ | |||
32 | #include <scsi/libfc.h> | 32 | #include <scsi/libfc.h> |
33 | #include <scsi/fc_encode.h> | 33 | #include <scsi/fc_encode.h> |
34 | 34 | ||
35 | /* | 35 | static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ |
36 | * fc_exch_debug can be set in debugger or at compile time to get more logs. | ||
37 | */ | ||
38 | static int fc_exch_debug; | ||
39 | |||
40 | #define FC_DEBUG_EXCH(fmt...) \ | ||
41 | do { \ | ||
42 | if (fc_exch_debug) \ | ||
43 | FC_DBG(fmt); \ | ||
44 | } while (0) | ||
45 | |||
46 | static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ | ||
47 | 36 | ||
48 | /* | 37 | /* |
49 | * Structure and function definitions for managing Fibre Channel Exchanges | 38 | * Structure and function definitions for managing Fibre Channel Exchanges |
@@ -333,8 +322,8 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep, | |||
333 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) | 322 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) |
334 | return; | 323 | return; |
335 | 324 | ||
336 | FC_DEBUG_EXCH("Exchange (%4x) timed out, notifying the upper layer\n", | 325 | FC_EXCH_DBG(ep, "Exchange timed out, notifying the upper layer\n"); |
337 | ep->xid); | 326 | |
338 | if (schedule_delayed_work(&ep->timeout_work, | 327 | if (schedule_delayed_work(&ep->timeout_work, |
339 | msecs_to_jiffies(timer_msec))) | 328 | msecs_to_jiffies(timer_msec))) |
340 | fc_exch_hold(ep); /* hold for timer */ | 329 | fc_exch_hold(ep); /* hold for timer */ |
@@ -545,7 +534,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, | |||
545 | /* alloc a new xid */ | 534 | /* alloc a new xid */ |
546 | xid = fc_em_alloc_xid(mp, fp); | 535 | xid = fc_em_alloc_xid(mp, fp); |
547 | if (!xid) { | 536 | if (!xid) { |
548 | printk(KERN_ERR "fc_em_alloc_xid() failed\n"); | 537 | printk(KERN_WARNING "libfc: Failed to allocate an exhange\n"); |
549 | goto err; | 538 | goto err; |
550 | } | 539 | } |
551 | } | 540 | } |
@@ -820,8 +809,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp) | |||
820 | struct fc_exch *ep = fc_seq_exch(sp); | 809 | struct fc_exch *ep = fc_seq_exch(sp); |
821 | 810 | ||
822 | sp = fc_seq_alloc(ep, ep->seq_id++); | 811 | sp = fc_seq_alloc(ep, ep->seq_id++); |
823 | FC_DEBUG_EXCH("exch %4x f_ctl %6x seq %2x\n", | 812 | FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", |
824 | ep->xid, ep->f_ctl, sp->id); | 813 | ep->f_ctl, sp->id); |
825 | return sp; | 814 | return sp; |
826 | } | 815 | } |
827 | /* | 816 | /* |
@@ -901,7 +890,7 @@ void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, | |||
901 | fc_exch_els_rec(sp, els_data->fp); | 890 | fc_exch_els_rec(sp, els_data->fp); |
902 | break; | 891 | break; |
903 | default: | 892 | default: |
904 | FC_DBG("Invalid ELS CMD:%x\n", els_cmd); | 893 | FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd); |
905 | } | 894 | } |
906 | } | 895 | } |
907 | EXPORT_SYMBOL(fc_seq_els_rsp_send); | 896 | EXPORT_SYMBOL(fc_seq_els_rsp_send); |
@@ -1134,7 +1123,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, | |||
1134 | lp->tt.lport_recv(lp, sp, fp); | 1123 | lp->tt.lport_recv(lp, sp, fp); |
1135 | fc_exch_release(ep); /* release from lookup */ | 1124 | fc_exch_release(ep); /* release from lookup */ |
1136 | } else { | 1125 | } else { |
1137 | FC_DEBUG_EXCH("exch/seq lookup failed: reject %x\n", reject); | 1126 | FC_EM_DBG(mp, "exch/seq lookup failed: reject %x\n", reject); |
1138 | fc_frame_free(fp); | 1127 | fc_frame_free(fp); |
1139 | } | 1128 | } |
1140 | } | 1129 | } |
@@ -1159,6 +1148,10 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
1159 | atomic_inc(&mp->stats.xid_not_found); | 1148 | atomic_inc(&mp->stats.xid_not_found); |
1160 | goto out; | 1149 | goto out; |
1161 | } | 1150 | } |
1151 | if (ep->esb_stat & ESB_ST_COMPLETE) { | ||
1152 | atomic_inc(&mp->stats.xid_not_found); | ||
1153 | goto out; | ||
1154 | } | ||
1162 | if (ep->rxid == FC_XID_UNKNOWN) | 1155 | if (ep->rxid == FC_XID_UNKNOWN) |
1163 | ep->rxid = ntohs(fh->fh_rx_id); | 1156 | ep->rxid = ntohs(fh->fh_rx_id); |
1164 | if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { | 1157 | if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { |
@@ -1238,10 +1231,10 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
1238 | sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ | 1231 | sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ |
1239 | if (!sp) { | 1232 | if (!sp) { |
1240 | atomic_inc(&mp->stats.xid_not_found); | 1233 | atomic_inc(&mp->stats.xid_not_found); |
1241 | FC_DEBUG_EXCH("seq lookup failed\n"); | 1234 | FC_EM_DBG(mp, "seq lookup failed\n"); |
1242 | } else { | 1235 | } else { |
1243 | atomic_inc(&mp->stats.non_bls_resp); | 1236 | atomic_inc(&mp->stats.non_bls_resp); |
1244 | FC_DEBUG_EXCH("non-BLS response to sequence"); | 1237 | FC_EM_DBG(mp, "non-BLS response to sequence"); |
1245 | } | 1238 | } |
1246 | fc_frame_free(fp); | 1239 | fc_frame_free(fp); |
1247 | } | 1240 | } |
@@ -1262,8 +1255,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) | |||
1262 | int rc = 1, has_rec = 0; | 1255 | int rc = 1, has_rec = 0; |
1263 | 1256 | ||
1264 | fh = fc_frame_header_get(fp); | 1257 | fh = fc_frame_header_get(fp); |
1265 | FC_DEBUG_EXCH("exch: BLS rctl %x - %s\n", | 1258 | FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, |
1266 | fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl)); | 1259 | fc_exch_rctl_name(fh->fh_r_ctl)); |
1267 | 1260 | ||
1268 | if (cancel_delayed_work_sync(&ep->timeout_work)) | 1261 | if (cancel_delayed_work_sync(&ep->timeout_work)) |
1269 | fc_exch_release(ep); /* release from pending timer hold */ | 1262 | fc_exch_release(ep); /* release from pending timer hold */ |
@@ -1355,9 +1348,9 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
1355 | case FC_RCTL_ACK_0: | 1348 | case FC_RCTL_ACK_0: |
1356 | break; | 1349 | break; |
1357 | default: | 1350 | default: |
1358 | FC_DEBUG_EXCH("BLS rctl %x - %s received", | 1351 | FC_EXCH_DBG(ep, "BLS rctl %x - %s received", |
1359 | fh->fh_r_ctl, | 1352 | fh->fh_r_ctl, |
1360 | fc_exch_rctl_name(fh->fh_r_ctl)); | 1353 | fc_exch_rctl_name(fh->fh_r_ctl)); |
1361 | break; | 1354 | break; |
1362 | } | 1355 | } |
1363 | fc_frame_free(fp); | 1356 | fc_frame_free(fp); |
@@ -1595,7 +1588,8 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) | |||
1595 | 1588 | ||
1596 | if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) | 1589 | if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) |
1597 | goto cleanup; | 1590 | goto cleanup; |
1598 | FC_DBG("Cannot process RRQ, because of frame error %d\n", err); | 1591 | FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, " |
1592 | "frame error %d\n", err); | ||
1599 | return; | 1593 | return; |
1600 | } | 1594 | } |
1601 | 1595 | ||
@@ -1604,12 +1598,13 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) | |||
1604 | 1598 | ||
1605 | switch (op) { | 1599 | switch (op) { |
1606 | case ELS_LS_RJT: | 1600 | case ELS_LS_RJT: |
1607 | FC_DBG("LS_RJT for RRQ"); | 1601 | FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ"); |
1608 | /* fall through */ | 1602 | /* fall through */ |
1609 | case ELS_LS_ACC: | 1603 | case ELS_LS_ACC: |
1610 | goto cleanup; | 1604 | goto cleanup; |
1611 | default: | 1605 | default: |
1612 | FC_DBG("unexpected response op %x for RRQ", op); | 1606 | FC_EXCH_DBG(aborted_ep, "unexpected response op %x " |
1607 | "for RRQ", op); | ||
1613 | return; | 1608 | return; |
1614 | } | 1609 | } |
1615 | 1610 | ||
@@ -1736,8 +1731,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, | |||
1736 | size_t len; | 1731 | size_t len; |
1737 | 1732 | ||
1738 | if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { | 1733 | if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { |
1739 | FC_DBG("Invalid min_xid 0x:%x and max_xid 0x:%x\n", | 1734 | FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n", |
1740 | min_xid, max_xid); | 1735 | min_xid, max_xid); |
1741 | return NULL; | 1736 | return NULL; |
1742 | } | 1737 | } |
1743 | 1738 | ||
@@ -1874,7 +1869,8 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, | |||
1874 | 1869 | ||
1875 | /* lport lock ? */ | 1870 | /* lport lock ? */ |
1876 | if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { | 1871 | if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { |
1877 | FC_DBG("fc_lport or EM is not allocated and configured"); | 1872 | FC_LPORT_DBG(lp, "Receiving frames for an lport that " |
1873 | "has not been initialized correctly\n"); | ||
1878 | fc_frame_free(fp); | 1874 | fc_frame_free(fp); |
1879 | return; | 1875 | return; |
1880 | } | 1876 | } |
@@ -1900,7 +1896,7 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, | |||
1900 | fc_exch_recv_req(lp, mp, fp); | 1896 | fc_exch_recv_req(lp, mp, fp); |
1901 | break; | 1897 | break; |
1902 | default: | 1898 | default: |
1903 | FC_DBG("dropping invalid frame (eof %x)", fr_eof(fp)); | 1899 | FC_EM_DBG(mp, "dropping invalid frame (eof %x)", fr_eof(fp)); |
1904 | fc_frame_free(fp); | 1900 | fc_frame_free(fp); |
1905 | break; | 1901 | break; |
1906 | } | 1902 | } |