| .. | .. |
|---|
| 16 | 16 | #include <linux/pci.h> |
|---|
| 17 | 17 | #include <linux/slab.h> |
|---|
| 18 | 18 | #include <linux/spinlock.h> |
|---|
| 19 | | -#include <linux/blkdev.h> |
|---|
| 19 | +#include <linux/blk-mq.h> |
|---|
| 20 | 20 | #include <linux/sched.h> |
|---|
| 21 | 21 | #include <linux/interrupt.h> |
|---|
| 22 | 22 | #include <linux/compiler.h> |
|---|
| .. | .. |
|---|
| 197 | 197 | FL_NON_RAID = FW_VER_NON_RAID, |
|---|
| 198 | 198 | FL_4PORT = FW_VER_4PORT, |
|---|
| 199 | 199 | FL_FW_VER_MASK = (FW_VER_NON_RAID | FW_VER_4PORT), |
|---|
| 200 | | - FL_DAC = (1 << 16), |
|---|
| 201 | 200 | FL_DYN_MAJOR = (1 << 17), |
|---|
| 202 | 201 | }; |
|---|
| 203 | 202 | |
|---|
| .. | .. |
|---|
| 254 | 253 | }; |
|---|
| 255 | 254 | |
|---|
| 256 | 255 | struct carm_request { |
|---|
| 257 | | - unsigned int tag; |
|---|
| 258 | 256 | int n_elem; |
|---|
| 259 | 257 | unsigned int msg_type; |
|---|
| 260 | 258 | unsigned int msg_subtype; |
|---|
| 261 | 259 | unsigned int msg_bucket; |
|---|
| 262 | | - struct request *rq; |
|---|
| 263 | | - struct carm_port *port; |
|---|
| 264 | 260 | struct scatterlist sg[CARM_MAX_REQ_SG]; |
|---|
| 265 | 261 | }; |
|---|
| 266 | 262 | |
|---|
| .. | .. |
|---|
| 279 | 275 | unsigned int state; |
|---|
| 280 | 276 | u32 fw_ver; |
|---|
| 281 | 277 | |
|---|
| 278 | + struct blk_mq_tag_set tag_set; |
|---|
| 282 | 279 | struct request_queue *oob_q; |
|---|
| 283 | 280 | unsigned int n_oob; |
|---|
| 284 | 281 | |
|---|
| .. | .. |
|---|
| 290 | 287 | unsigned int wait_q_cons; |
|---|
| 291 | 288 | struct request_queue *wait_q[CARM_MAX_WAIT_Q]; |
|---|
| 292 | 289 | |
|---|
| 293 | | - unsigned int n_msgs; |
|---|
| 294 | | - u64 msg_alloc; |
|---|
| 295 | | - struct carm_request req[CARM_MAX_REQ]; |
|---|
| 296 | 290 | void *msg_base; |
|---|
| 297 | 291 | dma_addr_t msg_dma; |
|---|
| 298 | 292 | |
|---|
| .. | .. |
|---|
| 477 | 471 | } |
|---|
| 478 | 472 | |
|---|
| 479 | 473 | static int carm_send_msg(struct carm_host *host, |
|---|
| 480 | | - struct carm_request *crq) |
|---|
| 474 | + struct carm_request *crq, unsigned tag) |
|---|
| 481 | 475 | { |
|---|
| 482 | 476 | void __iomem *mmio = host->mmio; |
|---|
| 483 | | - u32 msg = (u32) carm_ref_msg_dma(host, crq->tag); |
|---|
| 477 | + u32 msg = (u32) carm_ref_msg_dma(host, tag); |
|---|
| 484 | 478 | u32 cm_bucket = crq->msg_bucket; |
|---|
| 485 | 479 | u32 tmp; |
|---|
| 486 | 480 | int rc = 0; |
|---|
| .. | .. |
|---|
| 505 | 499 | return rc; |
|---|
| 506 | 500 | } |
|---|
| 507 | 501 | |
|---|
| 508 | | -static struct carm_request *carm_get_request(struct carm_host *host) |
|---|
| 509 | | -{ |
|---|
| 510 | | - unsigned int i; |
|---|
| 511 | | - |
|---|
| 512 | | - /* obey global hardware limit on S/G entries */ |
|---|
| 513 | | - if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) |
|---|
| 514 | | - return NULL; |
|---|
| 515 | | - |
|---|
| 516 | | - for (i = 0; i < max_queue; i++) |
|---|
| 517 | | - if ((host->msg_alloc & (1ULL << i)) == 0) { |
|---|
| 518 | | - struct carm_request *crq = &host->req[i]; |
|---|
| 519 | | - crq->port = NULL; |
|---|
| 520 | | - crq->n_elem = 0; |
|---|
| 521 | | - |
|---|
| 522 | | - host->msg_alloc |= (1ULL << i); |
|---|
| 523 | | - host->n_msgs++; |
|---|
| 524 | | - |
|---|
| 525 | | - assert(host->n_msgs <= CARM_MAX_REQ); |
|---|
| 526 | | - sg_init_table(crq->sg, CARM_MAX_REQ_SG); |
|---|
| 527 | | - return crq; |
|---|
| 528 | | - } |
|---|
| 529 | | - |
|---|
| 530 | | - DPRINTK("no request available, returning NULL\n"); |
|---|
| 531 | | - return NULL; |
|---|
| 532 | | -} |
|---|
| 533 | | - |
|---|
| 534 | | -static int carm_put_request(struct carm_host *host, struct carm_request *crq) |
|---|
| 535 | | -{ |
|---|
| 536 | | - assert(crq->tag < max_queue); |
|---|
| 537 | | - |
|---|
| 538 | | - if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) |
|---|
| 539 | | - return -EINVAL; /* tried to clear a tag that was not active */ |
|---|
| 540 | | - |
|---|
| 541 | | - assert(host->hw_sg_used >= crq->n_elem); |
|---|
| 542 | | - |
|---|
| 543 | | - host->msg_alloc &= ~(1ULL << crq->tag); |
|---|
| 544 | | - host->hw_sg_used -= crq->n_elem; |
|---|
| 545 | | - host->n_msgs--; |
|---|
| 546 | | - |
|---|
| 547 | | - return 0; |
|---|
| 548 | | -} |
|---|
| 549 | | - |
|---|
| 550 | | -static struct carm_request *carm_get_special(struct carm_host *host) |
|---|
| 551 | | -{ |
|---|
| 552 | | - unsigned long flags; |
|---|
| 553 | | - struct carm_request *crq = NULL; |
|---|
| 554 | | - struct request *rq; |
|---|
| 555 | | - int tries = 5000; |
|---|
| 556 | | - |
|---|
| 557 | | - while (tries-- > 0) { |
|---|
| 558 | | - spin_lock_irqsave(&host->lock, flags); |
|---|
| 559 | | - crq = carm_get_request(host); |
|---|
| 560 | | - spin_unlock_irqrestore(&host->lock, flags); |
|---|
| 561 | | - |
|---|
| 562 | | - if (crq) |
|---|
| 563 | | - break; |
|---|
| 564 | | - msleep(10); |
|---|
| 565 | | - } |
|---|
| 566 | | - |
|---|
| 567 | | - if (!crq) |
|---|
| 568 | | - return NULL; |
|---|
| 569 | | - |
|---|
| 570 | | - rq = blk_get_request(host->oob_q, REQ_OP_DRV_OUT, 0); |
|---|
| 571 | | - if (IS_ERR(rq)) { |
|---|
| 572 | | - spin_lock_irqsave(&host->lock, flags); |
|---|
| 573 | | - carm_put_request(host, crq); |
|---|
| 574 | | - spin_unlock_irqrestore(&host->lock, flags); |
|---|
| 575 | | - return NULL; |
|---|
| 576 | | - } |
|---|
| 577 | | - |
|---|
| 578 | | - crq->rq = rq; |
|---|
| 579 | | - return crq; |
|---|
| 580 | | -} |
|---|
| 581 | | - |
|---|
| 582 | 502 | static int carm_array_info (struct carm_host *host, unsigned int array_idx) |
|---|
| 583 | 503 | { |
|---|
| 584 | 504 | struct carm_msg_ioctl *ioc; |
|---|
| 585 | | - unsigned int idx; |
|---|
| 586 | 505 | u32 msg_data; |
|---|
| 587 | 506 | dma_addr_t msg_dma; |
|---|
| 588 | 507 | struct carm_request *crq; |
|---|
| 508 | + struct request *rq; |
|---|
| 589 | 509 | int rc; |
|---|
| 590 | 510 | |
|---|
| 591 | | - crq = carm_get_special(host); |
|---|
| 592 | | - if (!crq) { |
|---|
| 511 | + rq = blk_mq_alloc_request(host->oob_q, REQ_OP_DRV_OUT, 0); |
|---|
| 512 | + if (IS_ERR(rq)) { |
|---|
| 593 | 513 | rc = -ENOMEM; |
|---|
| 594 | 514 | goto err_out; |
|---|
| 595 | 515 | } |
|---|
| 516 | + crq = blk_mq_rq_to_pdu(rq); |
|---|
| 596 | 517 | |
|---|
| 597 | | - idx = crq->tag; |
|---|
| 598 | | - |
|---|
| 599 | | - ioc = carm_ref_msg(host, idx); |
|---|
| 600 | | - msg_dma = carm_ref_msg_dma(host, idx); |
|---|
| 518 | + ioc = carm_ref_msg(host, rq->tag); |
|---|
| 519 | + msg_dma = carm_ref_msg_dma(host, rq->tag); |
|---|
| 601 | 520 | msg_data = (u32) (msg_dma + sizeof(struct carm_array_info)); |
|---|
| 602 | 521 | |
|---|
| 603 | 522 | crq->msg_type = CARM_MSG_ARRAY; |
|---|
| .. | .. |
|---|
| 611 | 530 | ioc->type = CARM_MSG_ARRAY; |
|---|
| 612 | 531 | ioc->subtype = CARM_ARRAY_INFO; |
|---|
| 613 | 532 | ioc->array_id = (u8) array_idx; |
|---|
| 614 | | - ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); |
|---|
| 533 | + ioc->handle = cpu_to_le32(TAG_ENCODE(rq->tag)); |
|---|
| 615 | 534 | ioc->data_addr = cpu_to_le32(msg_data); |
|---|
| 616 | 535 | |
|---|
| 617 | 536 | spin_lock_irq(&host->lock); |
|---|
| .. | .. |
|---|
| 619 | 538 | host->state == HST_DEV_SCAN); |
|---|
| 620 | 539 | spin_unlock_irq(&host->lock); |
|---|
| 621 | 540 | |
|---|
| 622 | | - DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx); |
|---|
| 623 | | - crq->rq->special = crq; |
|---|
| 624 | | - blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL); |
|---|
| 541 | + DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag); |
|---|
| 542 | + blk_execute_rq_nowait(host->oob_q, NULL, rq, true, NULL); |
|---|
| 625 | 543 | |
|---|
| 626 | 544 | return 0; |
|---|
| 627 | 545 | |
|---|
| .. | .. |
|---|
| 636 | 554 | |
|---|
| 637 | 555 | static int carm_send_special (struct carm_host *host, carm_sspc_t func) |
|---|
| 638 | 556 | { |
|---|
| 557 | + struct request *rq; |
|---|
| 639 | 558 | struct carm_request *crq; |
|---|
| 640 | 559 | struct carm_msg_ioctl *ioc; |
|---|
| 641 | 560 | void *mem; |
|---|
| 642 | | - unsigned int idx, msg_size; |
|---|
| 561 | + unsigned int msg_size; |
|---|
| 643 | 562 | int rc; |
|---|
| 644 | 563 | |
|---|
| 645 | | - crq = carm_get_special(host); |
|---|
| 646 | | - if (!crq) |
|---|
| 564 | + rq = blk_mq_alloc_request(host->oob_q, REQ_OP_DRV_OUT, 0); |
|---|
| 565 | + if (IS_ERR(rq)) |
|---|
| 647 | 566 | return -ENOMEM; |
|---|
| 567 | + crq = blk_mq_rq_to_pdu(rq); |
|---|
| 648 | 568 | |
|---|
| 649 | | - idx = crq->tag; |
|---|
| 569 | + mem = carm_ref_msg(host, rq->tag); |
|---|
| 650 | 570 | |
|---|
| 651 | | - mem = carm_ref_msg(host, idx); |
|---|
| 652 | | - |
|---|
| 653 | | - msg_size = func(host, idx, mem); |
|---|
| 571 | + msg_size = func(host, rq->tag, mem); |
|---|
| 654 | 572 | |
|---|
| 655 | 573 | ioc = mem; |
|---|
| 656 | 574 | crq->msg_type = ioc->type; |
|---|
| .. | .. |
|---|
| 659 | 577 | BUG_ON(rc < 0); |
|---|
| 660 | 578 | crq->msg_bucket = (u32) rc; |
|---|
| 661 | 579 | |
|---|
| 662 | | - DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx); |
|---|
| 663 | | - crq->rq->special = crq; |
|---|
| 664 | | - blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL); |
|---|
| 580 | + DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag); |
|---|
| 581 | + blk_execute_rq_nowait(host->oob_q, NULL, rq, true, NULL); |
|---|
| 665 | 582 | |
|---|
| 666 | 583 | return 0; |
|---|
| 667 | 584 | } |
|---|
| .. | .. |
|---|
| 743 | 660 | sizeof(struct carm_fw_ver); |
|---|
| 744 | 661 | } |
|---|
| 745 | 662 | |
|---|
| 746 | | -static inline void carm_end_request_queued(struct carm_host *host, |
|---|
| 747 | | - struct carm_request *crq, |
|---|
| 748 | | - blk_status_t error) |
|---|
| 749 | | -{ |
|---|
| 750 | | - struct request *req = crq->rq; |
|---|
| 751 | | - int rc; |
|---|
| 752 | | - |
|---|
| 753 | | - __blk_end_request_all(req, error); |
|---|
| 754 | | - |
|---|
| 755 | | - rc = carm_put_request(host, crq); |
|---|
| 756 | | - assert(rc == 0); |
|---|
| 757 | | -} |
|---|
| 758 | | - |
|---|
| 759 | 663 | static inline void carm_push_q (struct carm_host *host, struct request_queue *q) |
|---|
| 760 | 664 | { |
|---|
| 761 | 665 | unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; |
|---|
| 762 | 666 | |
|---|
| 763 | | - blk_stop_queue(q); |
|---|
| 667 | + blk_mq_stop_hw_queues(q); |
|---|
| 764 | 668 | VPRINTK("STOPPED QUEUE %p\n", q); |
|---|
| 765 | 669 | |
|---|
| 766 | 670 | host->wait_q[idx] = q; |
|---|
| .. | .. |
|---|
| 785 | 689 | { |
|---|
| 786 | 690 | struct request_queue *q = carm_pop_q(host); |
|---|
| 787 | 691 | if (q) { |
|---|
| 788 | | - blk_start_queue(q); |
|---|
| 692 | + blk_mq_start_hw_queues(q); |
|---|
| 789 | 693 | VPRINTK("STARTED QUEUE %p\n", q); |
|---|
| 790 | 694 | } |
|---|
| 791 | 695 | } |
|---|
| 792 | 696 | |
|---|
| 793 | | -static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, |
|---|
| 794 | | - blk_status_t error) |
|---|
| 697 | +static inline enum dma_data_direction carm_rq_dir(struct request *rq) |
|---|
| 795 | 698 | { |
|---|
| 796 | | - carm_end_request_queued(host, crq, error); |
|---|
| 797 | | - if (max_queue == 1) |
|---|
| 798 | | - carm_round_robin(host); |
|---|
| 799 | | - else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && |
|---|
| 800 | | - (host->hw_sg_used <= CARM_SG_LOW_WATER)) { |
|---|
| 801 | | - carm_round_robin(host); |
|---|
| 802 | | - } |
|---|
| 699 | + return op_is_write(req_op(rq)) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; |
|---|
| 803 | 700 | } |
|---|
| 804 | 701 | |
|---|
| 805 | | -static void carm_oob_rq_fn(struct request_queue *q) |
|---|
| 702 | +static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx, |
|---|
| 703 | + const struct blk_mq_queue_data *bd) |
|---|
| 806 | 704 | { |
|---|
| 807 | | - struct carm_host *host = q->queuedata; |
|---|
| 808 | | - struct carm_request *crq; |
|---|
| 809 | | - struct request *rq; |
|---|
| 810 | | - int rc; |
|---|
| 811 | | - |
|---|
| 812 | | - while (1) { |
|---|
| 813 | | - DPRINTK("get req\n"); |
|---|
| 814 | | - rq = blk_fetch_request(q); |
|---|
| 815 | | - if (!rq) |
|---|
| 816 | | - break; |
|---|
| 817 | | - |
|---|
| 818 | | - crq = rq->special; |
|---|
| 819 | | - assert(crq != NULL); |
|---|
| 820 | | - assert(crq->rq == rq); |
|---|
| 821 | | - |
|---|
| 822 | | - crq->n_elem = 0; |
|---|
| 823 | | - |
|---|
| 824 | | - DPRINTK("send req\n"); |
|---|
| 825 | | - rc = carm_send_msg(host, crq); |
|---|
| 826 | | - if (rc) { |
|---|
| 827 | | - blk_requeue_request(q, rq); |
|---|
| 828 | | - carm_push_q(host, q); |
|---|
| 829 | | - return; /* call us again later, eventually */ |
|---|
| 830 | | - } |
|---|
| 831 | | - } |
|---|
| 832 | | -} |
|---|
| 833 | | - |
|---|
| 834 | | -static void carm_rq_fn(struct request_queue *q) |
|---|
| 835 | | -{ |
|---|
| 705 | + struct request_queue *q = hctx->queue; |
|---|
| 706 | + struct request *rq = bd->rq; |
|---|
| 836 | 707 | struct carm_port *port = q->queuedata; |
|---|
| 837 | 708 | struct carm_host *host = port->host; |
|---|
| 709 | + struct carm_request *crq = blk_mq_rq_to_pdu(rq); |
|---|
| 838 | 710 | struct carm_msg_rw *msg; |
|---|
| 839 | | - struct carm_request *crq; |
|---|
| 840 | | - struct request *rq; |
|---|
| 841 | 711 | struct scatterlist *sg; |
|---|
| 842 | | - int writing = 0, pci_dir, i, n_elem, rc; |
|---|
| 843 | | - u32 tmp; |
|---|
| 712 | + int i, n_elem = 0, rc; |
|---|
| 844 | 713 | unsigned int msg_size; |
|---|
| 714 | + u32 tmp; |
|---|
| 845 | 715 | |
|---|
| 846 | | -queue_one_request: |
|---|
| 847 | | - VPRINTK("get req\n"); |
|---|
| 848 | | - rq = blk_peek_request(q); |
|---|
| 849 | | - if (!rq) |
|---|
| 850 | | - return; |
|---|
| 716 | + crq->n_elem = 0; |
|---|
| 717 | + sg_init_table(crq->sg, CARM_MAX_REQ_SG); |
|---|
| 851 | 718 | |
|---|
| 852 | | - crq = carm_get_request(host); |
|---|
| 853 | | - if (!crq) { |
|---|
| 854 | | - carm_push_q(host, q); |
|---|
| 855 | | - return; /* call us again later, eventually */ |
|---|
| 856 | | - } |
|---|
| 857 | | - crq->rq = rq; |
|---|
| 719 | + blk_mq_start_request(rq); |
|---|
| 858 | 720 | |
|---|
| 859 | | - blk_start_request(rq); |
|---|
| 860 | | - |
|---|
| 861 | | - if (rq_data_dir(rq) == WRITE) { |
|---|
| 862 | | - writing = 1; |
|---|
| 863 | | - pci_dir = PCI_DMA_TODEVICE; |
|---|
| 864 | | - } else { |
|---|
| 865 | | - pci_dir = PCI_DMA_FROMDEVICE; |
|---|
| 866 | | - } |
|---|
| 721 | + spin_lock_irq(&host->lock); |
|---|
| 722 | + if (req_op(rq) == REQ_OP_DRV_OUT) |
|---|
| 723 | + goto send_msg; |
|---|
| 867 | 724 | |
|---|
| 868 | 725 | /* get scatterlist from block layer */ |
|---|
| 869 | 726 | sg = &crq->sg[0]; |
|---|
| 870 | 727 | n_elem = blk_rq_map_sg(q, rq, sg); |
|---|
| 871 | | - if (n_elem <= 0) { |
|---|
| 872 | | - carm_end_rq(host, crq, BLK_STS_IOERR); |
|---|
| 873 | | - return; /* request with no s/g entries? */ |
|---|
| 874 | | - } |
|---|
| 728 | + if (n_elem <= 0) |
|---|
| 729 | + goto out_ioerr; |
|---|
| 875 | 730 | |
|---|
| 876 | 731 | /* map scatterlist to PCI bus addresses */ |
|---|
| 877 | | - n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); |
|---|
| 878 | | - if (n_elem <= 0) { |
|---|
| 879 | | - carm_end_rq(host, crq, BLK_STS_IOERR); |
|---|
| 880 | | - return; /* request with no s/g entries? */ |
|---|
| 881 | | - } |
|---|
| 732 | + n_elem = dma_map_sg(&host->pdev->dev, sg, n_elem, carm_rq_dir(rq)); |
|---|
| 733 | + if (n_elem <= 0) |
|---|
| 734 | + goto out_ioerr; |
|---|
| 735 | + |
|---|
| 736 | + /* obey global hardware limit on S/G entries */ |
|---|
| 737 | + if (host->hw_sg_used >= CARM_MAX_HOST_SG - n_elem) |
|---|
| 738 | + goto out_resource; |
|---|
| 739 | + |
|---|
| 882 | 740 | crq->n_elem = n_elem; |
|---|
| 883 | | - crq->port = port; |
|---|
| 884 | 741 | host->hw_sg_used += n_elem; |
|---|
| 885 | 742 | |
|---|
| 886 | 743 | /* |
|---|
| .. | .. |
|---|
| 888 | 745 | */ |
|---|
| 889 | 746 | |
|---|
| 890 | 747 | VPRINTK("build msg\n"); |
|---|
| 891 | | - msg = (struct carm_msg_rw *) carm_ref_msg(host, crq->tag); |
|---|
| 748 | + msg = (struct carm_msg_rw *) carm_ref_msg(host, rq->tag); |
|---|
| 892 | 749 | |
|---|
| 893 | | - if (writing) { |
|---|
| 750 | + if (rq_data_dir(rq) == WRITE) { |
|---|
| 894 | 751 | msg->type = CARM_MSG_WRITE; |
|---|
| 895 | 752 | crq->msg_type = CARM_MSG_WRITE; |
|---|
| 896 | 753 | } else { |
|---|
| .. | .. |
|---|
| 901 | 758 | msg->id = port->port_no; |
|---|
| 902 | 759 | msg->sg_count = n_elem; |
|---|
| 903 | 760 | msg->sg_type = SGT_32BIT; |
|---|
| 904 | | - msg->handle = cpu_to_le32(TAG_ENCODE(crq->tag)); |
|---|
| 761 | + msg->handle = cpu_to_le32(TAG_ENCODE(rq->tag)); |
|---|
| 905 | 762 | msg->lba = cpu_to_le32(blk_rq_pos(rq) & 0xffffffff); |
|---|
| 906 | 763 | tmp = (blk_rq_pos(rq) >> 16) >> 16; |
|---|
| 907 | 764 | msg->lba_high = cpu_to_le16( (u16) tmp ); |
|---|
| .. | .. |
|---|
| 918 | 775 | rc = carm_lookup_bucket(msg_size); |
|---|
| 919 | 776 | BUG_ON(rc < 0); |
|---|
| 920 | 777 | crq->msg_bucket = (u32) rc; |
|---|
| 921 | | - |
|---|
| 778 | +send_msg: |
|---|
| 922 | 779 | /* |
|---|
| 923 | 780 | * queue read/write message to hardware |
|---|
| 924 | 781 | */ |
|---|
| 925 | | - |
|---|
| 926 | | - VPRINTK("send msg, tag == %u\n", crq->tag); |
|---|
| 927 | | - rc = carm_send_msg(host, crq); |
|---|
| 782 | + VPRINTK("send msg, tag == %u\n", rq->tag); |
|---|
| 783 | + rc = carm_send_msg(host, crq, rq->tag); |
|---|
| 928 | 784 | if (rc) { |
|---|
| 929 | | - carm_put_request(host, crq); |
|---|
| 930 | | - blk_requeue_request(q, rq); |
|---|
| 931 | | - carm_push_q(host, q); |
|---|
| 932 | | - return; /* call us again later, eventually */ |
|---|
| 785 | + host->hw_sg_used -= n_elem; |
|---|
| 786 | + goto out_resource; |
|---|
| 933 | 787 | } |
|---|
| 934 | 788 | |
|---|
| 935 | | - goto queue_one_request; |
|---|
| 789 | + spin_unlock_irq(&host->lock); |
|---|
| 790 | + return BLK_STS_OK; |
|---|
| 791 | +out_resource: |
|---|
| 792 | + dma_unmap_sg(&host->pdev->dev, &crq->sg[0], n_elem, carm_rq_dir(rq)); |
|---|
| 793 | + carm_push_q(host, q); |
|---|
| 794 | + spin_unlock_irq(&host->lock); |
|---|
| 795 | + return BLK_STS_DEV_RESOURCE; |
|---|
| 796 | +out_ioerr: |
|---|
| 797 | + carm_round_robin(host); |
|---|
| 798 | + spin_unlock_irq(&host->lock); |
|---|
| 799 | + return BLK_STS_IOERR; |
|---|
| 936 | 800 | } |
|---|
| 937 | 801 | |
|---|
| 938 | 802 | static void carm_handle_array_info(struct carm_host *host, |
|---|
| .. | .. |
|---|
| 947 | 811 | size_t slen; |
|---|
| 948 | 812 | |
|---|
| 949 | 813 | DPRINTK("ENTER\n"); |
|---|
| 950 | | - |
|---|
| 951 | | - carm_end_rq(host, crq, error); |
|---|
| 952 | 814 | |
|---|
| 953 | 815 | if (error) |
|---|
| 954 | 816 | goto out; |
|---|
| .. | .. |
|---|
| 1005 | 867 | |
|---|
| 1006 | 868 | DPRINTK("ENTER\n"); |
|---|
| 1007 | 869 | |
|---|
| 1008 | | - carm_end_rq(host, crq, error); |
|---|
| 1009 | | - |
|---|
| 1010 | 870 | if (error) { |
|---|
| 1011 | 871 | new_state = HST_ERROR; |
|---|
| 1012 | 872 | goto out; |
|---|
| .. | .. |
|---|
| 1034 | 894 | { |
|---|
| 1035 | 895 | DPRINTK("ENTER\n"); |
|---|
| 1036 | 896 | |
|---|
| 1037 | | - carm_end_rq(host, crq, error); |
|---|
| 1038 | | - |
|---|
| 1039 | 897 | assert(host->state == cur_state); |
|---|
| 1040 | 898 | if (error) |
|---|
| 1041 | 899 | host->state = HST_ERROR; |
|---|
| .. | .. |
|---|
| 1044 | 902 | schedule_work(&host->fsm_task); |
|---|
| 1045 | 903 | } |
|---|
| 1046 | 904 | |
|---|
| 1047 | | -static inline void carm_handle_rw(struct carm_host *host, |
|---|
| 1048 | | - struct carm_request *crq, blk_status_t error) |
|---|
| 1049 | | -{ |
|---|
| 1050 | | - int pci_dir; |
|---|
| 1051 | | - |
|---|
| 1052 | | - VPRINTK("ENTER\n"); |
|---|
| 1053 | | - |
|---|
| 1054 | | - if (rq_data_dir(crq->rq) == WRITE) |
|---|
| 1055 | | - pci_dir = PCI_DMA_TODEVICE; |
|---|
| 1056 | | - else |
|---|
| 1057 | | - pci_dir = PCI_DMA_FROMDEVICE; |
|---|
| 1058 | | - |
|---|
| 1059 | | - pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); |
|---|
| 1060 | | - |
|---|
| 1061 | | - carm_end_rq(host, crq, error); |
|---|
| 1062 | | -} |
|---|
| 1063 | | - |
|---|
| 1064 | 905 | static inline void carm_handle_resp(struct carm_host *host, |
|---|
| 1065 | 906 | __le32 ret_handle_le, u32 status) |
|---|
| 1066 | 907 | { |
|---|
| 1067 | 908 | u32 handle = le32_to_cpu(ret_handle_le); |
|---|
| 1068 | 909 | unsigned int msg_idx; |
|---|
| 910 | + struct request *rq; |
|---|
| 1069 | 911 | struct carm_request *crq; |
|---|
| 1070 | 912 | blk_status_t error = (status == RMSG_OK) ? 0 : BLK_STS_IOERR; |
|---|
| 1071 | 913 | u8 *mem; |
|---|
| .. | .. |
|---|
| 1081 | 923 | msg_idx = TAG_DECODE(handle); |
|---|
| 1082 | 924 | VPRINTK("tag == %u\n", msg_idx); |
|---|
| 1083 | 925 | |
|---|
| 1084 | | - crq = &host->req[msg_idx]; |
|---|
| 926 | + rq = blk_mq_tag_to_rq(host->tag_set.tags[0], msg_idx); |
|---|
| 927 | + crq = blk_mq_rq_to_pdu(rq); |
|---|
| 1085 | 928 | |
|---|
| 1086 | 929 | /* fast path */ |
|---|
| 1087 | 930 | if (likely(crq->msg_type == CARM_MSG_READ || |
|---|
| 1088 | 931 | crq->msg_type == CARM_MSG_WRITE)) { |
|---|
| 1089 | | - carm_handle_rw(host, crq, error); |
|---|
| 1090 | | - return; |
|---|
| 932 | + dma_unmap_sg(&host->pdev->dev, &crq->sg[0], crq->n_elem, |
|---|
| 933 | + carm_rq_dir(rq)); |
|---|
| 934 | + goto done; |
|---|
| 1091 | 935 | } |
|---|
| 1092 | 936 | |
|---|
| 1093 | 937 | mem = carm_ref_msg(host, msg_idx); |
|---|
| .. | .. |
|---|
| 1097 | 941 | switch (crq->msg_subtype) { |
|---|
| 1098 | 942 | case CARM_IOC_SCAN_CHAN: |
|---|
| 1099 | 943 | carm_handle_scan_chan(host, crq, mem, error); |
|---|
| 1100 | | - break; |
|---|
| 944 | + goto done; |
|---|
| 1101 | 945 | default: |
|---|
| 1102 | 946 | /* unknown / invalid response */ |
|---|
| 1103 | 947 | goto err_out; |
|---|
| .. | .. |
|---|
| 1110 | 954 | case MISC_ALLOC_MEM: |
|---|
| 1111 | 955 | carm_handle_generic(host, crq, error, |
|---|
| 1112 | 956 | HST_ALLOC_BUF, HST_SYNC_TIME); |
|---|
| 1113 | | - break; |
|---|
| 957 | + goto done; |
|---|
| 1114 | 958 | case MISC_SET_TIME: |
|---|
| 1115 | 959 | carm_handle_generic(host, crq, error, |
|---|
| 1116 | 960 | HST_SYNC_TIME, HST_GET_FW_VER); |
|---|
| 1117 | | - break; |
|---|
| 961 | + goto done; |
|---|
| 1118 | 962 | case MISC_GET_FW_VER: { |
|---|
| 1119 | 963 | struct carm_fw_ver *ver = (struct carm_fw_ver *) |
|---|
| 1120 | 964 | (mem + sizeof(struct carm_msg_get_fw_ver)); |
|---|
| .. | .. |
|---|
| 1124 | 968 | } |
|---|
| 1125 | 969 | carm_handle_generic(host, crq, error, |
|---|
| 1126 | 970 | HST_GET_FW_VER, HST_PORT_SCAN); |
|---|
| 1127 | | - break; |
|---|
| 971 | + goto done; |
|---|
| 1128 | 972 | } |
|---|
| 1129 | 973 | default: |
|---|
| 1130 | 974 | /* unknown / invalid response */ |
|---|
| .. | .. |
|---|
| 1155 | 999 | err_out: |
|---|
| 1156 | 1000 | printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", |
|---|
| 1157 | 1001 | pci_name(host->pdev), crq->msg_type, crq->msg_subtype); |
|---|
| 1158 | | - carm_end_rq(host, crq, BLK_STS_IOERR); |
|---|
| 1002 | + error = BLK_STS_IOERR; |
|---|
| 1003 | +done: |
|---|
| 1004 | + host->hw_sg_used -= crq->n_elem; |
|---|
| 1005 | + blk_mq_end_request(blk_mq_rq_from_pdu(crq), error); |
|---|
| 1006 | + |
|---|
| 1007 | + if (host->hw_sg_used <= CARM_SG_LOW_WATER) |
|---|
| 1008 | + carm_round_robin(host); |
|---|
| 1159 | 1009 | } |
|---|
| 1160 | 1010 | |
|---|
| 1161 | 1011 | static inline void carm_handle_responses(struct carm_host *host) |
|---|
| .. | .. |
|---|
| 1485 | 1335 | return 0; |
|---|
| 1486 | 1336 | } |
|---|
| 1487 | 1337 | |
|---|
| 1488 | | -static int carm_init_disks(struct carm_host *host) |
|---|
| 1338 | +static const struct blk_mq_ops carm_mq_ops = { |
|---|
| 1339 | + .queue_rq = carm_queue_rq, |
|---|
| 1340 | +}; |
|---|
| 1341 | + |
|---|
| 1342 | +static int carm_init_disk(struct carm_host *host, unsigned int port_no) |
|---|
| 1489 | 1343 | { |
|---|
| 1490 | | - unsigned int i; |
|---|
| 1491 | | - int rc = 0; |
|---|
| 1344 | + struct carm_port *port = &host->port[port_no]; |
|---|
| 1345 | + struct gendisk *disk; |
|---|
| 1346 | + struct request_queue *q; |
|---|
| 1492 | 1347 | |
|---|
| 1493 | | - for (i = 0; i < CARM_MAX_PORTS; i++) { |
|---|
| 1494 | | - struct gendisk *disk; |
|---|
| 1495 | | - struct request_queue *q; |
|---|
| 1496 | | - struct carm_port *port; |
|---|
| 1348 | + port->host = host; |
|---|
| 1349 | + port->port_no = port_no; |
|---|
| 1497 | 1350 | |
|---|
| 1498 | | - port = &host->port[i]; |
|---|
| 1499 | | - port->host = host; |
|---|
| 1500 | | - port->port_no = i; |
|---|
| 1351 | + disk = alloc_disk(CARM_MINORS_PER_MAJOR); |
|---|
| 1352 | + if (!disk) |
|---|
| 1353 | + return -ENOMEM; |
|---|
| 1501 | 1354 | |
|---|
| 1502 | | - disk = alloc_disk(CARM_MINORS_PER_MAJOR); |
|---|
| 1503 | | - if (!disk) { |
|---|
| 1504 | | - rc = -ENOMEM; |
|---|
| 1505 | | - break; |
|---|
| 1506 | | - } |
|---|
| 1355 | + port->disk = disk; |
|---|
| 1356 | + sprintf(disk->disk_name, DRV_NAME "/%u", |
|---|
| 1357 | + (unsigned int)host->id * CARM_MAX_PORTS + port_no); |
|---|
| 1358 | + disk->major = host->major; |
|---|
| 1359 | + disk->first_minor = port_no * CARM_MINORS_PER_MAJOR; |
|---|
| 1360 | + disk->fops = &carm_bd_ops; |
|---|
| 1361 | + disk->private_data = port; |
|---|
| 1507 | 1362 | |
|---|
| 1508 | | - port->disk = disk; |
|---|
| 1509 | | - sprintf(disk->disk_name, DRV_NAME "/%u", |
|---|
| 1510 | | - (unsigned int) (host->id * CARM_MAX_PORTS) + i); |
|---|
| 1511 | | - disk->major = host->major; |
|---|
| 1512 | | - disk->first_minor = i * CARM_MINORS_PER_MAJOR; |
|---|
| 1513 | | - disk->fops = &carm_bd_ops; |
|---|
| 1514 | | - disk->private_data = port; |
|---|
| 1363 | + q = blk_mq_init_queue(&host->tag_set); |
|---|
| 1364 | + if (IS_ERR(q)) |
|---|
| 1365 | + return PTR_ERR(q); |
|---|
| 1515 | 1366 | |
|---|
| 1516 | | - q = blk_init_queue(carm_rq_fn, &host->lock); |
|---|
| 1517 | | - if (!q) { |
|---|
| 1518 | | - rc = -ENOMEM; |
|---|
| 1519 | | - break; |
|---|
| 1520 | | - } |
|---|
| 1521 | | - disk->queue = q; |
|---|
| 1522 | | - blk_queue_max_segments(q, CARM_MAX_REQ_SG); |
|---|
| 1523 | | - blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); |
|---|
| 1367 | + blk_queue_max_segments(q, CARM_MAX_REQ_SG); |
|---|
| 1368 | + blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); |
|---|
| 1524 | 1369 | |
|---|
| 1525 | | - q->queuedata = port; |
|---|
| 1526 | | - } |
|---|
| 1527 | | - |
|---|
| 1528 | | - return rc; |
|---|
| 1370 | + q->queuedata = port; |
|---|
| 1371 | + disk->queue = q; |
|---|
| 1372 | + return 0; |
|---|
| 1529 | 1373 | } |
|---|
| 1530 | 1374 | |
|---|
| 1531 | | -static void carm_free_disks(struct carm_host *host) |
|---|
| 1375 | +static void carm_free_disk(struct carm_host *host, unsigned int port_no) |
|---|
| 1532 | 1376 | { |
|---|
| 1533 | | - unsigned int i; |
|---|
| 1377 | + struct carm_port *port = &host->port[port_no]; |
|---|
| 1378 | + struct gendisk *disk = port->disk; |
|---|
| 1534 | 1379 | |
|---|
| 1535 | | - for (i = 0; i < CARM_MAX_PORTS; i++) { |
|---|
| 1536 | | - struct gendisk *disk = host->port[i].disk; |
|---|
| 1537 | | - if (disk) { |
|---|
| 1538 | | - struct request_queue *q = disk->queue; |
|---|
| 1380 | + if (!disk) |
|---|
| 1381 | + return; |
|---|
| 1539 | 1382 | |
|---|
| 1540 | | - if (disk->flags & GENHD_FL_UP) |
|---|
| 1541 | | - del_gendisk(disk); |
|---|
| 1542 | | - if (q) |
|---|
| 1543 | | - blk_cleanup_queue(q); |
|---|
| 1544 | | - put_disk(disk); |
|---|
| 1545 | | - } |
|---|
| 1546 | | - } |
|---|
| 1383 | + if (disk->flags & GENHD_FL_UP) |
|---|
| 1384 | + del_gendisk(disk); |
|---|
| 1385 | + if (disk->queue) |
|---|
| 1386 | + blk_cleanup_queue(disk->queue); |
|---|
| 1387 | + put_disk(disk); |
|---|
| 1547 | 1388 | } |
|---|
| 1548 | 1389 | |
|---|
| 1549 | 1390 | static int carm_init_shm(struct carm_host *host) |
|---|
| 1550 | 1391 | { |
|---|
| 1551 | | - host->shm = pci_alloc_consistent(host->pdev, CARM_SHM_SIZE, |
|---|
| 1552 | | - &host->shm_dma); |
|---|
| 1392 | + host->shm = dma_alloc_coherent(&host->pdev->dev, CARM_SHM_SIZE, |
|---|
| 1393 | + &host->shm_dma, GFP_KERNEL); |
|---|
| 1553 | 1394 | if (!host->shm) |
|---|
| 1554 | 1395 | return -ENOMEM; |
|---|
| 1555 | 1396 | |
|---|
| .. | .. |
|---|
| 1565 | 1406 | static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
|---|
| 1566 | 1407 | { |
|---|
| 1567 | 1408 | struct carm_host *host; |
|---|
| 1568 | | - unsigned int pci_dac; |
|---|
| 1569 | 1409 | int rc; |
|---|
| 1570 | 1410 | struct request_queue *q; |
|---|
| 1571 | 1411 | unsigned int i; |
|---|
| .. | .. |
|---|
| 1580 | 1420 | if (rc) |
|---|
| 1581 | 1421 | goto err_out; |
|---|
| 1582 | 1422 | |
|---|
| 1583 | | -#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ |
|---|
| 1584 | | - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); |
|---|
| 1585 | | - if (!rc) { |
|---|
| 1586 | | - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
|---|
| 1587 | | - if (rc) { |
|---|
| 1588 | | - printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n", |
|---|
| 1589 | | - pci_name(pdev)); |
|---|
| 1590 | | - goto err_out_regions; |
|---|
| 1591 | | - } |
|---|
| 1592 | | - pci_dac = 1; |
|---|
| 1593 | | - } else { |
|---|
| 1594 | | -#endif |
|---|
| 1595 | | - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
|---|
| 1596 | | - if (rc) { |
|---|
| 1597 | | - printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", |
|---|
| 1598 | | - pci_name(pdev)); |
|---|
| 1599 | | - goto err_out_regions; |
|---|
| 1600 | | - } |
|---|
| 1601 | | - pci_dac = 0; |
|---|
| 1602 | | -#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ |
|---|
| 1423 | + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 1424 | + if (rc) { |
|---|
| 1425 | + printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", |
|---|
| 1426 | + pci_name(pdev)); |
|---|
| 1427 | + goto err_out_regions; |
|---|
| 1603 | 1428 | } |
|---|
| 1604 | | -#endif |
|---|
| 1605 | 1429 | |
|---|
| 1606 | 1430 | host = kzalloc(sizeof(*host), GFP_KERNEL); |
|---|
| 1607 | 1431 | if (!host) { |
|---|
| .. | .. |
|---|
| 1612 | 1436 | } |
|---|
| 1613 | 1437 | |
|---|
| 1614 | 1438 | host->pdev = pdev; |
|---|
| 1615 | | - host->flags = pci_dac ? FL_DAC : 0; |
|---|
| 1616 | 1439 | spin_lock_init(&host->lock); |
|---|
| 1617 | 1440 | INIT_WORK(&host->fsm_task, carm_fsm_task); |
|---|
| 1618 | 1441 | init_completion(&host->probe_comp); |
|---|
| 1619 | | - |
|---|
| 1620 | | - for (i = 0; i < ARRAY_SIZE(host->req); i++) |
|---|
| 1621 | | - host->req[i].tag = i; |
|---|
| 1622 | 1442 | |
|---|
| 1623 | 1443 | host->mmio = ioremap(pci_resource_start(pdev, 0), |
|---|
| 1624 | 1444 | pci_resource_len(pdev, 0)); |
|---|
| .. | .. |
|---|
| 1636 | 1456 | goto err_out_iounmap; |
|---|
| 1637 | 1457 | } |
|---|
| 1638 | 1458 | |
|---|
| 1639 | | - q = blk_init_queue(carm_oob_rq_fn, &host->lock); |
|---|
| 1640 | | - if (!q) { |
|---|
| 1641 | | - printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", |
|---|
| 1642 | | - pci_name(pdev)); |
|---|
| 1643 | | - rc = -ENOMEM; |
|---|
| 1644 | | - goto err_out_pci_free; |
|---|
| 1459 | + memset(&host->tag_set, 0, sizeof(host->tag_set)); |
|---|
| 1460 | + host->tag_set.ops = &carm_mq_ops; |
|---|
| 1461 | + host->tag_set.cmd_size = sizeof(struct carm_request); |
|---|
| 1462 | + host->tag_set.nr_hw_queues = 1; |
|---|
| 1463 | + host->tag_set.nr_maps = 1; |
|---|
| 1464 | + host->tag_set.queue_depth = max_queue; |
|---|
| 1465 | + host->tag_set.numa_node = NUMA_NO_NODE; |
|---|
| 1466 | + host->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
|---|
| 1467 | + |
|---|
| 1468 | + rc = blk_mq_alloc_tag_set(&host->tag_set); |
|---|
| 1469 | + if (rc) |
|---|
| 1470 | + goto err_out_dma_free; |
|---|
| 1471 | + |
|---|
| 1472 | + q = blk_mq_init_queue(&host->tag_set); |
|---|
| 1473 | + if (IS_ERR(q)) { |
|---|
| 1474 | + rc = PTR_ERR(q); |
|---|
| 1475 | + blk_mq_free_tag_set(&host->tag_set); |
|---|
| 1476 | + goto err_out_dma_free; |
|---|
| 1645 | 1477 | } |
|---|
| 1478 | + |
|---|
| 1646 | 1479 | host->oob_q = q; |
|---|
| 1647 | 1480 | q->queuedata = host; |
|---|
| 1648 | 1481 | |
|---|
| .. | .. |
|---|
| 1665 | 1498 | if (host->flags & FL_DYN_MAJOR) |
|---|
| 1666 | 1499 | host->major = rc; |
|---|
| 1667 | 1500 | |
|---|
| 1668 | | - rc = carm_init_disks(host); |
|---|
| 1669 | | - if (rc) |
|---|
| 1670 | | - goto err_out_blkdev_disks; |
|---|
| 1501 | + for (i = 0; i < CARM_MAX_PORTS; i++) { |
|---|
| 1502 | + rc = carm_init_disk(host, i); |
|---|
| 1503 | + if (rc) |
|---|
| 1504 | + goto err_out_blkdev_disks; |
|---|
| 1505 | + } |
|---|
| 1671 | 1506 | |
|---|
| 1672 | 1507 | pci_set_master(pdev); |
|---|
| 1673 | 1508 | |
|---|
| .. | .. |
|---|
| 1697 | 1532 | err_out_free_irq: |
|---|
| 1698 | 1533 | free_irq(pdev->irq, host); |
|---|
| 1699 | 1534 | err_out_blkdev_disks: |
|---|
| 1700 | | - carm_free_disks(host); |
|---|
| 1535 | + for (i = 0; i < CARM_MAX_PORTS; i++) |
|---|
| 1536 | + carm_free_disk(host, i); |
|---|
| 1701 | 1537 | unregister_blkdev(host->major, host->name); |
|---|
| 1702 | 1538 | err_out_free_majors: |
|---|
| 1703 | 1539 | if (host->major == 160) |
|---|
| .. | .. |
|---|
| 1705 | 1541 | else if (host->major == 161) |
|---|
| 1706 | 1542 | clear_bit(1, &carm_major_alloc); |
|---|
| 1707 | 1543 | blk_cleanup_queue(host->oob_q); |
|---|
| 1708 | | -err_out_pci_free: |
|---|
| 1709 | | - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); |
|---|
| 1544 | + blk_mq_free_tag_set(&host->tag_set); |
|---|
| 1545 | +err_out_dma_free: |
|---|
| 1546 | + dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma); |
|---|
| 1710 | 1547 | err_out_iounmap: |
|---|
| 1711 | 1548 | iounmap(host->mmio); |
|---|
| 1712 | 1549 | err_out_kfree: |
|---|
| .. | .. |
|---|
| 1721 | 1558 | static void carm_remove_one (struct pci_dev *pdev) |
|---|
| 1722 | 1559 | { |
|---|
| 1723 | 1560 | struct carm_host *host = pci_get_drvdata(pdev); |
|---|
| 1561 | + unsigned int i; |
|---|
| 1724 | 1562 | |
|---|
| 1725 | 1563 | if (!host) { |
|---|
| 1726 | 1564 | printk(KERN_ERR PFX "BUG: no host data for PCI(%s)\n", |
|---|
| .. | .. |
|---|
| 1729 | 1567 | } |
|---|
| 1730 | 1568 | |
|---|
| 1731 | 1569 | free_irq(pdev->irq, host); |
|---|
| 1732 | | - carm_free_disks(host); |
|---|
| 1570 | + for (i = 0; i < CARM_MAX_PORTS; i++) |
|---|
| 1571 | + carm_free_disk(host, i); |
|---|
| 1733 | 1572 | unregister_blkdev(host->major, host->name); |
|---|
| 1734 | 1573 | if (host->major == 160) |
|---|
| 1735 | 1574 | clear_bit(0, &carm_major_alloc); |
|---|
| 1736 | 1575 | else if (host->major == 161) |
|---|
| 1737 | 1576 | clear_bit(1, &carm_major_alloc); |
|---|
| 1738 | 1577 | blk_cleanup_queue(host->oob_q); |
|---|
| 1739 | | - pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); |
|---|
| 1578 | + blk_mq_free_tag_set(&host->tag_set); |
|---|
| 1579 | + dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma); |
|---|
| 1740 | 1580 | iounmap(host->mmio); |
|---|
| 1741 | 1581 | kfree(host); |
|---|
| 1742 | 1582 | pci_release_regions(pdev); |
|---|