diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 118 |
1 files changed, 50 insertions, 68 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c24127dd6ef..63d53277d6a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -35,6 +35,7 @@ #include <linux/kernel.h> #include <linux/gfp.h> #include <linux/pci.h> +#include <linux/module.h> #include <linux/libata.h> #include <linux/highmem.h> @@ -569,7 +570,7 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, /* Transfer trailing byte, if any. */ if (unlikely(buflen & 0x01)) { - unsigned char pad[2]; + unsigned char pad[2] = { }; /* Point buf to the tail of buffer */ buf += buflen - 1; @@ -628,7 +629,7 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, /* Transfer trailing bytes, if any */ if (unlikely(slop)) { - unsigned char pad[4]; + unsigned char pad[4] = { }; /* Point buf to the tail of buffer */ buf += buflen - slop; @@ -678,7 +679,7 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, unsigned int consumed; local_irq_save(flags); - consumed = ata_sff_data_xfer(dev, buf, buflen, rw); + consumed = ata_sff_data_xfer32(dev, buf, buflen, rw); local_irq_restore(flags); return consumed; @@ -2507,31 +2508,10 @@ static const struct ata_port_info *ata_sff_find_valid_pi( return NULL; } -/** - * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller - * @pdev: Controller to be initialized - * @ppi: array of port_info, must be enough for two ports - * @sht: scsi_host_template to use when registering the host - * @host_priv: host private_data - * @hflag: host flags - * - * This is a helper function which can be called from a driver's - * xxx_init_one() probe function if the hardware uses traditional - * IDE taskfile registers and is PIO only. - * - * ASSUMPTION: - * Nobody makes a single channel controller that appears solely as - * the secondary legacy port on PCI. - * - * LOCKING: - * Inherited from PCI layer (may sleep). - * - * RETURNS: - * Zero on success, negative on errno-based value on error. - */ -int ata_pci_sff_init_one(struct pci_dev *pdev, - const struct ata_port_info * const *ppi, - struct scsi_host_template *sht, void *host_priv, int hflag) +static int ata_pci_init_one(struct pci_dev *pdev, + const struct ata_port_info * const *ppi, + struct scsi_host_template *sht, void *host_priv, + int hflags, bool bmdma) { struct device *dev = &pdev->dev; const struct ata_port_info *pi; @@ -2553,14 +2533,22 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, if (rc) goto out; - /* prepare and activate SFF host */ - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + if (bmdma) + /* prepare and activate BMDMA host */ + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); + else + /* prepare and activate SFF host */ + rc = ata_pci_sff_prepare_host(pdev, ppi, &host); if (rc) goto out; host->private_data = host_priv; - host->flags |= hflag; + host->flags |= hflags; - rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); + if (bmdma) { + pci_set_master(pdev); + rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); + } else + rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); out: if (rc == 0) devres_remove_group(&pdev->dev, NULL); @@ -2569,6 +2557,35 @@ out: return rc; } + +/** + * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller + * @pdev: Controller to be initialized + * @ppi: array of port_info, must be enough for two ports + * @sht: scsi_host_template to use when registering the host + * @host_priv: host private_data + * @hflag: host flags + * + * This is a helper function which can be called from a driver's + * xxx_init_one() probe function if the hardware uses traditional + * IDE taskfile registers and is PIO only. + * + * ASSUMPTION: + * Nobody makes a single channel controller that appears solely as + * the secondary legacy port on PCI. + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, negative on errno-based value on error. + */ +int ata_pci_sff_init_one(struct pci_dev *pdev, + const struct ata_port_info * const *ppi, + struct scsi_host_template *sht, void *host_priv, int hflag) +{ + return ata_pci_init_one(pdev, ppi, sht, host_priv, hflag, 0); +} EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); #endif /* CONFIG_PCI */ @@ -3286,42 +3303,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev, struct scsi_host_template *sht, void *host_priv, int hflags) { - struct device *dev = &pdev->dev; - const struct ata_port_info *pi; - struct ata_host *host = NULL; - int rc; - - DPRINTK("ENTER\n"); - - pi = ata_sff_find_valid_pi(ppi); - if (!pi) { - dev_err(&pdev->dev, "no valid port_info specified\n"); - return -EINVAL; - } - - if (!devres_open_group(dev, NULL, GFP_KERNEL)) - return -ENOMEM; - - rc = pcim_enable_device(pdev); - if (rc) - goto out; - - /* prepare and activate BMDMA host */ - rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); - if (rc) - goto out; - host->private_data = host_priv; - host->flags |= hflags; - - pci_set_master(pdev); - rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); - out: - if (rc == 0) - devres_remove_group(&pdev->dev, NULL); - else - devres_release_group(&pdev->dev, NULL); - - return rc; + return ata_pci_init_one(pdev, ppi, sht, host_priv, hflags, 1); } EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); |