aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
commit9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (patch)
tree8d104ec2a459346b99413b0b77421ca7b9936c1a /drivers/scsi/fcoe/fcoe.c
parentca44d6e60f9de26281fda203f58b570e1748c015 (diff)
parent45e3e1935e2857c54783291107d33323b3ef33c8 (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.c95
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 */
55LIST_HEAD(fcoe_hostlist); 55LIST_HEAD(fcoe_hostlist);
56DEFINE_RWLOCK(fcoe_hostlist_lock); 56DEFINE_RWLOCK(fcoe_hostlist_lock);
57DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
58DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); 57DEFINE_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 *);
71static int fcoe_hostlist_add(const struct fc_lport *); 70static int fcoe_hostlist_add(const struct fc_lport *);
72static int fcoe_hostlist_remove(const struct fc_lport *); 71static int fcoe_hostlist_remove(const struct fc_lport *);
73 72
74static int fcoe_check_wait_queue(struct fc_lport *); 73static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *);
75static int fcoe_device_notification(struct notifier_block *, ulong, void *); 74static int fcoe_device_notification(struct notifier_block *, ulong, void *);
76static void fcoe_dev_setup(void); 75static void fcoe_dev_setup(void);
77static void fcoe_dev_cleanup(void); 76static 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 */
252static 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 */
1022int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) 1038int 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 */
1313void 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 */
1344static int fcoe_check_wait_queue(struct fc_lport *lp) 1322static 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;
1378out: 1360out:
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 */
1386static void fcoe_dev_setup() 1370static 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 */
1394static void fcoe_dev_cleanup(void) 1378static 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);