aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-06 00:11:38 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-06 00:11:42 -0400
commited011b22ce567eabefa9ea571d3721c10ecd0553 (patch)
treec7aee6684613075c772388a99a9137014549434e /drivers/net/cnic.c
parent85bac32c4a52c592b857f2c360cc5ec93a097d70 (diff)
parente07cccf4046978df10f2e13fe2b99b2f9b3a65db (diff)
Merge commit 'v2.6.31-rc9' into tracing/core
Merge reason: move from -rc5 to -rc9. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c143
1 files changed, 104 insertions, 39 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 4869d77cbe91..74c342959b7b 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -138,6 +138,16 @@ static struct cnic_dev *cnic_from_netdev(struct net_device *netdev)
138 return NULL; 138 return NULL;
139} 139}
140 140
141static inline void ulp_get(struct cnic_ulp_ops *ulp_ops)
142{
143 atomic_inc(&ulp_ops->ref_count);
144}
145
146static inline void ulp_put(struct cnic_ulp_ops *ulp_ops)
147{
148 atomic_dec(&ulp_ops->ref_count);
149}
150
141static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val) 151static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val)
142{ 152{
143 struct cnic_local *cp = dev->cnic_priv; 153 struct cnic_local *cp = dev->cnic_priv;
@@ -358,6 +368,7 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
358 } 368 }
359 read_unlock(&cnic_dev_lock); 369 read_unlock(&cnic_dev_lock);
360 370
371 atomic_set(&ulp_ops->ref_count, 0);
361 rcu_assign_pointer(cnic_ulp_tbl[ulp_type], ulp_ops); 372 rcu_assign_pointer(cnic_ulp_tbl[ulp_type], ulp_ops);
362 mutex_unlock(&cnic_lock); 373 mutex_unlock(&cnic_lock);
363 374
@@ -379,6 +390,8 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
379int cnic_unregister_driver(int ulp_type) 390int cnic_unregister_driver(int ulp_type)
380{ 391{
381 struct cnic_dev *dev; 392 struct cnic_dev *dev;
393 struct cnic_ulp_ops *ulp_ops;
394 int i = 0;
382 395
383 if (ulp_type >= MAX_CNIC_ULP_TYPE) { 396 if (ulp_type >= MAX_CNIC_ULP_TYPE) {
384 printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n", 397 printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
@@ -386,7 +399,8 @@ int cnic_unregister_driver(int ulp_type)
386 return -EINVAL; 399 return -EINVAL;
387 } 400 }
388 mutex_lock(&cnic_lock); 401 mutex_lock(&cnic_lock);
389 if (!cnic_ulp_tbl[ulp_type]) { 402 ulp_ops = cnic_ulp_tbl[ulp_type];
403 if (!ulp_ops) {
390 printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not " 404 printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not "
391 "been registered\n", ulp_type); 405 "been registered\n", ulp_type);
392 goto out_unlock; 406 goto out_unlock;
@@ -411,6 +425,14 @@ int cnic_unregister_driver(int ulp_type)
411 425
412 mutex_unlock(&cnic_lock); 426 mutex_unlock(&cnic_lock);
413 synchronize_rcu(); 427 synchronize_rcu();
428 while ((atomic_read(&ulp_ops->ref_count) != 0) && (i < 20)) {
429 msleep(100);
430 i++;
431 }
432
433 if (atomic_read(&ulp_ops->ref_count) != 0)
434 printk(KERN_WARNING PFX "%s: Failed waiting for ref count to go"
435 " to zero.\n", dev->netdev->name);
414 return 0; 436 return 0;
415 437
416out_unlock: 438out_unlock:
@@ -466,6 +488,7 @@ EXPORT_SYMBOL(cnic_register_driver);
466static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) 488static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
467{ 489{
468 struct cnic_local *cp = dev->cnic_priv; 490 struct cnic_local *cp = dev->cnic_priv;
491 int i = 0;
469 492
470 if (ulp_type >= MAX_CNIC_ULP_TYPE) { 493 if (ulp_type >= MAX_CNIC_ULP_TYPE) {
471 printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n", 494 printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
@@ -486,6 +509,15 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
486 509
487 synchronize_rcu(); 510 synchronize_rcu();
488 511
512 while (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]) &&
513 i < 20) {
514 msleep(100);
515 i++;
516 }
517 if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
518 printk(KERN_WARNING PFX "%s: Failed waiting for ULP up call"
519 " to complete.\n", dev->netdev->name);
520
489 return 0; 521 return 0;
490} 522}
491EXPORT_SYMBOL(cnic_unregister_driver); 523EXPORT_SYMBOL(cnic_unregister_driver);
@@ -1076,18 +1108,23 @@ static void cnic_ulp_stop(struct cnic_dev *dev)
1076 if (cp->cnic_uinfo) 1108 if (cp->cnic_uinfo)
1077 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); 1109 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
1078 1110
1079 rcu_read_lock();
1080 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { 1111 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
1081 struct cnic_ulp_ops *ulp_ops; 1112 struct cnic_ulp_ops *ulp_ops;
1082 1113
1083 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); 1114 mutex_lock(&cnic_lock);
1084 if (!ulp_ops) 1115 ulp_ops = cp->ulp_ops[if_type];
1116 if (!ulp_ops) {
1117 mutex_unlock(&cnic_lock);
1085 continue; 1118 continue;
1119 }
1120 set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1121 mutex_unlock(&cnic_lock);
1086 1122
1087 if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) 1123 if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
1088 ulp_ops->cnic_stop(cp->ulp_handle[if_type]); 1124 ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
1125
1126 clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1089 } 1127 }
1090 rcu_read_unlock();
1091} 1128}
1092 1129
1093static void cnic_ulp_start(struct cnic_dev *dev) 1130static void cnic_ulp_start(struct cnic_dev *dev)
@@ -1095,18 +1132,23 @@ static void cnic_ulp_start(struct cnic_dev *dev)
1095 struct cnic_local *cp = dev->cnic_priv; 1132 struct cnic_local *cp = dev->cnic_priv;
1096 int if_type; 1133 int if_type;
1097 1134
1098 rcu_read_lock();
1099 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { 1135 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
1100 struct cnic_ulp_ops *ulp_ops; 1136 struct cnic_ulp_ops *ulp_ops;
1101 1137
1102 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); 1138 mutex_lock(&cnic_lock);
1103 if (!ulp_ops || !ulp_ops->cnic_start) 1139 ulp_ops = cp->ulp_ops[if_type];
1140 if (!ulp_ops || !ulp_ops->cnic_start) {
1141 mutex_unlock(&cnic_lock);
1104 continue; 1142 continue;
1143 }
1144 set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1145 mutex_unlock(&cnic_lock);
1105 1146
1106 if (!test_and_set_bit(ULP_F_START, &cp->ulp_flags[if_type])) 1147 if (!test_and_set_bit(ULP_F_START, &cp->ulp_flags[if_type]))
1107 ulp_ops->cnic_start(cp->ulp_handle[if_type]); 1148 ulp_ops->cnic_start(cp->ulp_handle[if_type]);
1149
1150 clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
1108 } 1151 }
1109 rcu_read_unlock();
1110} 1152}
1111 1153
1112static int cnic_ctl(void *data, struct cnic_ctl_info *info) 1154static int cnic_ctl(void *data, struct cnic_ctl_info *info)
@@ -1116,22 +1158,18 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
1116 switch (info->cmd) { 1158 switch (info->cmd) {
1117 case CNIC_CTL_STOP_CMD: 1159 case CNIC_CTL_STOP_CMD:
1118 cnic_hold(dev); 1160 cnic_hold(dev);
1119 mutex_lock(&cnic_lock);
1120 1161
1121 cnic_ulp_stop(dev); 1162 cnic_ulp_stop(dev);
1122 cnic_stop_hw(dev); 1163 cnic_stop_hw(dev);
1123 1164
1124 mutex_unlock(&cnic_lock);
1125 cnic_put(dev); 1165 cnic_put(dev);
1126 break; 1166 break;
1127 case CNIC_CTL_START_CMD: 1167 case CNIC_CTL_START_CMD:
1128 cnic_hold(dev); 1168 cnic_hold(dev);
1129 mutex_lock(&cnic_lock);
1130 1169
1131 if (!cnic_start_hw(dev)) 1170 if (!cnic_start_hw(dev))
1132 cnic_ulp_start(dev); 1171 cnic_ulp_start(dev);
1133 1172
1134 mutex_unlock(&cnic_lock);
1135 cnic_put(dev); 1173 cnic_put(dev);
1136 break; 1174 break;
1137 default: 1175 default:
@@ -1145,19 +1183,23 @@ static void cnic_ulp_init(struct cnic_dev *dev)
1145 int i; 1183 int i;
1146 struct cnic_local *cp = dev->cnic_priv; 1184 struct cnic_local *cp = dev->cnic_priv;
1147 1185
1148 rcu_read_lock();
1149 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) { 1186 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
1150 struct cnic_ulp_ops *ulp_ops; 1187 struct cnic_ulp_ops *ulp_ops;
1151 1188
1152 ulp_ops = rcu_dereference(cnic_ulp_tbl[i]); 1189 mutex_lock(&cnic_lock);
1153 if (!ulp_ops || !ulp_ops->cnic_init) 1190 ulp_ops = cnic_ulp_tbl[i];
1191 if (!ulp_ops || !ulp_ops->cnic_init) {
1192 mutex_unlock(&cnic_lock);
1154 continue; 1193 continue;
1194 }
1195 ulp_get(ulp_ops);
1196 mutex_unlock(&cnic_lock);
1155 1197
1156 if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[i])) 1198 if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[i]))
1157 ulp_ops->cnic_init(dev); 1199 ulp_ops->cnic_init(dev);
1158 1200
1201 ulp_put(ulp_ops);
1159 } 1202 }
1160 rcu_read_unlock();
1161} 1203}
1162 1204
1163static void cnic_ulp_exit(struct cnic_dev *dev) 1205static void cnic_ulp_exit(struct cnic_dev *dev)
@@ -1165,19 +1207,23 @@ static void cnic_ulp_exit(struct cnic_dev *dev)
1165 int i; 1207 int i;
1166 struct cnic_local *cp = dev->cnic_priv; 1208 struct cnic_local *cp = dev->cnic_priv;
1167 1209
1168 rcu_read_lock();
1169 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) { 1210 for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
1170 struct cnic_ulp_ops *ulp_ops; 1211 struct cnic_ulp_ops *ulp_ops;
1171 1212
1172 ulp_ops = rcu_dereference(cnic_ulp_tbl[i]); 1213 mutex_lock(&cnic_lock);
1173 if (!ulp_ops || !ulp_ops->cnic_exit) 1214 ulp_ops = cnic_ulp_tbl[i];
1215 if (!ulp_ops || !ulp_ops->cnic_exit) {
1216 mutex_unlock(&cnic_lock);
1174 continue; 1217 continue;
1218 }
1219 ulp_get(ulp_ops);
1220 mutex_unlock(&cnic_lock);
1175 1221
1176 if (test_and_clear_bit(ULP_F_INIT, &cp->ulp_flags[i])) 1222 if (test_and_clear_bit(ULP_F_INIT, &cp->ulp_flags[i]))
1177 ulp_ops->cnic_exit(dev); 1223 ulp_ops->cnic_exit(dev);
1178 1224
1225 ulp_put(ulp_ops);
1179 } 1226 }
1180 rcu_read_unlock();
1181} 1227}
1182 1228
1183static int cnic_cm_offload_pg(struct cnic_sock *csk) 1229static int cnic_cm_offload_pg(struct cnic_sock *csk)
@@ -2393,21 +2439,45 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
2393 return 0; 2439 return 0;
2394} 2440}
2395 2441
2396static int cnic_start_hw(struct cnic_dev *dev) 2442static int cnic_register_netdev(struct cnic_dev *dev)
2397{ 2443{
2398 struct cnic_local *cp = dev->cnic_priv; 2444 struct cnic_local *cp = dev->cnic_priv;
2399 struct cnic_eth_dev *ethdev = cp->ethdev; 2445 struct cnic_eth_dev *ethdev = cp->ethdev;
2400 int err; 2446 int err;
2401 2447
2402 if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) 2448 if (!ethdev)
2403 return -EALREADY; 2449 return -ENODEV;
2450
2451 if (ethdev->drv_state & CNIC_DRV_STATE_REGD)
2452 return 0;
2404 2453
2405 err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev); 2454 err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
2406 if (err) { 2455 if (err)
2407 printk(KERN_ERR PFX "%s: register_cnic failed\n", 2456 printk(KERN_ERR PFX "%s: register_cnic failed\n",
2408 dev->netdev->name); 2457 dev->netdev->name);
2409 goto err2; 2458
2410 } 2459 return err;
2460}
2461
2462static void cnic_unregister_netdev(struct cnic_dev *dev)
2463{
2464 struct cnic_local *cp = dev->cnic_priv;
2465 struct cnic_eth_dev *ethdev = cp->ethdev;
2466
2467 if (!ethdev)
2468 return;
2469
2470 ethdev->drv_unregister_cnic(dev->netdev);
2471}
2472
2473static int cnic_start_hw(struct cnic_dev *dev)
2474{
2475 struct cnic_local *cp = dev->cnic_priv;
2476 struct cnic_eth_dev *ethdev = cp->ethdev;
2477 int err;
2478
2479 if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
2480 return -EALREADY;
2411 2481
2412 dev->regview = ethdev->io_base; 2482 dev->regview = ethdev->io_base;
2413 cp->chip_id = ethdev->chip_id; 2483 cp->chip_id = ethdev->chip_id;
@@ -2438,18 +2508,13 @@ static int cnic_start_hw(struct cnic_dev *dev)
2438 return 0; 2508 return 0;
2439 2509
2440err1: 2510err1:
2441 ethdev->drv_unregister_cnic(dev->netdev);
2442 cp->free_resc(dev); 2511 cp->free_resc(dev);
2443 pci_dev_put(dev->pcidev); 2512 pci_dev_put(dev->pcidev);
2444err2:
2445 return err; 2513 return err;
2446} 2514}
2447 2515
2448static void cnic_stop_bnx2_hw(struct cnic_dev *dev) 2516static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
2449{ 2517{
2450 struct cnic_local *cp = dev->cnic_priv;
2451 struct cnic_eth_dev *ethdev = cp->ethdev;
2452
2453 cnic_disable_bnx2_int_sync(dev); 2518 cnic_disable_bnx2_int_sync(dev);
2454 2519
2455 cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0); 2520 cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
@@ -2461,8 +2526,6 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
2461 cnic_setup_5709_context(dev, 0); 2526 cnic_setup_5709_context(dev, 0);
2462 cnic_free_irq(dev); 2527 cnic_free_irq(dev);
2463 2528
2464 ethdev->drv_unregister_cnic(dev->netdev);
2465
2466 cnic_free_resc(dev); 2529 cnic_free_resc(dev);
2467} 2530}
2468 2531
@@ -2543,7 +2606,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev)
2543 probe = symbol_get(bnx2_cnic_probe); 2606 probe = symbol_get(bnx2_cnic_probe);
2544 if (probe) { 2607 if (probe) {
2545 ethdev = (*probe)(dev); 2608 ethdev = (*probe)(dev);
2546 symbol_put_addr(probe); 2609 symbol_put(bnx2_cnic_probe);
2547 } 2610 }
2548 if (!ethdev) 2611 if (!ethdev)
2549 return NULL; 2612 return NULL;
@@ -2646,10 +2709,12 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
2646 else if (event == NETDEV_UNREGISTER) 2709 else if (event == NETDEV_UNREGISTER)
2647 cnic_ulp_exit(dev); 2710 cnic_ulp_exit(dev);
2648 else if (event == NETDEV_UP) { 2711 else if (event == NETDEV_UP) {
2649 mutex_lock(&cnic_lock); 2712 if (cnic_register_netdev(dev) != 0) {
2713 cnic_put(dev);
2714 goto done;
2715 }
2650 if (!cnic_start_hw(dev)) 2716 if (!cnic_start_hw(dev))
2651 cnic_ulp_start(dev); 2717 cnic_ulp_start(dev);
2652 mutex_unlock(&cnic_lock);
2653 } 2718 }
2654 2719
2655 rcu_read_lock(); 2720 rcu_read_lock();
@@ -2668,10 +2733,9 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
2668 rcu_read_unlock(); 2733 rcu_read_unlock();
2669 2734
2670 if (event == NETDEV_GOING_DOWN) { 2735 if (event == NETDEV_GOING_DOWN) {
2671 mutex_lock(&cnic_lock);
2672 cnic_ulp_stop(dev); 2736 cnic_ulp_stop(dev);
2673 cnic_stop_hw(dev); 2737 cnic_stop_hw(dev);
2674 mutex_unlock(&cnic_lock); 2738 cnic_unregister_netdev(dev);
2675 } else if (event == NETDEV_UNREGISTER) { 2739 } else if (event == NETDEV_UNREGISTER) {
2676 write_lock(&cnic_dev_lock); 2740 write_lock(&cnic_dev_lock);
2677 list_del_init(&dev->list); 2741 list_del_init(&dev->list);
@@ -2703,6 +2767,7 @@ static void cnic_release(void)
2703 } 2767 }
2704 2768
2705 cnic_ulp_exit(dev); 2769 cnic_ulp_exit(dev);
2770 cnic_unregister_netdev(dev);
2706 list_del_init(&dev->list); 2771 list_del_init(&dev->list);
2707 cnic_free_dev(dev); 2772 cnic_free_dev(dev);
2708 } 2773 }