aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_mv.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-05 15:44:02 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-05 15:44:02 -0500
commit8cedcfd43a0b00741fff43d6a4c1a8b7748db3b0 (patch)
tree41758e4da78f94a20813554ef9f5ed9b323a4f8c /drivers/scsi/sata_mv.c
parentcd8200e6d4f9f05e6ea48f7c000be890337396ac (diff)
parent70d9d825e0a5a78ec1dacaaaf5c72ff5b0206fab (diff)
Merge branch 'master'
Diffstat (limited to 'drivers/scsi/sata_mv.c')
-rw-r--r--drivers/scsi/sata_mv.c48
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
674static 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
758err_out_priv:
759 mv_priv_free(pp, dev);
760err_out_pp:
761 kfree(pp);
762err_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)
785static void mv_fill_sg(struct ata_queued_cmd *qc) 800static 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