aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_sil24.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r--drivers/scsi/sata_sil24.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 211ec7eebc9c..e6c8e89c226f 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -635,6 +635,13 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *
635 return IRQ_RETVAL(handled); 635 return IRQ_RETVAL(handled);
636} 636}
637 637
638static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
639{
640 const size_t cb_size = sizeof(*pp->cmd_block);
641
642 dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
643}
644
638static int sil24_port_start(struct ata_port *ap) 645static int sil24_port_start(struct ata_port *ap)
639{ 646{
640 struct device *dev = ap->host_set->dev; 647 struct device *dev = ap->host_set->dev;
@@ -642,36 +649,44 @@ static int sil24_port_start(struct ata_port *ap)
642 struct sil24_cmd_block *cb; 649 struct sil24_cmd_block *cb;
643 size_t cb_size = sizeof(*cb); 650 size_t cb_size = sizeof(*cb);
644 dma_addr_t cb_dma; 651 dma_addr_t cb_dma;
652 int rc = -ENOMEM;
645 653
646 pp = kmalloc(sizeof(*pp), GFP_KERNEL); 654 pp = kzalloc(sizeof(*pp), GFP_KERNEL);
647 if (!pp) 655 if (!pp)
648 return -ENOMEM; 656 goto err_out;
649 memset(pp, 0, sizeof(*pp));
650 657
651 pp->tf.command = ATA_DRDY; 658 pp->tf.command = ATA_DRDY;
652 659
653 cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL); 660 cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
654 if (!cb) { 661 if (!cb)
655 kfree(pp); 662 goto err_out_pp;
656 return -ENOMEM;
657 }
658 memset(cb, 0, cb_size); 663 memset(cb, 0, cb_size);
659 664
665 rc = ata_pad_alloc(ap, dev);
666 if (rc)
667 goto err_out_pad;
668
660 pp->cmd_block = cb; 669 pp->cmd_block = cb;
661 pp->cmd_block_dma = cb_dma; 670 pp->cmd_block_dma = cb_dma;
662 671
663 ap->private_data = pp; 672 ap->private_data = pp;
664 673
665 return 0; 674 return 0;
675
676err_out_pad:
677 sil24_cblk_free(pp, dev);
678err_out_pp:
679 kfree(pp);
680err_out:
681 return rc;
666} 682}
667 683
668static void sil24_port_stop(struct ata_port *ap) 684static void sil24_port_stop(struct ata_port *ap)
669{ 685{
670 struct device *dev = ap->host_set->dev; 686 struct device *dev = ap->host_set->dev;
671 struct sil24_port_priv *pp = ap->private_data; 687 struct sil24_port_priv *pp = ap->private_data;
672 size_t cb_size = sizeof(*pp->cmd_block);
673 688
674 dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); 689 sil24_cblk_free(pp, dev);
675 kfree(pp); 690 kfree(pp);
676} 691}
677 692