diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-29 13:48:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-29 13:48:48 -0400 |
commit | e389f9aec689209724105ae80a6c91fd2e747bc9 (patch) | |
tree | 3cc88a3e785e4f2ffeaa9dad0da695cfa437d4fe /drivers/net/ehea/ehea_qmr.c | |
parent | f73b0a08eae0e28c50db5dd5ab8245546918bfb6 (diff) | |
parent | b4cf205846463a0a23a917bb18ad833bc9a8c0bb (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (107 commits)
smc911x: fix compilation breakage wjen debug is on
[netdrvr] eexpress: minor corrections
add NAPI support to sb1250-mac.c
ixgb: ROUND_UP macro cleanup in drivers/net/ixgb
e1000: ROUND_UP macro cleanup in drivers/net/e1000
Generic HDLC sparse annotations
e100: Optionally use I/O mode only to access register space
e100: allow bad MAC address when running with invalid eeprom csum
ehea: fix for dlpar support
ehea: fix for sysfs entries
3C509: Remove unnecessary include of <linux/pm_legacy.h>
NetXen: Fix for vmalloc issues
NetXen: Fixes for Power PC architecture
NetXen: Port swap feature for multi port cards
NetXen: Removal of redundant macros
NetXen: Multi PCI support for Quad cards
NetXen: Removal of redundant argument passing
NetXen: Use multiple PCI functions
[netdrvr e100] experiment with doing RX in a similar manner to eepro100
[PATCH] ieee80211: add missing global needed by IEEE80211_DEBUG_XXXX
...
Diffstat (limited to 'drivers/net/ehea/ehea_qmr.c')
-rw-r--r-- | drivers/net/ehea/ehea_qmr.c | 184 |
1 files changed, 134 insertions, 50 deletions
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 96ff3b679996..f24a8862977d 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -197,7 +197,7 @@ out_kill_hwq: | |||
197 | hw_queue_dtor(&cq->hw_queue); | 197 | hw_queue_dtor(&cq->hw_queue); |
198 | 198 | ||
199 | out_freeres: | 199 | out_freeres: |
200 | ehea_h_free_resource(adapter->handle, cq->fw_handle); | 200 | ehea_h_free_resource(adapter->handle, cq->fw_handle, FORCE_FREE); |
201 | 201 | ||
202 | out_freemem: | 202 | out_freemem: |
203 | kfree(cq); | 203 | kfree(cq); |
@@ -206,25 +206,38 @@ out_nomem: | |||
206 | return NULL; | 206 | return NULL; |
207 | } | 207 | } |
208 | 208 | ||
209 | int ehea_destroy_cq(struct ehea_cq *cq) | 209 | u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force) |
210 | { | 210 | { |
211 | u64 adapter_handle, hret; | 211 | u64 hret; |
212 | u64 adapter_handle = cq->adapter->handle; | ||
213 | |||
214 | /* deregister all previous registered pages */ | ||
215 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force); | ||
216 | if (hret != H_SUCCESS) | ||
217 | return hret; | ||
218 | |||
219 | hw_queue_dtor(&cq->hw_queue); | ||
220 | kfree(cq); | ||
221 | |||
222 | return hret; | ||
223 | } | ||
212 | 224 | ||
225 | int ehea_destroy_cq(struct ehea_cq *cq) | ||
226 | { | ||
227 | u64 hret; | ||
213 | if (!cq) | 228 | if (!cq) |
214 | return 0; | 229 | return 0; |
215 | 230 | ||
216 | adapter_handle = cq->adapter->handle; | 231 | if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) { |
232 | ehea_error_data(cq->adapter, cq->fw_handle); | ||
233 | hret = ehea_destroy_cq_res(cq, FORCE_FREE); | ||
234 | } | ||
217 | 235 | ||
218 | /* deregister all previous registered pages */ | ||
219 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); | ||
220 | if (hret != H_SUCCESS) { | 236 | if (hret != H_SUCCESS) { |
221 | ehea_error("destroy CQ failed"); | 237 | ehea_error("destroy CQ failed"); |
222 | return -EIO; | 238 | return -EIO; |
223 | } | 239 | } |
224 | 240 | ||
225 | hw_queue_dtor(&cq->hw_queue); | ||
226 | kfree(cq); | ||
227 | |||
228 | return 0; | 241 | return 0; |
229 | } | 242 | } |
230 | 243 | ||
@@ -297,7 +310,7 @@ out_kill_hwq: | |||
297 | hw_queue_dtor(&eq->hw_queue); | 310 | hw_queue_dtor(&eq->hw_queue); |
298 | 311 | ||
299 | out_freeres: | 312 | out_freeres: |
300 | ehea_h_free_resource(adapter->handle, eq->fw_handle); | 313 | ehea_h_free_resource(adapter->handle, eq->fw_handle, FORCE_FREE); |
301 | 314 | ||
302 | out_freemem: | 315 | out_freemem: |
303 | kfree(eq); | 316 | kfree(eq); |
@@ -316,27 +329,41 @@ struct ehea_eqe *ehea_poll_eq(struct ehea_eq *eq) | |||
316 | return eqe; | 329 | return eqe; |
317 | } | 330 | } |
318 | 331 | ||
319 | int ehea_destroy_eq(struct ehea_eq *eq) | 332 | u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force) |
320 | { | 333 | { |
321 | u64 hret; | 334 | u64 hret; |
322 | unsigned long flags; | 335 | unsigned long flags; |
323 | 336 | ||
324 | if (!eq) | ||
325 | return 0; | ||
326 | |||
327 | spin_lock_irqsave(&eq->spinlock, flags); | 337 | spin_lock_irqsave(&eq->spinlock, flags); |
328 | 338 | ||
329 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle); | 339 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle, force); |
330 | spin_unlock_irqrestore(&eq->spinlock, flags); | 340 | spin_unlock_irqrestore(&eq->spinlock, flags); |
331 | 341 | ||
332 | if (hret != H_SUCCESS) { | 342 | if (hret != H_SUCCESS) |
333 | ehea_error("destroy_eq failed"); | 343 | return hret; |
334 | return -EIO; | ||
335 | } | ||
336 | 344 | ||
337 | hw_queue_dtor(&eq->hw_queue); | 345 | hw_queue_dtor(&eq->hw_queue); |
338 | kfree(eq); | 346 | kfree(eq); |
339 | 347 | ||
348 | return hret; | ||
349 | } | ||
350 | |||
351 | int ehea_destroy_eq(struct ehea_eq *eq) | ||
352 | { | ||
353 | u64 hret; | ||
354 | if (!eq) | ||
355 | return 0; | ||
356 | |||
357 | if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) { | ||
358 | ehea_error_data(eq->adapter, eq->fw_handle); | ||
359 | hret = ehea_destroy_eq_res(eq, FORCE_FREE); | ||
360 | } | ||
361 | |||
362 | if (hret != H_SUCCESS) { | ||
363 | ehea_error("destroy EQ failed"); | ||
364 | return -EIO; | ||
365 | } | ||
366 | |||
340 | return 0; | 367 | return 0; |
341 | } | 368 | } |
342 | 369 | ||
@@ -471,41 +498,56 @@ out_kill_hwsq: | |||
471 | 498 | ||
472 | out_freeres: | 499 | out_freeres: |
473 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); | 500 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); |
474 | ehea_h_free_resource(adapter->handle, qp->fw_handle); | 501 | ehea_h_free_resource(adapter->handle, qp->fw_handle, FORCE_FREE); |
475 | 502 | ||
476 | out_freemem: | 503 | out_freemem: |
477 | kfree(qp); | 504 | kfree(qp); |
478 | return NULL; | 505 | return NULL; |
479 | } | 506 | } |
480 | 507 | ||
481 | int ehea_destroy_qp(struct ehea_qp *qp) | 508 | u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) |
482 | { | 509 | { |
483 | u64 hret; | 510 | u64 hret; |
484 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; | 511 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; |
485 | 512 | ||
486 | if (!qp) | ||
487 | return 0; | ||
488 | 513 | ||
489 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); | 514 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); |
490 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle); | 515 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); |
491 | if (hret != H_SUCCESS) { | 516 | if (hret != H_SUCCESS) |
492 | ehea_error("destroy_qp failed"); | 517 | return hret; |
493 | return -EIO; | ||
494 | } | ||
495 | 518 | ||
496 | hw_queue_dtor(&qp->hw_squeue); | 519 | hw_queue_dtor(&qp->hw_squeue); |
497 | hw_queue_dtor(&qp->hw_rqueue1); | 520 | hw_queue_dtor(&qp->hw_rqueue1); |
498 | 521 | ||
499 | if (qp_attr->rq_count > 1) | 522 | if (qp_attr->rq_count > 1) |
500 | hw_queue_dtor(&qp->hw_rqueue2); | 523 | hw_queue_dtor(&qp->hw_rqueue2); |
501 | if (qp_attr->rq_count > 2) | 524 | if (qp_attr->rq_count > 2) |
502 | hw_queue_dtor(&qp->hw_rqueue3); | 525 | hw_queue_dtor(&qp->hw_rqueue3); |
503 | kfree(qp); | 526 | kfree(qp); |
504 | 527 | ||
505 | return 0; | 528 | return hret; |
506 | } | 529 | } |
507 | 530 | ||
508 | int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | 531 | int ehea_destroy_qp(struct ehea_qp *qp) |
532 | { | ||
533 | u64 hret; | ||
534 | if (!qp) | ||
535 | return 0; | ||
536 | |||
537 | if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { | ||
538 | ehea_error_data(qp->adapter, qp->fw_handle); | ||
539 | hret = ehea_destroy_qp_res(qp, FORCE_FREE); | ||
540 | } | ||
541 | |||
542 | if (hret != H_SUCCESS) { | ||
543 | ehea_error("destroy QP failed"); | ||
544 | return -EIO; | ||
545 | } | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) | ||
509 | { | 551 | { |
510 | int i, k, ret; | 552 | int i, k, ret; |
511 | u64 hret, pt_abs, start, end, nr_pages; | 553 | u64 hret, pt_abs, start, end, nr_pages; |
@@ -526,14 +568,14 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
526 | 568 | ||
527 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, | 569 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, |
528 | acc_ctrl, adapter->pd, | 570 | acc_ctrl, adapter->pd, |
529 | &adapter->mr.handle, &adapter->mr.lkey); | 571 | &mr->handle, &mr->lkey); |
530 | if (hret != H_SUCCESS) { | 572 | if (hret != H_SUCCESS) { |
531 | ehea_error("alloc_resource_mr failed"); | 573 | ehea_error("alloc_resource_mr failed"); |
532 | ret = -EIO; | 574 | ret = -EIO; |
533 | goto out; | 575 | goto out; |
534 | } | 576 | } |
535 | 577 | ||
536 | adapter->mr.vaddr = KERNELBASE; | 578 | mr->vaddr = KERNELBASE; |
537 | k = 0; | 579 | k = 0; |
538 | 580 | ||
539 | while (nr_pages > 0) { | 581 | while (nr_pages > 0) { |
@@ -545,7 +587,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
545 | EHEA_PAGESIZE))); | 587 | EHEA_PAGESIZE))); |
546 | 588 | ||
547 | hret = ehea_h_register_rpage_mr(adapter->handle, | 589 | hret = ehea_h_register_rpage_mr(adapter->handle, |
548 | adapter->mr.handle, 0, | 590 | mr->handle, 0, |
549 | 0, (u64)pt_abs, | 591 | 0, (u64)pt_abs, |
550 | num_pages); | 592 | num_pages); |
551 | nr_pages -= num_pages; | 593 | nr_pages -= num_pages; |
@@ -554,34 +596,68 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
554 | (k * EHEA_PAGESIZE))); | 596 | (k * EHEA_PAGESIZE))); |
555 | 597 | ||
556 | hret = ehea_h_register_rpage_mr(adapter->handle, | 598 | hret = ehea_h_register_rpage_mr(adapter->handle, |
557 | adapter->mr.handle, 0, | 599 | mr->handle, 0, |
558 | 0, abs_adr,1); | 600 | 0, abs_adr,1); |
559 | nr_pages--; | 601 | nr_pages--; |
560 | } | 602 | } |
561 | 603 | ||
562 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { | 604 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { |
563 | ehea_h_free_resource(adapter->handle, | 605 | ehea_h_free_resource(adapter->handle, |
564 | adapter->mr.handle); | 606 | mr->handle, FORCE_FREE); |
565 | ehea_error("register_rpage_mr failed: hret = %lX", | 607 | ehea_error("register_rpage_mr failed"); |
566 | hret); | ||
567 | ret = -EIO; | 608 | ret = -EIO; |
568 | goto out; | 609 | goto out; |
569 | } | 610 | } |
570 | } | 611 | } |
571 | 612 | ||
572 | if (hret != H_SUCCESS) { | 613 | if (hret != H_SUCCESS) { |
573 | ehea_h_free_resource(adapter->handle, adapter->mr.handle); | 614 | ehea_h_free_resource(adapter->handle, mr->handle, |
574 | ehea_error("register_rpage failed for last page: hret = %lX", | 615 | FORCE_FREE); |
575 | hret); | 616 | ehea_error("register_rpage failed for last page"); |
576 | ret = -EIO; | 617 | ret = -EIO; |
577 | goto out; | 618 | goto out; |
578 | } | 619 | } |
620 | |||
621 | mr->adapter = adapter; | ||
579 | ret = 0; | 622 | ret = 0; |
580 | out: | 623 | out: |
581 | kfree(pt); | 624 | kfree(pt); |
582 | return ret; | 625 | return ret; |
583 | } | 626 | } |
584 | 627 | ||
628 | int ehea_rem_mr(struct ehea_mr *mr) | ||
629 | { | ||
630 | u64 hret; | ||
631 | |||
632 | if (!mr || !mr->adapter) | ||
633 | return -EINVAL; | ||
634 | |||
635 | hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, | ||
636 | FORCE_FREE); | ||
637 | if (hret != H_SUCCESS) { | ||
638 | ehea_error("destroy MR failed"); | ||
639 | return -EIO; | ||
640 | } | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr, | ||
646 | struct ehea_mr *shared_mr) | ||
647 | { | ||
648 | u64 hret; | ||
649 | |||
650 | hret = ehea_h_register_smr(adapter->handle, old_mr->handle, | ||
651 | old_mr->vaddr, EHEA_MR_ACC_CTRL, | ||
652 | adapter->pd, shared_mr); | ||
653 | if (hret != H_SUCCESS) | ||
654 | return -EIO; | ||
655 | |||
656 | shared_mr->adapter = adapter; | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
585 | void print_error_data(u64 *data) | 661 | void print_error_data(u64 *data) |
586 | { | 662 | { |
587 | int length; | 663 | int length; |
@@ -597,6 +673,14 @@ void print_error_data(u64 *data) | |||
597 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " | 673 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " |
598 | "port=%lX", resource, data[6], data[12], data[22]); | 674 | "port=%lX", resource, data[6], data[12], data[22]); |
599 | 675 | ||
676 | if (type == 0x4) /* Completion Queue */ | ||
677 | ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, | ||
678 | data[6]); | ||
679 | |||
680 | if (type == 0x3) /* Event Queue */ | ||
681 | ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, | ||
682 | data[6]); | ||
683 | |||
600 | ehea_dump(data, length, "error data"); | 684 | ehea_dump(data, length, "error data"); |
601 | } | 685 | } |
602 | 686 | ||