diff options
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r-- | drivers/scsi/sata_sil24.c | 33 |
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 | ||
638 | static 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 | |||
638 | static int sil24_port_start(struct ata_port *ap) | 645 | static 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 | |||
676 | err_out_pad: | ||
677 | sil24_cblk_free(pp, dev); | ||
678 | err_out_pp: | ||
679 | kfree(pp); | ||
680 | err_out: | ||
681 | return rc; | ||
666 | } | 682 | } |
667 | 683 | ||
668 | static void sil24_port_stop(struct ata_port *ap) | 684 | static 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 | ||