Commit f96ed261 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata

Pull libata updates from Tejun Heo:
 - Write same support added
 - Minor ahci MSIX irq handling updates
 - Non-critical SCSI command translation fixes
 - Controller specific changes

* 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  ahci: qoriq: Revert "ahci: qoriq: Disable NCQ on ls2080a SoC"
  libata: remove <asm-generic/libata-portmap.h>
  libata: remove unused definitions from <asm/libata-portmap.h>
  pata_at91: Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
  ata: Replace BUG() with BUG_ON().
  ata: sata_mv: Replacing dma_pool_alloc and memset with a single call dma_pool_zalloc.
  libata: Some drives failing on SCT Write Same
  ahci: use pci_alloc_irq_vectors
  libata: SCT Write Same handle ATA_DFLAG_PIO
  libata: SCT Write Same / DSM Trim
  libata: Add support for SCT Write Same
  libata: Safely overwrite attached page in WRITE SAME xlat
  ahci: also use a per-port lock for the multi-MSIX case
  ARM: dts: STiH407-family: Add ports-implemented property in sata nodes
  ahci: st: Add ports-implemented property in support
  ahci: qoriq: enable snoopable sata read and write
  ahci: qoriq: adjust sata parameter
  libata-scsi: fix MODE SELECT translation for Control mode page
  libata-scsi: use u8 array to store mode page copy
