diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-15 06:02:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-15 06:02:23 -0400 |
commit | 9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (patch) | |
tree | 8d104ec2a459346b99413b0b77421ca7b9936c1a /drivers/scsi/fcoe/fcoe.c | |
parent | ca44d6e60f9de26281fda203f58b570e1748c015 (diff) | |
parent | 45e3e1935e2857c54783291107d33323b3ef33c8 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/scsi/fcoe/fcoe.c
net/core/drop_monitor.c
net/core/net-traces.c
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 95 |
1 files changed, 36 insertions, 59 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index f791348871fc..c15878e88157 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -54,7 +54,6 @@ MODULE_LICENSE("GPL v2"); | |||
54 | /* fcoe host list */ | 54 | /* fcoe host list */ |
55 | LIST_HEAD(fcoe_hostlist); | 55 | LIST_HEAD(fcoe_hostlist); |
56 | DEFINE_RWLOCK(fcoe_hostlist_lock); | 56 | DEFINE_RWLOCK(fcoe_hostlist_lock); |
57 | DEFINE_TIMER(fcoe_timer, NULL, 0, 0); | ||
58 | DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); | 57 | DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); |
59 | 58 | ||
60 | /* Function Prototypes */ | 59 | /* Function Prototypes */ |
@@ -71,7 +70,7 @@ static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); | |||
71 | static int fcoe_hostlist_add(const struct fc_lport *); | 70 | static int fcoe_hostlist_add(const struct fc_lport *); |
72 | static int fcoe_hostlist_remove(const struct fc_lport *); | 71 | static int fcoe_hostlist_remove(const struct fc_lport *); |
73 | 72 | ||
74 | static int fcoe_check_wait_queue(struct fc_lport *); | 73 | static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *); |
75 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); | 74 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); |
76 | static void fcoe_dev_setup(void); | 75 | static void fcoe_dev_setup(void); |
77 | static void fcoe_dev_cleanup(void); | 76 | static void fcoe_dev_cleanup(void); |
@@ -198,6 +197,7 @@ static int fcoe_lport_config(struct fc_lport *lp) | |||
198 | lp->link_up = 0; | 197 | lp->link_up = 0; |
199 | lp->qfull = 0; | 198 | lp->qfull = 0; |
200 | lp->max_retry_count = 3; | 199 | lp->max_retry_count = 3; |
200 | lp->max_rport_retry_count = 3; | ||
201 | lp->e_d_tov = 2 * 1000; /* FC-FS default */ | 201 | lp->e_d_tov = 2 * 1000; /* FC-FS default */ |
202 | lp->r_a_tov = 2 * 2 * 1000; | 202 | lp->r_a_tov = 2 * 2 * 1000; |
203 | lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | | 203 | lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | |
@@ -243,6 +243,18 @@ void fcoe_netdev_cleanup(struct fcoe_softc *fc) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | /** | 245 | /** |
246 | * fcoe_queue_timer() - fcoe queue timer | ||
247 | * @lp: the fc_lport pointer | ||
248 | * | ||
249 | * Calls fcoe_check_wait_queue on timeout | ||
250 | * | ||
251 | */ | ||
252 | static void fcoe_queue_timer(ulong lp) | ||
253 | { | ||
254 | fcoe_check_wait_queue((struct fc_lport *)lp, NULL); | ||
255 | } | ||
256 | |||
257 | /** | ||
246 | * fcoe_netdev_config() - Set up netdev for SW FCoE | 258 | * fcoe_netdev_config() - Set up netdev for SW FCoE |
247 | * @lp : ptr to the fc_lport | 259 | * @lp : ptr to the fc_lport |
248 | * @netdev : ptr to the associated netdevice struct | 260 | * @netdev : ptr to the associated netdevice struct |
@@ -313,6 +325,7 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
313 | } | 325 | } |
314 | skb_queue_head_init(&fc->fcoe_pending_queue); | 326 | skb_queue_head_init(&fc->fcoe_pending_queue); |
315 | fc->fcoe_pending_queue_active = 0; | 327 | fc->fcoe_pending_queue_active = 0; |
328 | setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp); | ||
316 | 329 | ||
317 | /* look for SAN MAC address, if multiple SAN MACs exist, only | 330 | /* look for SAN MAC address, if multiple SAN MACs exist, only |
318 | * use the first one for SPMA */ | 331 | * use the first one for SPMA */ |
@@ -474,6 +487,9 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
474 | /* Free existing skbs */ | 487 | /* Free existing skbs */ |
475 | fcoe_clean_pending_queue(lp); | 488 | fcoe_clean_pending_queue(lp); |
476 | 489 | ||
490 | /* Stop the timer */ | ||
491 | del_timer_sync(&fc->timer); | ||
492 | |||
477 | /* Free memory used by statistical counters */ | 493 | /* Free memory used by statistical counters */ |
478 | fc_lport_free_stats(lp); | 494 | fc_lport_free_stats(lp); |
479 | 495 | ||
@@ -1021,7 +1037,7 @@ u32 fcoe_fc_crc(struct fc_frame *fp) | |||
1021 | */ | 1037 | */ |
1022 | int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | 1038 | int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) |
1023 | { | 1039 | { |
1024 | int wlen, rc = 0; | 1040 | int wlen; |
1025 | u32 crc; | 1041 | u32 crc; |
1026 | struct ethhdr *eh; | 1042 | struct ethhdr *eh; |
1027 | struct fcoe_crc_eof *cp; | 1043 | struct fcoe_crc_eof *cp; |
@@ -1054,8 +1070,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1054 | sof = fr_sof(fp); | 1070 | sof = fr_sof(fp); |
1055 | eof = fr_eof(fp); | 1071 | eof = fr_eof(fp); |
1056 | 1072 | ||
1057 | elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ? | 1073 | elen = sizeof(struct ethhdr); |
1058 | sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr); | ||
1059 | hlen = sizeof(struct fcoe_hdr); | 1074 | hlen = sizeof(struct fcoe_hdr); |
1060 | tlen = sizeof(struct fcoe_crc_eof); | 1075 | tlen = sizeof(struct fcoe_crc_eof); |
1061 | wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE; | 1076 | wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE; |
@@ -1140,18 +1155,9 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1140 | /* send down to lld */ | 1155 | /* send down to lld */ |
1141 | fr_dev(fp) = lp; | 1156 | fr_dev(fp) = lp; |
1142 | if (fc->fcoe_pending_queue.qlen) | 1157 | if (fc->fcoe_pending_queue.qlen) |
1143 | rc = fcoe_check_wait_queue(lp); | 1158 | fcoe_check_wait_queue(lp, skb); |
1144 | 1159 | else if (fcoe_start_io(skb)) | |
1145 | if (rc == 0) | 1160 | fcoe_check_wait_queue(lp, skb); |
1146 | rc = fcoe_start_io(skb); | ||
1147 | |||
1148 | if (rc) { | ||
1149 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | ||
1150 | __skb_queue_tail(&fc->fcoe_pending_queue, skb); | ||
1151 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | ||
1152 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | ||
1153 | lp->qfull = 1; | ||
1154 | } | ||
1155 | 1161 | ||
1156 | return 0; | 1162 | return 0; |
1157 | } | 1163 | } |
@@ -1301,32 +1307,6 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1301 | } | 1307 | } |
1302 | 1308 | ||
1303 | /** | 1309 | /** |
1304 | * fcoe_watchdog() - fcoe timer callback | ||
1305 | * @vp: | ||
1306 | * | ||
1307 | * This checks the pending queue length for fcoe and set lport qfull | ||
1308 | * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the | ||
1309 | * fcoe_hostlist. | ||
1310 | * | ||
1311 | * Returns: 0 for success | ||
1312 | */ | ||
1313 | void fcoe_watchdog(ulong vp) | ||
1314 | { | ||
1315 | struct fcoe_softc *fc; | ||
1316 | |||
1317 | read_lock(&fcoe_hostlist_lock); | ||
1318 | list_for_each_entry(fc, &fcoe_hostlist, list) { | ||
1319 | if (fc->ctlr.lp) | ||
1320 | fcoe_check_wait_queue(fc->ctlr.lp); | ||
1321 | } | ||
1322 | read_unlock(&fcoe_hostlist_lock); | ||
1323 | |||
1324 | fcoe_timer.expires = jiffies + (1 * HZ); | ||
1325 | add_timer(&fcoe_timer); | ||
1326 | } | ||
1327 | |||
1328 | |||
1329 | /** | ||
1330 | * fcoe_check_wait_queue() - attempt to clear the transmit backlog | 1310 | * fcoe_check_wait_queue() - attempt to clear the transmit backlog |
1331 | * @lp: the fc_lport | 1311 | * @lp: the fc_lport |
1332 | * | 1312 | * |
@@ -1338,16 +1318,17 @@ void fcoe_watchdog(ulong vp) | |||
1338 | * The wait_queue is used when the skb transmit fails. skb will go | 1318 | * The wait_queue is used when the skb transmit fails. skb will go |
1339 | * in the wait_queue which will be emptied by the timer function or | 1319 | * in the wait_queue which will be emptied by the timer function or |
1340 | * by the next skb transmit. | 1320 | * by the next skb transmit. |
1341 | * | ||
1342 | * Returns: 0 for success | ||
1343 | */ | 1321 | */ |
1344 | static int fcoe_check_wait_queue(struct fc_lport *lp) | 1322 | static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) |
1345 | { | 1323 | { |
1346 | struct fcoe_softc *fc = lport_priv(lp); | 1324 | struct fcoe_softc *fc = lport_priv(lp); |
1347 | struct sk_buff *skb; | 1325 | int rc; |
1348 | int rc = -1; | ||
1349 | 1326 | ||
1350 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 1327 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
1328 | |||
1329 | if (skb) | ||
1330 | __skb_queue_tail(&fc->fcoe_pending_queue, skb); | ||
1331 | |||
1351 | if (fc->fcoe_pending_queue_active) | 1332 | if (fc->fcoe_pending_queue_active) |
1352 | goto out; | 1333 | goto out; |
1353 | fc->fcoe_pending_queue_active = 1; | 1334 | fc->fcoe_pending_queue_active = 1; |
@@ -1373,23 +1354,26 @@ static int fcoe_check_wait_queue(struct fc_lport *lp) | |||
1373 | 1354 | ||
1374 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | 1355 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) |
1375 | lp->qfull = 0; | 1356 | lp->qfull = 0; |
1357 | if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer)) | ||
1358 | mod_timer(&fc->timer, jiffies + 2); | ||
1376 | fc->fcoe_pending_queue_active = 0; | 1359 | fc->fcoe_pending_queue_active = 0; |
1377 | rc = fc->fcoe_pending_queue.qlen; | ||
1378 | out: | 1360 | out: |
1361 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | ||
1362 | lp->qfull = 1; | ||
1379 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 1363 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); |
1380 | return rc; | 1364 | return; |
1381 | } | 1365 | } |
1382 | 1366 | ||
1383 | /** | 1367 | /** |
1384 | * fcoe_dev_setup() - setup link change notification interface | 1368 | * fcoe_dev_setup() - setup link change notification interface |
1385 | */ | 1369 | */ |
1386 | static void fcoe_dev_setup() | 1370 | static void fcoe_dev_setup(void) |
1387 | { | 1371 | { |
1388 | register_netdevice_notifier(&fcoe_notifier); | 1372 | register_netdevice_notifier(&fcoe_notifier); |
1389 | } | 1373 | } |
1390 | 1374 | ||
1391 | /** | 1375 | /** |
1392 | * fcoe_dev_setup() - cleanup link change notification interface | 1376 | * fcoe_dev_cleanup() - cleanup link change notification interface |
1393 | */ | 1377 | */ |
1394 | static void fcoe_dev_cleanup(void) | 1378 | static void fcoe_dev_cleanup(void) |
1395 | { | 1379 | { |
@@ -1848,10 +1832,6 @@ static int __init fcoe_init(void) | |||
1848 | /* Setup link change notification */ | 1832 | /* Setup link change notification */ |
1849 | fcoe_dev_setup(); | 1833 | fcoe_dev_setup(); |
1850 | 1834 | ||
1851 | setup_timer(&fcoe_timer, fcoe_watchdog, 0); | ||
1852 | |||
1853 | mod_timer(&fcoe_timer, jiffies + (10 * HZ)); | ||
1854 | |||
1855 | fcoe_if_init(); | 1835 | fcoe_if_init(); |
1856 | 1836 | ||
1857 | return 0; | 1837 | return 0; |
@@ -1877,9 +1857,6 @@ static void __exit fcoe_exit(void) | |||
1877 | 1857 | ||
1878 | fcoe_dev_cleanup(); | 1858 | fcoe_dev_cleanup(); |
1879 | 1859 | ||
1880 | /* Stop the timer */ | ||
1881 | del_timer_sync(&fcoe_timer); | ||
1882 | |||
1883 | /* releases the associated fcoe hosts */ | 1860 | /* releases the associated fcoe hosts */ |
1884 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) | 1861 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) |
1885 | fcoe_if_destroy(fc->real_dev); | 1862 | fcoe_if_destroy(fc->real_dev); |