diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:44:02 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:44:02 -0500 |
commit | 8cedcfd43a0b00741fff43d6a4c1a8b7748db3b0 (patch) | |
tree | 41758e4da78f94a20813554ef9f5ed9b323a4f8c /drivers/scsi/sata_mv.c | |
parent | cd8200e6d4f9f05e6ea48f7c000be890337396ac (diff) | |
parent | 70d9d825e0a5a78ec1dacaaaf5c72ff5b0206fab (diff) |
Merge branch 'master'
Diffstat (limited to 'drivers/scsi/sata_mv.c')
-rw-r--r-- | drivers/scsi/sata_mv.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 2a68b6227464..a99dad510705 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -671,6 +671,11 @@ static void mv_host_stop(struct ata_host_set *host_set) | |||
671 | ata_host_stop(host_set); | 671 | ata_host_stop(host_set); |
672 | } | 672 | } |
673 | 673 | ||
674 | static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev) | ||
675 | { | ||
676 | dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma); | ||
677 | } | ||
678 | |||
674 | /** | 679 | /** |
675 | * mv_port_start - Port specific init/start routine. | 680 | * mv_port_start - Port specific init/start routine. |
676 | * @ap: ATA channel to manipulate | 681 | * @ap: ATA channel to manipulate |
@@ -688,21 +693,23 @@ static int mv_port_start(struct ata_port *ap) | |||
688 | void __iomem *port_mmio = mv_ap_base(ap); | 693 | void __iomem *port_mmio = mv_ap_base(ap); |
689 | void *mem; | 694 | void *mem; |
690 | dma_addr_t mem_dma; | 695 | dma_addr_t mem_dma; |
696 | int rc = -ENOMEM; | ||
691 | 697 | ||
692 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 698 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); |
693 | if (!pp) { | 699 | if (!pp) |
694 | return -ENOMEM; | 700 | goto err_out; |
695 | } | ||
696 | memset(pp, 0, sizeof(*pp)); | 701 | memset(pp, 0, sizeof(*pp)); |
697 | 702 | ||
698 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, | 703 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, |
699 | GFP_KERNEL); | 704 | GFP_KERNEL); |
700 | if (!mem) { | 705 | if (!mem) |
701 | kfree(pp); | 706 | goto err_out_pp; |
702 | return -ENOMEM; | ||
703 | } | ||
704 | memset(mem, 0, MV_PORT_PRIV_DMA_SZ); | 707 | memset(mem, 0, MV_PORT_PRIV_DMA_SZ); |
705 | 708 | ||
709 | rc = ata_pad_alloc(ap, dev); | ||
710 | if (rc) | ||
711 | goto err_out_priv; | ||
712 | |||
706 | /* First item in chunk of DMA memory: | 713 | /* First item in chunk of DMA memory: |
707 | * 32-slot command request table (CRQB), 32 bytes each in size | 714 | * 32-slot command request table (CRQB), 32 bytes each in size |
708 | */ | 715 | */ |
@@ -747,6 +754,13 @@ static int mv_port_start(struct ata_port *ap) | |||
747 | */ | 754 | */ |
748 | ap->private_data = pp; | 755 | ap->private_data = pp; |
749 | return 0; | 756 | return 0; |
757 | |||
758 | err_out_priv: | ||
759 | mv_priv_free(pp, dev); | ||
760 | err_out_pp: | ||
761 | kfree(pp); | ||
762 | err_out: | ||
763 | return rc; | ||
750 | } | 764 | } |
751 | 765 | ||
752 | /** | 766 | /** |
@@ -769,7 +783,8 @@ static void mv_port_stop(struct ata_port *ap) | |||
769 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 783 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
770 | 784 | ||
771 | ap->private_data = NULL; | 785 | ap->private_data = NULL; |
772 | dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma); | 786 | ata_pad_free(ap, dev); |
787 | mv_priv_free(pp, dev); | ||
773 | kfree(pp); | 788 | kfree(pp); |
774 | } | 789 | } |
775 | 790 | ||
@@ -785,23 +800,24 @@ static void mv_port_stop(struct ata_port *ap) | |||
785 | static void mv_fill_sg(struct ata_queued_cmd *qc) | 800 | static void mv_fill_sg(struct ata_queued_cmd *qc) |
786 | { | 801 | { |
787 | struct mv_port_priv *pp = qc->ap->private_data; | 802 | struct mv_port_priv *pp = qc->ap->private_data; |
788 | unsigned int i; | 803 | unsigned int i = 0; |
804 | struct scatterlist *sg; | ||
789 | 805 | ||
790 | for (i = 0; i < qc->n_elem; i++) { | 806 | ata_for_each_sg(sg, qc) { |
791 | u32 sg_len; | 807 | u32 sg_len; |
792 | dma_addr_t addr; | 808 | dma_addr_t addr; |
793 | 809 | ||
794 | addr = sg_dma_address(&qc->sg[i]); | 810 | addr = sg_dma_address(sg); |
795 | sg_len = sg_dma_len(&qc->sg[i]); | 811 | sg_len = sg_dma_len(sg); |
796 | 812 | ||
797 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | 813 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); |
798 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | 814 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); |
799 | assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); | 815 | assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); |
800 | pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); | 816 | pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); |
801 | } | 817 | if (ata_sg_is_last(sg, qc)) |
802 | if (0 < qc->n_elem) { | 818 | pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); |
803 | pp->sg_tbl[qc->n_elem - 1].flags_size |= | 819 | |
804 | cpu_to_le32(EPRD_FLAG_END_OF_TBL); | 820 | i++; |
805 | } | 821 | } |
806 | } | 822 | } |
807 | 823 | ||