parents b56061b0 1ce788d2
...@@ -502,10 +502,11 @@ usb2: usb3@3100000 { ...@@ -502,10 +502,11 @@ usb2: usb3@3100000 {
}; };
sata: sata@3200000 { sata: sata@3200000 {
compatible = "fsl,ls1043a-ahci", "fsl,ls1021a-ahci"; compatible = "fsl,ls1043a-ahci";
reg = <0x0 0x3200000 0x0 0x10000>; reg = <0x0 0x3200000 0x0 0x10000>;
interrupts = <0 69 0x4>; interrupts = <0 69 0x4>;
clocks = <&clockgen 4 0>; clocks = <&clockgen 4 0>;
dma-coherent;
}; };
msi1: msi-controller1@1571000 { msi1: msi-controller1@1571000 {
......
...@@ -683,6 +683,7 @@ sata0: sata@3200000 { ...@@ -683,6 +683,7 @@ sata0: sata@3200000 {
reg = <0x0 0x3200000 0x0 0x10000>; reg = <0x0 0x3200000 0x0 0x10000>;
interrupts = <0 133 0x4>; /* Level high type */ interrupts = <0 133 0x4>; /* Level high type */
clocks = <&clockgen 4 3>; clocks = <&clockgen 4 3>;
dma-coherent;
}; };
sata1: sata@3210000 { sata1: sata@3210000 {
...@@ -691,6 +692,7 @@ sata1: sata@3210000 { ...@@ -691,6 +692,7 @@ sata1: sata@3210000 {
reg = <0x0 0x3210000 0x0 0x10000>; reg = <0x0 0x3210000 0x0 0x10000>;
interrupts = <0 136 0x4>; /* Level high type */ interrupts = <0 136 0x4>; /* Level high type */
clocks = <&clockgen 4 3>; clocks = <&clockgen 4 3>;
dma-coherent;
}; };
usb0: usb3@3100000 { usb0: usb3@3100000 {
......
#ifndef __ASM_IA64_LIBATA_PORTMAP_H #ifndef __ASM_IA64_LIBATA_PORTMAP_H
#define __ASM_IA64_LIBATA_PORTMAP_H #define __ASM_IA64_LIBATA_PORTMAP_H
#define ATA_PRIMARY_CMD 0x1F0
#define ATA_PRIMARY_CTL 0x3F6
#define ATA_PRIMARY_IRQ(dev) isa_irq_to_vector(14) #define ATA_PRIMARY_IRQ(dev) isa_irq_to_vector(14)
#define ATA_SECONDARY_CMD 0x170
#define ATA_SECONDARY_CTL 0x376
#define ATA_SECONDARY_IRQ(dev) isa_irq_to_vector(15) #define ATA_SECONDARY_IRQ(dev) isa_irq_to_vector(15)
#endif #endif
#ifndef __ASM_POWERPC_LIBATA_PORTMAP_H #ifndef __ASM_POWERPC_LIBATA_PORTMAP_H
#define __ASM_POWERPC_LIBATA_PORTMAP_H #define __ASM_POWERPC_LIBATA_PORTMAP_H
#define ATA_PRIMARY_CMD 0x1F0
#define ATA_PRIMARY_CTL 0x3F6
#define ATA_PRIMARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 0) #define ATA_PRIMARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 0)
#define ATA_SECONDARY_CMD 0x170
#define ATA_SECONDARY_CTL 0x376
#define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1) #define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1)
#endif #endif
...@@ -1400,142 +1400,56 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance) ...@@ -1400,142 +1400,56 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
} }
#endif #endif
/* static int ahci_get_irq_vector(struct ata_host *host, int port)
* ahci_init_msix() - optionally enable per-port MSI-X otherwise defer
* to single msi.
*/
static int ahci_init_msix(struct pci_dev *pdev, unsigned int n_ports,
struct ahci_host_priv *hpriv, unsigned long flags)
{ {
int nvec, i, rc; return pci_irq_vector(to_pci_dev(host->dev), port);
/* Do not init MSI-X if MSI is disabled for the device */
if (hpriv->flags & AHCI_HFLAG_NO_MSI)
return -ENODEV;
nvec = pci_msix_vec_count(pdev);
if (nvec < 0)
return nvec;
/*
* Proper MSI-X implementations will have a vector per-port.
* Barring that, we prefer single-MSI over single-MSIX. If this
* check fails (not enough MSI-X vectors for all ports) we will
* be called again with the flag clear iff ahci_init_msi()
* fails.
*/
if (flags & AHCI_HFLAG_MULTI_MSIX) {
if (nvec < n_ports)
return -ENODEV;
nvec = n_ports;
} else if (nvec) {
nvec = 1;
} else {
/*
* Emit dev_err() since this was the non-legacy irq
* method of last resort.
*/
rc = -ENODEV;
goto fail;
}
for (i = 0; i < nvec; i++)
hpriv->msix[i].entry = i;
rc = pci_enable_msix_exact(pdev, hpriv->msix, nvec);
if (rc < 0)
goto fail;
if (nvec > 1)
hpriv->flags |= AHCI_HFLAG_MULTI_MSIX;
hpriv->irq = hpriv->msix[0].vector; /* for single msi-x */
return nvec;
fail:
dev_err(&pdev->dev,
"failed to enable MSI-X with error %d, # of vectors: %d\n",
rc, nvec);
return rc;
} }
static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports, static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
struct ahci_host_priv *hpriv) struct ahci_host_priv *hpriv)
{ {
int rc, nvec; int nvec;
if (hpriv->flags & AHCI_HFLAG_NO_MSI) if (hpriv->flags & AHCI_HFLAG_NO_MSI)
return -ENODEV; return -ENODEV;
nvec = pci_msi_vec_count(pdev);
if (nvec < 0)
return nvec;
/* /*
* If number of MSIs is less than number of ports then Sharing Last * If number of MSIs is less than number of ports then Sharing Last
* Message mode could be enforced. In this case assume that advantage * Message mode could be enforced. In this case assume that advantage
* of multipe MSIs is negated and use single MSI mode instead. * of multipe MSIs is negated and use single MSI mode instead.
*/ */
if (nvec < n_ports) nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
goto single_msi; PCI_IRQ_MSIX | PCI_IRQ_MSI);
if (nvec > 0) {
rc = pci_enable_msi_exact(pdev, nvec); if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
if (rc == -ENOSPC) hpriv->get_irq_vector = ahci_get_irq_vector;
goto single_msi; hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
if (rc < 0) return nvec;
return rc; }
/* fallback to single MSI mode if the controller enforced MRSM mode */ /*
if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { * Fallback to single MSI mode if the controller enforced MRSM
pci_disable_msi(pdev); * mode.
*/
printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
goto single_msi; pci_free_irq_vectors(pdev);
} }
if (nvec > 1)
hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
goto out;
single_msi:
nvec = 1;
rc = pci_enable_msi(pdev);
if (rc < 0)
return rc;
out:
hpriv->irq = pdev->irq;
return nvec;
}
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
struct ahci_host_priv *hpriv)
{
int nvec;
/* /*
* Try to enable per-port MSI-X. If the host is not capable * -ENOSPC indicated we don't have enough vectors. Don't bother trying
* fall back to single MSI before finally attempting single * a single vectors for any other error:
* MSI-X.
*/ */
nvec = ahci_init_msix(pdev, n_ports, hpriv, AHCI_HFLAG_MULTI_MSIX); if (nvec < 0 && nvec != -ENOSPC)
if (nvec >= 0)
return nvec; return nvec;
nvec = ahci_init_msi(pdev, n_ports, hpriv); /*
if (nvec >= 0) * If the host is not capable of supporting per-port vectors, fall
return nvec; * back to single MSI before finally attempting single MSI-X.
*/
/* try single-msix */ nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
nvec = ahci_init_msix(pdev, n_ports, hpriv, 0); if (nvec == 1)
if (nvec >= 0)
return nvec; return nvec;
return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
/* legacy intx interrupts */
pci_intx(pdev, 1);
hpriv->irq = pdev->irq;
return 0;
} }
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
...@@ -1698,11 +1612,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1698,11 +1612,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!host) if (!host)
return -ENOMEM; return -ENOMEM;
host->private_data = hpriv; host->private_data = hpriv;
hpriv->msix = devm_kzalloc(&pdev->dev,
sizeof(struct msix_entry) * n_ports, GFP_KERNEL); if (ahci_init_msi(pdev, n_ports, hpriv) < 0) {
if (!hpriv->msix) /* legacy intx interrupts */
return -ENOMEM; pci_intx(pdev, 1);
ahci_init_interrupts(pdev, n_ports, hpriv); }
hpriv->irq = pdev->irq;
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN; host->flags |= ATA_HOST_PARALLEL_SCAN;
......
...@@ -242,12 +242,10 @@ enum { ...@@ -242,12 +242,10 @@ enum {
AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
AHCI_HFLAG_MULTI_MSI = (1 << 20), /* multiple PCI MSIs */ AHCI_HFLAG_MULTI_MSI = (1 << 20), /* per-port MSI(-X) */
AHCI_HFLAG_MULTI_MSIX = (1 << 21), /* per-port MSI-X */
#else #else
/* compile out MSI infrastructure */ /* compile out MSI infrastructure */
AHCI_HFLAG_MULTI_MSI = 0, AHCI_HFLAG_MULTI_MSI = 0,
AHCI_HFLAG_MULTI_MSIX = 0,
#endif #endif
AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */ AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */
...@@ -351,7 +349,6 @@ struct ahci_host_priv { ...@@ -351,7 +349,6 @@ struct ahci_host_priv {
* the PHY position in this array. * the PHY position in this array.
*/ */
struct phy **phys; struct phy **phys;
struct msix_entry *msix; /* Optional MSI-X support */
unsigned nports; /* Number of ports */ unsigned nports; /* Number of ports */
void *plat_data; /* Other platform data */ void *plat_data; /* Other platform data */
unsigned int irq; /* interrupt line */ unsigned int irq; /* interrupt line */
...@@ -362,22 +359,11 @@ struct ahci_host_priv { ...@@ -362,22 +359,11 @@ struct ahci_host_priv {
*/ */
void (*start_engine)(struct ata_port *ap); void (*start_engine)(struct ata_port *ap);
irqreturn_t (*irq_handler)(int irq, void *dev_instance); irqreturn_t (*irq_handler)(int irq, void *dev_instance);
};
#ifdef CONFIG_PCI_MSI /* only required for per-port MSI(-X) support */
static inline int ahci_irq_vector(struct ahci_host_priv *hpriv, int port) int (*get_irq_vector)(struct ata_host *host,
{ int port);
if (hpriv->flags & AHCI_HFLAG_MULTI_MSIX) };
return hpriv->msix[port].vector;
else
return hpriv->irq + port;
}
#else
static inline int ahci_irq_vector(struct ahci_host_priv *hpriv, int port)
{
return hpriv->irq;
}
#endif
extern int ahci_ignore_sss; extern int ahci_ignore_sss;
......
...@@ -30,24 +30,23 @@ ...@@ -30,24 +30,23 @@
#define PORT_PHY3 0xB0 #define PORT_PHY3 0xB0
#define PORT_PHY4 0xB4 #define PORT_PHY4 0xB4
#define PORT_PHY5 0xB8 #define PORT_PHY5 0xB8
#define PORT_AXICC 0xBC
#define PORT_TRANS 0xC8 #define PORT_TRANS 0xC8
/* port register default value */ /* port register default value */
#define AHCI_PORT_PHY_1_CFG 0xa003fffe #define AHCI_PORT_PHY_1_CFG 0xa003fffe
#define AHCI_PORT_TRANS_CFG 0x08000029 #define AHCI_PORT_TRANS_CFG 0x08000029
#define AHCI_PORT_AXICC_CFG 0x3fffffff
/* for ls1021a */ /* for ls1021a */
#define LS1021A_PORT_PHY2 0x28183414 #define LS1021A_PORT_PHY2 0x28183414
#define LS1021A_PORT_PHY3 0x0e080e06 #define LS1021A_PORT_PHY3 0x0e080e06
#define LS1021A_PORT_PHY4 0x064a080b #define LS1021A_PORT_PHY4 0x064a080b
#define LS1021A_PORT_PHY5 0x2aa86470 #define LS1021A_PORT_PHY5 0x2aa86470
#define LS1021A_AXICC_ADDR 0xC0
#define SATA_ECC_DISABLE 0x00020000 #define SATA_ECC_DISABLE 0x00020000
/* for ls1043a */
#define LS1043A_PORT_PHY2 0x28184d1f
#define LS1043A_PORT_PHY3 0x0e081509
enum ahci_qoriq_type { enum ahci_qoriq_type {
AHCI_LS1021A, AHCI_LS1021A,
AHCI_LS1043A, AHCI_LS1043A,
...@@ -137,7 +136,7 @@ static struct ata_port_operations ahci_qoriq_ops = { ...@@ -137,7 +136,7 @@ static struct ata_port_operations ahci_qoriq_ops = {
.hardreset = ahci_qoriq_hardreset, .hardreset = ahci_qoriq_hardreset,
}; };
static struct ata_port_info ahci_qoriq_port_info = { static const struct ata_port_info ahci_qoriq_port_info = {
.flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
...@@ -162,18 +161,19 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) ...@@ -162,18 +161,19 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
break; break;
case AHCI_LS1043A: case AHCI_LS1043A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(LS1043A_PORT_PHY2, reg_base + PORT_PHY2);
writel(LS1043A_PORT_PHY3, reg_base + PORT_PHY3);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break; break;
case AHCI_LS2080A: case AHCI_LS2080A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break; break;
} }
...@@ -221,12 +221,6 @@ static int ahci_qoriq_probe(struct platform_device *pdev) ...@@ -221,12 +221,6 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
if (rc) if (rc)
goto disable_resources; goto disable_resources;
/* Workaround for ls2080a */
if (qoriq_priv->type == AHCI_LS2080A) {
hpriv->flags |= AHCI_HFLAG_NO_NCQ;
ahci_qoriq_port_info.flags &= ~ATA_FLAG_NCQ;
}
rc = ahci_platform_init_host(pdev, hpriv, &ahci_qoriq_port_info, rc = ahci_platform_init_host(pdev, hpriv, &ahci_qoriq_port_info,
&ahci_qoriq_sht); &ahci_qoriq_sht);
if (rc) if (rc)
......
...@@ -147,6 +147,7 @@ static struct scsi_host_template ahci_platform_sht = { ...@@ -147,6 +147,7 @@ static struct scsi_host_template ahci_platform_sht = {
static int st_ahci_probe(struct platform_device *pdev) static int st_ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct st_ahci_drv_data *drv_data; struct st_ahci_drv_data *drv_data;
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
int err; int err;
...@@ -170,6 +171,9 @@ static int st_ahci_probe(struct platform_device *pdev) ...@@ -170,6 +171,9 @@ static int st_ahci_probe(struct platform_device *pdev)
st_ahci_configure_oob(hpriv->mmio); st_ahci_configure_oob(hpriv->mmio);
of_property_read_u32(dev->of_node,
"ports-implemented", &hpriv->force_port_map);
err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
&ahci_platform_sht); &ahci_platform_sht);
if (err) { if (err) {
......
...@@ -2520,7 +2520,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, ...@@ -2520,7 +2520,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host,
*/ */
for (i = 0; i < host->n_ports; i++) { for (i = 0; i < host->n_ports; i++) {
struct ahci_port_priv *pp = host->ports[i]->private_data; struct ahci_port_priv *pp = host->ports[i]->private_data;
int irq = ahci_irq_vector(hpriv, i); int irq = hpriv->get_irq_vector(host, i);
/* Do not receive interrupts sent by dummy ports */ /* Do not receive interrupts sent by dummy ports */
if (!pp) { if (!pp) {
...@@ -2556,10 +2556,15 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht) ...@@ -2556,10 +2556,15 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
int irq = hpriv->irq; int irq = hpriv->irq;
int rc; int rc;
if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) { if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
if (hpriv->irq_handler) if (hpriv->irq_handler)
dev_warn(host->dev, dev_warn(host->dev,
"both AHCI_HFLAG_MULTI_MSI flag set and custom irq handler implemented\n"); "both AHCI_HFLAG_MULTI_MSI flag set and custom irq handler implemented\n");
if (!hpriv->get_irq_vector) {
dev_err(host->dev,
"AHCI_HFLAG_MULTI_MSI requires ->get_irq_vector!\n");
return -EIO;
}
rc = ahci_host_activate_multi_irqs(host, sht); rc = ahci_host_activate_multi_irqs(host, sht);
} else { } else {
......
This diff is collapsed.
...@@ -347,10 +347,8 @@ static int at91sam9_smc_fields_init(struct device *dev) ...@@ -347,10 +347,8 @@ static int at91sam9_smc_fields_init(struct device *dev)
field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC); field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC);
fields.mode = devm_regmap_field_alloc(dev, smc, field); fields.mode = devm_regmap_field_alloc(dev, smc, field);
if (IS_ERR(fields.mode))
return PTR_ERR(fields.mode);
return 0; return PTR_ERR_OR_ZERO(fields.mode);
} }
static int pata_at91_probe(struct platform_device *pdev) static int pata_at91_probe(struct platform_device *pdev)
......
...@@ -152,8 +152,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev) ...@@ -152,8 +152,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
div = 8; div = 8;
T = (int)((1000000000000LL * div) / octeon_get_io_clock_rate()); T = (int)((1000000000000LL * div) / octeon_get_io_clock_rate());
if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T)) BUG_ON(ata_timing_compute(dev, dev->pio_mode, &timing, T, T));
BUG();
t1 = timing.setup; t1 = timing.setup;
if (t1) if (t1)
......
...@@ -1727,15 +1727,13 @@ static int mv_port_start(struct ata_port *ap) ...@@ -1727,15 +1727,13 @@ static int mv_port_start(struct ata_port *ap)
return -ENOMEM; return -ENOMEM;
ap->private_data = pp; ap->private_data = pp;
pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma); pp->crqb = dma_pool_zalloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma);
if (!pp->crqb) if (!pp->crqb)
return -ENOMEM; return -ENOMEM;
memset(pp->crqb, 0, MV_CRQB_Q_SZ);
pp->crpb = dma_pool_alloc(hpriv->crpb_pool, GFP_KERNEL, &pp->crpb_dma); pp->crpb = dma_pool_zalloc(hpriv->crpb_pool, GFP_KERNEL, &pp->crpb_dma);
if (!pp->crpb) if (!pp->crpb)
goto out_port_free_dma_mem; goto out_port_free_dma_mem;
memset(pp->crpb, 0, MV_CRPB_Q_SZ);
/* 6041/6081 Rev. "C0" (and newer) are okay with async notify */ /* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0) if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
......
#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
#define __ASM_GENERIC_LIBATA_PORTMAP_H
#define ATA_PRIMARY_IRQ(dev) 14
#define ATA_SECONDARY_IRQ(dev) 15
#endif
...@@ -105,6 +105,7 @@ enum { ...@@ -105,6 +105,7 @@ enum {
ATA_ID_CFA_KEY_MGMT = 162, ATA_ID_CFA_KEY_MGMT = 162,
ATA_ID_CFA_MODES = 163, ATA_ID_CFA_MODES = 163,
ATA_ID_DATA_SET_MGMT = 169, ATA_ID_DATA_SET_MGMT = 169,
ATA_ID_SCT_CMD_XPORT = 206,
ATA_ID_ROT_SPEED = 217, ATA_ID_ROT_SPEED = 217,
ATA_ID_PIO4 = (1 << 1), ATA_ID_PIO4 = (1 << 1),
...@@ -788,6 +789,48 @@ static inline bool ata_id_sense_reporting_enabled(const u16 *id) ...@@ -788,6 +789,48 @@ static inline bool ata_id_sense_reporting_enabled(const u16 *id)
return id[ATA_ID_COMMAND_SET_4] & (1 << 6); return id[ATA_ID_COMMAND_SET_4] & (1 << 6);
} }
/**
*
* Word: 206 - SCT Command Transport
* 15:12 - Vendor Specific
* 11:6 - Reserved
* 5 - SCT Command Transport Data Tables supported
* 4 - SCT Command Transport Features Control supported
* 3 - SCT Command Transport Error Recovery Control supported
* 2 - SCT Command Transport Write Same supported
* 1 - SCT Command Transport Long Sector Access supported
* 0 - SCT Command Transport supported
*/
static inline bool ata_id_sct_data_tables(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 5) ? true : false;
}
static inline bool ata_id_sct_features_ctrl(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 4) ? true : false;
}
static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false;
}
static inline bool ata_id_sct_write_same(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 2) ? true : false;
}
static inline bool ata_id_sct_long_sector_access(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false;
}
static inline bool ata_id_sct_supported(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 0) ? true : false;
}
/** /**
* ata_id_major_version - get ATA level of drive * ata_id_major_version - get ATA level of drive
* @id: Identify data * @id: Identify data
...@@ -1071,32 +1114,6 @@ static inline void ata_id_to_hd_driveid(u16 *id) ...@@ -1071,32 +1114,6 @@ static inline void ata_id_to_hd_driveid(u16 *id)
#endif #endif
} }
/*
* Write LBA Range Entries to the buffer that will cover the extent from
* sector to sector + count. This is used for TRIM and for ADD LBA(S)
* TO NV CACHE PINNED SET.
*/
static inline unsigned ata_set_lba_range_entries(void *_buffer,
unsigned num, u64 sector, unsigned long count)
{
__le64 *buffer = _buffer;
unsigned i = 0, used_bytes;
while (i < num) {
u64 entry = sector |
((u64)(count > 0xffff ? 0xffff : count) << 48);
buffer[i++] = __cpu_to_le64(entry);
if (count <= 0xffff)
break;
count -= 0xffff;
sector += 0xffff;
}
used_bytes = ALIGN(i * 8, 512);
memset(buffer + i, 0, used_bytes - i * 8);
return used_bytes;
}
static inline bool ata_ok(u8 status) static inline bool ata_ok(u8 status)
{ {
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
......
...@@ -46,7 +46,8 @@ ...@@ -46,7 +46,8 @@
#ifdef CONFIG_ATA_NONSTANDARD #ifdef CONFIG_ATA_NONSTANDARD
#include <asm/libata-portmap.h> #include <asm/libata-portmap.h>
#else #else
#include <asm-generic/libata-portmap.h> #define ATA_PRIMARY_IRQ(dev) 14
#define ATA_SECONDARY_IRQ(dev) 15
#endif #endif
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment