Commit 75a442ef authored by Linus Torvalds's avatar Linus Torvalds

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

Pull libata updates from Tejun Heo:
 "libata saw quite a bit of activities in this cycle:

   - SMR drive support still being worked on

   - bug fixes and improvements to misc SCSI command emulation

   - some low level driver updates"

* 'for-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (39 commits)
  libata-scsi: better style in ata_msense_*()
  AHCI: Clear GHC.IS to prevent unexpectly asserting INTx
  ata: sata_dwc_460ex: remove redundant dev_err call
  ata: define ATA_PROT_* in terms of ATA_PROT_FLAG_*
  libata: remove ATA_PROT_FLAG_DATA
  libata: remove ata_is_nodata
  ata: make lba_{28,48}_ok() use ATA_MAX_SECTORS{,_LBA48}
  libata-scsi: minor cleanup for ata_scsi_zbc_out_xlat
  libata-scsi: Fix ZBC management out command translation
  libata-scsi: Fix translation of REPORT ZONES command
  ata: Handle ATA NCQ NO-DATA commands correctly
  libata-eh: decode all taskfile protocols
  ata: fixup ATA_PROT_NODATA
  libsas: use ata_is_ncq() and ata_has_dma() accessors
  libata: use ata_is_ncq() accessors
  libata: return boolean values from ata_is_*
  libata-scsi: avoid repeated calculation of number of TRIM ranges
  libata-scsi: reject WRITE SAME (16) with n_block that exceeds limit
  libata-scsi: rename ata_msense_ctl_mode() to ata_msense_control()
  libata-scsi: fix D_SENSE bit relection in control mode page
  ...
parents b55b0487 737bee93
* Broadcom SATA3 AHCI Controller for STB * Broadcom SATA3 AHCI Controller
SATA nodes are defined to describe on-chip Serial ATA controllers. SATA nodes are defined to describe on-chip Serial ATA controllers.
Each SATA controller should have its own node. Each SATA controller should have its own node.
Required properties: Required properties:
- compatible : should be one or more of - compatible : should be one or more of
"brcm,bcm7425-ahci" "brcm,bcm7425-ahci"
"brcm,bcm7445-ahci" "brcm,bcm7445-ahci"
"brcm,sata3-ahci" "brcm,bcm-nsp-ahci"
"brcm,sata3-ahci"
- reg : register mappings for AHCI and SATA_TOP_CTRL - reg : register mappings for AHCI and SATA_TOP_CTRL
- reg-names : "ahci" and "top-ctrl" - reg-names : "ahci" and "top-ctrl"
- interrupts : interrupt mapping for SATA IRQ - interrupts : interrupt mapping for SATA IRQ
......
...@@ -5,6 +5,7 @@ Required properties: ...@@ -5,6 +5,7 @@ Required properties:
"brcm,bcm7425-sata-phy" "brcm,bcm7425-sata-phy"
"brcm,bcm7445-sata-phy" "brcm,bcm7445-sata-phy"
"brcm,iproc-ns2-sata-phy" "brcm,iproc-ns2-sata-phy"
"brcm,iproc-nsp-sata-phy"
"brcm,phy-sata3" "brcm,phy-sata3"
- address-cells: should be 1 - address-cells: should be 1
- size-cells: should be 0 - size-cells: should be 0
...@@ -22,7 +23,8 @@ Sub-nodes required properties: ...@@ -22,7 +23,8 @@ Sub-nodes required properties:
Sub-nodes optional properties: Sub-nodes optional properties:
- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port - brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
This property is not applicable for "brcm,iproc-ns2-sata-phy". This property is not applicable for "brcm,iproc-ns2-sata-phy" and
"brcm,iproc-nsp-sata-phy".
Example: Example:
sata-phy@f0458100 { sata-phy@f0458100 {
......
...@@ -6768,6 +6768,7 @@ S: Maintained ...@@ -6768,6 +6768,7 @@ S: Maintained
F: drivers/ata/ F: drivers/ata/
F: include/linux/ata.h F: include/linux/ata.h
F: include/linux/libata.h F: include/linux/libata.h
F: Documentation/devicetree/bindings/ata/
LIBATA PATA ARASAN COMPACT FLASH CONTROLLER LIBATA PATA ARASAN COMPACT FLASH CONTROLLER
M: Viresh Kumar <vireshk@kernel.org> M: Viresh Kumar <vireshk@kernel.org>
......
...@@ -271,6 +271,48 @@ pinctrl: pinctrl@3f1c0 { ...@@ -271,6 +271,48 @@ pinctrl: pinctrl@3f1c0 {
<0x30028 0x04>, <0x30028 0x04>,
<0x3f408 0x04>; <0x3f408 0x04>;
}; };
sata_phy: sata_phy@40100 {
compatible = "brcm,iproc-nsp-sata-phy";
reg = <0x40100 0x340>;
reg-names = "phy";
#address-cells = <1>;
#size-cells = <0>;
sata_phy0: sata-phy@0 {
reg = <0>;
#phy-cells = <0>;
status = "disabled";
};
sata_phy1: sata-phy@1 {
reg = <1>;
#phy-cells = <0>;
status = "disabled";
};
};
sata: ahci@41000 {
compatible = "brcm,bcm-nsp-ahci";
reg-names = "ahci", "top-ctrl";
reg = <0x41000 0x1000>, <0x40020 0x1c>;
interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
sata0: sata-port@0 {
reg = <0>;
phys = <&sata_phy0>;
phy-names = "sata-phy";
};
sata1: sata-port@1 {
reg = <1>;
phys = <&sata_phy1>;
phy-names = "sata-phy";
};
};
}; };
pcie0: pcie@18012000 { pcie0: pcie@18012000 {
......
...@@ -68,6 +68,18 @@ &pcie2 { ...@@ -68,6 +68,18 @@ &pcie2 {
status = "okay"; status = "okay";
}; };
&sata_phy0 {
status = "okay";
};
&sata_phy1 {
status = "okay";
};
&sata {
status = "okay";
};
&nand { &nand {
nandcs@0 { nandcs@0 {
compatible = "brcm,nandcs"; compatible = "brcm,nandcs";
......
...@@ -98,12 +98,12 @@ config SATA_AHCI_PLATFORM ...@@ -98,12 +98,12 @@ config SATA_AHCI_PLATFORM
If unsure, say N. If unsure, say N.
config AHCI_BRCMSTB config AHCI_BRCM
tristate "Broadcom STB AHCI SATA support" tristate "Broadcom AHCI SATA support"
depends on ARCH_BRCMSTB || BMIPS_GENERIC depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP
help help
This option enables support for the AHCI SATA3 controller found on This option enables support for the AHCI SATA3 controller found on
STB SoC's. Broadcom SoC's.
If unsure, say N. If unsure, say N.
......
...@@ -11,7 +11,7 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o ...@@ -11,7 +11,7 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
obj-$(CONFIG_AHCI_BRCMSTB) += ahci_brcmstb.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
......
...@@ -580,7 +580,7 @@ static struct pci_driver ahci_pci_driver = { ...@@ -580,7 +580,7 @@ static struct pci_driver ahci_pci_driver = {
}, },
}; };
#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE) #if IS_ENABLED(CONFIG_PATA_MARVELL)
static int marvell_enable; static int marvell_enable;
#else #else
static int marvell_enable = 1; static int marvell_enable = 1;
......
...@@ -71,6 +71,12 @@ ...@@ -71,6 +71,12 @@
(DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
(MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
enum brcm_ahci_version {
BRCM_SATA_BCM7425 = 1,
BRCM_SATA_BCM7445,
BRCM_SATA_NSP,
};
enum brcm_ahci_quirks { enum brcm_ahci_quirks {
BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), BRCM_AHCI_QUIRK_NO_NCQ = BIT(0),
BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
...@@ -81,6 +87,7 @@ struct brcm_ahci_priv { ...@@ -81,6 +87,7 @@ struct brcm_ahci_priv {
void __iomem *top_ctrl; void __iomem *top_ctrl;
u32 port_mask; u32 port_mask;
u32 quirks; u32 quirks;
enum brcm_ahci_version version;
}; };
static const struct ata_port_info ahci_brcm_port_info = { static const struct ata_port_info ahci_brcm_port_info = {
...@@ -247,9 +254,19 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev, ...@@ -247,9 +254,19 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
static void brcm_sata_init(struct brcm_ahci_priv *priv) static void brcm_sata_init(struct brcm_ahci_priv *priv)
{ {
void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
/* Configure endianness */ /* Configure endianness */
brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, if (priv->version == BRCM_SATA_NSP) {
priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL); u32 data = brcm_sata_readreg(ctrl);
data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) |
(0x03 << DMADESC_ENDIAN_SHIFT));
data |= (0x02 << DMADATA_ENDIAN_SHIFT) |
(0x02 << DMADESC_ENDIAN_SHIFT);
brcm_sata_writereg(data, ctrl);
} else
brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -282,8 +299,17 @@ static struct scsi_host_template ahci_platform_sht = { ...@@ -282,8 +299,17 @@ static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME), AHCI_SHT(DRV_NAME),
}; };
static const struct of_device_id ahci_of_match[] = {
{.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
{.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
{.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
{},
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
static int brcm_ahci_probe(struct platform_device *pdev) static int brcm_ahci_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct brcm_ahci_priv *priv; struct brcm_ahci_priv *priv;
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
...@@ -293,6 +319,12 @@ static int brcm_ahci_probe(struct platform_device *pdev) ...@@ -293,6 +319,12 @@ static int brcm_ahci_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
if (!of_id)
return -ENODEV;
priv->version = (enum brcm_ahci_version)of_id->data;
priv->dev = dev; priv->dev = dev;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
...@@ -300,7 +332,8 @@ static int brcm_ahci_probe(struct platform_device *pdev) ...@@ -300,7 +332,8 @@ static int brcm_ahci_probe(struct platform_device *pdev)
if (IS_ERR(priv->top_ctrl)) if (IS_ERR(priv->top_ctrl))
return PTR_ERR(priv->top_ctrl); return PTR_ERR(priv->top_ctrl);
if (of_device_is_compatible(dev->of_node, "brcm,bcm7425-ahci")) { if ((priv->version == BRCM_SATA_BCM7425) ||
(priv->version == BRCM_SATA_NSP)) {
priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
} }
...@@ -354,13 +387,6 @@ static int brcm_ahci_remove(struct platform_device *pdev) ...@@ -354,13 +387,6 @@ static int brcm_ahci_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id ahci_of_match[] = {
{.compatible = "brcm,bcm7425-ahci"},
{.compatible = "brcm,bcm7445-ahci"},
{},
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
static struct platform_driver brcm_ahci_driver = { static struct platform_driver brcm_ahci_driver = {
......
...@@ -1975,7 +1975,7 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) ...@@ -1975,7 +1975,7 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
*/ */
pp->active_link = qc->dev->link; pp->active_link = qc->dev->link;
if (qc->tf.protocol == ATA_PROT_NCQ) if (ata_is_ncq(qc->tf.protocol))
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) { if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) {
...@@ -2392,12 +2392,20 @@ static int ahci_port_start(struct ata_port *ap) ...@@ -2392,12 +2392,20 @@ static int ahci_port_start(struct ata_port *ap)
static void ahci_port_stop(struct ata_port *ap) static void ahci_port_stop(struct ata_port *ap)
{ {
const char *emsg = NULL; const char *emsg = NULL;
struct ahci_host_priv *hpriv = ap->host->private_data;
void __iomem *host_mmio = hpriv->mmio;
int rc; int rc;
/* de-initialize port */ /* de-initialize port */
rc = ahci_deinit_port(ap, &emsg); rc = ahci_deinit_port(ap, &emsg);
if (rc) if (rc)
ata_port_warn(ap, "%s (%d)\n", emsg, rc); ata_port_warn(ap, "%s (%d)\n", emsg, rc);
/*
* Clear GHC.IS to prevent stuck INTx after disabling MSI and
* re-enabling INTx.
*/
writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
} }
void ahci_print_info(struct ata_host *host, const char *scc_s) void ahci_print_info(struct ata_host *host, const char *scc_s)
......
...@@ -1238,7 +1238,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) ...@@ -1238,7 +1238,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
} else } else
tf.command = ATA_CMD_READ_NATIVE_MAX; tf.command = ATA_CMD_READ_NATIVE_MAX;
tf.protocol |= ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.device |= ATA_LBA; tf.device |= ATA_LBA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
...@@ -1297,7 +1297,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors) ...@@ -1297,7 +1297,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
tf.device |= (new_sectors >> 24) & 0xf; tf.device |= (new_sectors >> 24) & 0xf;
} }
tf.protocol |= ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.device |= ATA_LBA; tf.device |= ATA_LBA;
tf.lbal = (new_sectors >> 0) & 0xff; tf.lbal = (new_sectors >> 0) & 0xff;
...@@ -4848,7 +4848,7 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) ...@@ -4848,7 +4848,7 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc)
{ {
struct ata_link *link = qc->dev->link; struct ata_link *link = qc->dev->link;
if (qc->tf.protocol == ATA_PROT_NCQ) { if (ata_is_ncq(qc->tf.protocol)) {
if (!ata_tag_valid(link->active_tag)) if (!ata_tag_valid(link->active_tag))
return 0; return 0;
} else { } else {
...@@ -5013,7 +5013,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) ...@@ -5013,7 +5013,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
ata_sg_clean(qc); ata_sg_clean(qc);
/* command should be marked inactive atomically with qc completion */ /* command should be marked inactive atomically with qc completion */
if (qc->tf.protocol == ATA_PROT_NCQ) { if (ata_is_ncq(qc->tf.protocol)) {
link->sactive &= ~(1 << qc->tag); link->sactive &= ~(1 << qc->tag);
if (!link->sactive) if (!link->sactive)
ap->nr_active_links--; ap->nr_active_links--;
...@@ -5050,7 +5050,7 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) ...@@ -5050,7 +5050,7 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
{ {
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
if (ata_is_nodata(qc->tf.protocol)) if (!ata_is_data(qc->tf.protocol))
return; return;
if ((dev->mwdma_mask || dev->udma_mask) && ata_is_pio(qc->tf.protocol)) if ((dev->mwdma_mask || dev->udma_mask) && ata_is_pio(qc->tf.protocol))
...@@ -5133,7 +5133,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc) ...@@ -5133,7 +5133,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
switch (qc->tf.command) { switch (qc->tf.command) {
case ATA_CMD_SET_FEATURES: case ATA_CMD_SET_FEATURES:
if (qc->tf.feature != SETFEATURES_WC_ON && if (qc->tf.feature != SETFEATURES_WC_ON &&
qc->tf.feature != SETFEATURES_WC_OFF) qc->tf.feature != SETFEATURES_WC_OFF &&
qc->tf.feature != SETFEATURES_RA_ON &&
qc->tf.feature != SETFEATURES_RA_OFF)
break; break;
/* fall through */ /* fall through */
case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
......
...@@ -2607,9 +2607,13 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -2607,9 +2607,13 @@ static void ata_eh_link_report(struct ata_link *link)
[DMA_FROM_DEVICE] = "in", [DMA_FROM_DEVICE] = "in",
}; };
static const char *prot_str[] = { static const char *prot_str[] = {
[ATA_PROT_UNKNOWN] = "unknown",
[ATA_PROT_NODATA] = "nodata",
[ATA_PROT_PIO] = "pio", [ATA_PROT_PIO] = "pio",
[ATA_PROT_DMA] = "dma", [ATA_PROT_DMA] = "dma",
[ATA_PROT_NCQ] = "ncq", [ATA_PROT_NCQ] = "ncq dma",
[ATA_PROT_NCQ_NODATA] = "ncq nodata",
[ATAPI_PROT_NODATA] = "nodata",
[ATAPI_PROT_PIO] = "pio", [ATAPI_PROT_PIO] = "pio",
[ATAPI_PROT_DMA] = "dma", [ATAPI_PROT_DMA] = "dma",
}; };
...@@ -3177,7 +3181,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park) ...@@ -3177,7 +3181,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park)
} }
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol |= ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
if (park && (err_mask || tf.lbal != 0xc4)) { if (park && (err_mask || tf.lbal != 0xc4)) {
ata_dev_err(dev, "head unload failed!\n"); ata_dev_err(dev, "head unload failed!\n");
......
...@@ -304,7 +304,7 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev, ...@@ -304,7 +304,7 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev,
struct scsi_cmnd *cmd, u16 field, u8 bit) struct scsi_cmnd *cmd, u16 field, u8 bit)
{ {
ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */ /* "Invalid field in CDB" */
scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
field, bit, 1); field, bit, 1);
} }
...@@ -2075,8 +2075,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2075,8 +2075,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
0x03, 0x03,
0x20, /* SBC-2 (no version claimed) */ 0x20, /* SBC-2 (no version claimed) */
0x02, 0x03,
0x60 /* SPC-3 (no version claimed) */ 0x00 /* SPC-3 (no version claimed) */
}; };
const u8 versions_zbc[] = { const u8 versions_zbc[] = {
0x00, 0x00,
...@@ -2097,7 +2097,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2097,7 +2097,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
0, 0,
0x5, /* claim SPC-3 version compatibility */ 0x5, /* claim SPC-3 version compatibility */
2, 2,
95 - 4 95 - 4,
0,
0,
2
}; };
VPRINTK("ENTER\n"); VPRINTK("ENTER\n");
...@@ -2109,8 +2112,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2109,8 +2112,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
(args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL)) (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
hdr[1] |= (1 << 7); hdr[1] |= (1 << 7);
if (args->dev->class == ATA_DEV_ZAC) if (args->dev->class == ATA_DEV_ZAC) {
hdr[0] = TYPE_ZBC; hdr[0] = TYPE_ZBC;
hdr[2] = 0x7; /* claim SPC-5 version compatibility */
}
memcpy(rbuf, hdr, sizeof(hdr)); memcpy(rbuf, hdr, sizeof(hdr));
memcpy(&rbuf[8], "ATA ", 8); memcpy(&rbuf[8], "ATA ", 8);
...@@ -2314,7 +2319,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2314,7 +2319,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
* with the unmap bit set. * with the unmap bit set.
*/ */
if (ata_id_has_trim(args->id)) { if (ata_id_has_trim(args->id)) {
put_unaligned_be64(65535 * 512 / 8, &rbuf[36]); put_unaligned_be64(65535 * ATA_MAX_TRIM_RNUM, &rbuf[36]);
put_unaligned_be32(1, &rbuf[28]); put_unaligned_be32(1, &rbuf[28]);
} }
...@@ -2424,15 +2429,17 @@ static void modecpy(u8 *dest, const u8 *src, int n, bool changeable) ...@@ -2424,15 +2429,17 @@ static void modecpy(u8 *dest, const u8 *src, int n, bool changeable)
static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
{ {
modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable); modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable);
if (changeable || ata_id_wcache_enabled(id)) if (changeable) {
buf[2] |= (1 << 2); /* write cache enable */ buf[2] |= (1 << 2); /* ata_mselect_caching() */
if (!changeable && !ata_id_rahead_enabled(id)) } else {
buf[12] |= (1 << 5); /* disable read ahead */ buf[2] |= (ata_id_wcache_enabled(id) << 2); /* write cache enable */
buf[12] |= (!ata_id_rahead_enabled(id) << 5); /* disable read ahead */
}
return sizeof(def_cache_mpage); return sizeof(def_cache_mpage);
} }
/** /**
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page * ata_msense_control - Simulate MODE SENSE control mode page
* @dev: ATA device of interest * @dev: ATA device of interest
* @buf: output buffer * @buf: output buffer
* @changeable: whether changeable parameters are requested * @changeable: whether changeable parameters are requested
...@@ -2442,12 +2449,17 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) ...@@ -2442,12 +2449,17 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
* LOCKING: * LOCKING:
* None. * None.
*/ */
static unsigned int ata_msense_ctl_mode(struct ata_device *dev, u8 *buf, static unsigned int ata_msense_control(struct ata_device *dev, u8 *buf,
bool changeable) bool changeable)
{ {
modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable); modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable);
if (changeable && (dev->flags & ATA_DFLAG_D_SENSE)) if (changeable) {
buf[2] |= (1 << 2); /* Descriptor sense requested */ buf[2] |= (1 << 2); /* ata_mselect_control() */
} else {
bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE);
buf[2] |= (d_sense << 2); /* descriptor format sense data */
}
return sizeof(def_control_mpage); return sizeof(def_control_mpage);
} }
...@@ -2566,13 +2578,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2566,13 +2578,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
break; break;
case CONTROL_MPAGE: case CONTROL_MPAGE:
p += ata_msense_ctl_mode(args->dev, p, page_control == 1); p += ata_msense_control(args->dev, p, page_control == 1);
break; break;
case ALL_MPAGES: case ALL_MPAGES:
p += ata_msense_rw_recovery(p, page_control == 1); p += ata_msense_rw_recovery(p, page_control == 1);
p += ata_msense_caching(args->id, p, page_control == 1); p += ata_msense_caching(args->id, p, page_control == 1);
p += ata_msense_ctl_mode(args->dev, p, page_control == 1); p += ata_msense_control(args->dev, p, page_control == 1);
break; break;
default: /* invalid page code */ default: /* invalid page code */
...@@ -3077,6 +3089,9 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ...@@ -3077,6 +3089,9 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
goto invalid_fld; goto invalid_fld;
} }
if (ata_is_ncq(tf->protocol) && (cdb[2] & 0x3) == 0)
tf->protocol = ATA_PROT_NCQ_NODATA;
/* enable LBA */ /* enable LBA */
tf->flags |= ATA_TFLAG_LBA; tf->flags |= ATA_TFLAG_LBA;
...@@ -3125,8 +3140,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ...@@ -3125,8 +3140,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->command = cdb[9]; tf->command = cdb[9];
} }
/* For NCQ commands with FPDMA protocol, copy the tag value */ /* For NCQ commands copy the tag value */
if (tf->protocol == ATA_PROT_NCQ) if (ata_is_ncq(tf->protocol))
tf->nsect = qc->tag << 3; tf->nsect = qc->tag << 3;
/* enforce correct master/slave bit */ /* enforce correct master/slave bit */
...@@ -3305,7 +3320,13 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) ...@@ -3305,7 +3320,13 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
goto invalid_param_len; goto invalid_param_len;
buf = page_address(sg_page(scsi_sglist(scmd))); buf = page_address(sg_page(scsi_sglist(scmd)));
size = ata_set_lba_range_entries(buf, 512, block, n_block);
if (n_block <= 65535 * ATA_MAX_TRIM_RNUM) {
size = ata_set_lba_range_entries(buf, ATA_MAX_TRIM_RNUM, block, n_block);
} else {
fp = 2;
goto invalid_fld;
}
if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
/* Newer devices support queued TRIM commands */ /* Newer devices support queued TRIM commands */
...@@ -3454,7 +3475,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) ...@@ -3454,7 +3475,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc)
goto invalid_param_len; goto invalid_param_len;
} }
sect = n_block / 512; sect = n_block / 512;
options = cdb[14]; options = cdb[14] & 0xbf;
if (ata_ncq_enabled(qc->dev) && if (ata_ncq_enabled(qc->dev) &&
ata_fpdma_zac_mgmt_in_supported(qc->dev)) { ata_fpdma_zac_mgmt_in_supported(qc->dev)) {
...@@ -3464,7 +3485,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) ...@@ -3464,7 +3485,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc)
tf->nsect = qc->tag << 3; tf->nsect = qc->tag << 3;
tf->feature = sect & 0xff; tf->feature = sect & 0xff;
tf->hob_feature = (sect >> 8) & 0xff; tf->hob_feature = (sect >> 8) & 0xff;
tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES; tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES | (options << 8);
} else { } else {
tf->command = ATA_CMD_ZAC_MGMT_IN; tf->command = ATA_CMD_ZAC_MGMT_IN;
tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES; tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES;
...@@ -3506,7 +3527,7 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) ...@@ -3506,7 +3527,7 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
struct scsi_cmnd *scmd = qc->scsicmd; struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
const u8 *cdb = scmd->cmnd; const u8 *cdb = scmd->cmnd;
u8 reset_all, sa; u8 all, sa;
u64 block; u64 block;
u32 n_block; u32 n_block;
u16 fp = (u16)-1; u16 fp = (u16)-1;
...@@ -3533,20 +3554,20 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) ...@@ -3533,20 +3554,20 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
if (block > dev->n_sectors) if (block > dev->n_sectors)
goto out_of_range; goto out_of_range;
reset_all = cdb[14] & 0x1; all = cdb[14] & 0x1;
if (ata_ncq_enabled(qc->dev) && if (ata_ncq_enabled(qc->dev) &&
ata_fpdma_zac_mgmt_out_supported(qc->dev)) { ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
tf->protocol = ATA_PROT_NCQ; tf->protocol = ATA_PROT_NCQ_NODATA;
tf->command = ATA_CMD_NCQ_NON_DATA; tf->command = ATA_CMD_NCQ_NON_DATA;
tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT; tf->feature = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
tf->nsect = qc->tag << 3; tf->nsect = qc->tag << 3;
tf->auxiliary = sa | (reset_all & 0x1) << 8; tf->auxiliary = sa | ((u16)all << 8);
} else { } else {
tf->protocol = ATA_PROT_NODATA; tf->protocol = ATA_PROT_NODATA;
tf->command = ATA_CMD_ZAC_MGMT_OUT; tf->command = ATA_CMD_ZAC_MGMT_OUT;
tf->feature = sa; tf->feature = sa;
tf->hob_feature = reset_all & 0x1; tf->hob_feature = all;
} }
tf->lbah = (block >> 16) & 0xff; tf->lbah = (block >> 16) & 0xff;
tf->lbam = (block >> 8) & 0xff; tf->lbam = (block >> 8) & 0xff;
...@@ -3667,7 +3688,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, ...@@ -3667,7 +3688,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
/* /*
* Check that read-only bits are not modified. * Check that read-only bits are not modified.
*/ */
ata_msense_ctl_mode(dev, mpage, false); ata_msense_control(dev, mpage, false);
for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) { for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
if (i == 0) if (i == 0)
continue; continue;
...@@ -4039,11 +4060,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ...@@ -4039,11 +4060,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
args.done = cmd->scsi_done; args.done = cmd->scsi_done;
switch(scsicmd[0]) { switch(scsicmd[0]) {
/* TODO: worth improving? */
case FORMAT_UNIT:
ata_scsi_invalid_field(dev, cmd, 0);
break;
case INQUIRY: case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */ if (scsicmd[1] & 2) /* is CmdDt set? */
ata_scsi_invalid_field(dev, cmd, 1); ata_scsi_invalid_field(dev, cmd, 1);
......
...@@ -495,12 +495,13 @@ struct ata_show_ering_arg { ...@@ -495,12 +495,13 @@ struct ata_show_ering_arg {
static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg) static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
{ {
struct ata_show_ering_arg* arg = void_arg; struct ata_show_ering_arg* arg = void_arg;
struct timespec time; u64 seconds;
u32 rem;
jiffies_to_timespec(ent->timestamp,&time); seconds = div_u64_rem(ent->timestamp, HZ, &rem);
arg->written += sprintf(arg->buf + arg->written, arg->written += sprintf(arg->buf + arg->written,
"[%5lu.%06lu]", "[%5llu.%09lu]", seconds,
time.tv_sec, time.tv_nsec); rem * NSEC_PER_SEC / HZ);
arg->written += get_ata_err_names(ent->err_mask, arg->written += get_ata_err_names(ent->err_mask,
arg->buf + arg->written); arg->buf + arg->written);
return 0; return 0;
......
...@@ -565,7 +565,7 @@ static void data_xfer(struct work_struct *work) ...@@ -565,7 +565,7 @@ static void data_xfer(struct work_struct *work)
qc->ap->hsm_task_state = HSM_ST_ERR; qc->ap->hsm_task_state = HSM_ST_ERR;
cf_ctrl_reset(acdev); cf_ctrl_reset(acdev);
spin_unlock_irqrestore(qc->ap->lock, flags); spin_unlock_irqrestore(&acdev->host->lock, flags);
sff_intr: sff_intr:
dma_complete(acdev); dma_complete(acdev);
} }
......
...@@ -183,8 +183,8 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -183,8 +183,8 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* We must now look at the PIO mode situation. We may need to * We must now look at the PIO mode situation. We may need to
* adjust the PIO mode to keep the timings acceptable * adjust the PIO mode to keep the timings acceptable
*/ */
if (adev->dma_mode >= XFER_MW_DMA_2) if (adev->dma_mode >= XFER_MW_DMA_2)
wanted_pio = 4; wanted_pio = 4;
else if (adev->dma_mode == XFER_MW_DMA_1) else if (adev->dma_mode == XFER_MW_DMA_1)
wanted_pio = 3; wanted_pio = 3;
else if (adev->dma_mode == XFER_MW_DMA_0) else if (adev->dma_mode == XFER_MW_DMA_0)
......
...@@ -368,7 +368,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -368,7 +368,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* PCI clocking determines the ATA timing values to use */ /* PCI clocking determines the ATA timing values to use */
/* info_hpt366 is safe against re-entry so we can scribble on it */ /* info_hpt366 is safe against re-entry so we can scribble on it */
switch ((reg1 & 0x700) >> 8) { switch ((reg1 & 0xf00) >> 8) {
case 9: case 9:
hpriv = &hpt366_40; hpriv = &hpt366_40;
break; break;
......
...@@ -146,7 +146,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i ...@@ -146,7 +146,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
if (pdev->device == 0x6101) if (pdev->device == 0x6101)
ppi[1] = &ata_dummy_port_info; ppi[1] = &ata_dummy_port_info;
#if defined(CONFIG_SATA_AHCI) || defined(CONFIG_SATA_AHCI_MODULE) #if IS_ENABLED(CONFIG_SATA_AHCI)
if (!marvell_pata_active(pdev)) { if (!marvell_pata_active(pdev)) {
printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n"); printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n");
return -ENODEV; return -ENODEV;
......
...@@ -259,11 +259,8 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev, ...@@ -259,11 +259,8 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
/* Get physical SATA DMA register base address */ /* Get physical SATA DMA register base address */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
hsdev->dma->regs = devm_ioremap_resource(&pdev->dev, res); hsdev->dma->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hsdev->dma->regs)) { if (IS_ERR(hsdev->dma->regs))
dev_err(&pdev->dev,
"ioremap failed for AHBDMA register address\n");
return PTR_ERR(hsdev->dma->regs); return PTR_ERR(hsdev->dma->regs);
}
/* Initialize AHB DMAC */ /* Initialize AHB DMAC */
return dw_dma_probe(hsdev->dma); return dw_dma_probe(hsdev->dma);
...@@ -281,7 +278,7 @@ static void sata_dwc_dma_exit_old(struct sata_dwc_device *hsdev) ...@@ -281,7 +278,7 @@ static void sata_dwc_dma_exit_old(struct sata_dwc_device *hsdev)
static const char *get_prot_descript(u8 protocol) static const char *get_prot_descript(u8 protocol)
{ {
switch ((enum ata_tf_protocols)protocol) { switch (protocol) {
case ATA_PROT_NODATA: case ATA_PROT_NODATA:
return "ATA no data"; return "ATA no data";
case ATA_PROT_PIO: case ATA_PROT_PIO:
...@@ -290,6 +287,8 @@ static const char *get_prot_descript(u8 protocol) ...@@ -290,6 +287,8 @@ static const char *get_prot_descript(u8 protocol)
return "ATA DMA"; return "ATA DMA";
case ATA_PROT_NCQ: case ATA_PROT_NCQ:
return "ATA NCQ"; return "ATA NCQ";
case ATA_PROT_NCQ_NODATA:
return "ATA NCQ no data";
case ATAPI_PROT_NODATA: case ATAPI_PROT_NODATA:
return "ATAPI no data"; return "ATAPI no data";
case ATAPI_PROT_PIO: case ATAPI_PROT_PIO:
...@@ -1225,11 +1224,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) ...@@ -1225,11 +1224,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
/* Ioremap SATA registers */ /* Ioremap SATA registers */
res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&ofdev->dev, res); base = devm_ioremap_resource(&ofdev->dev, res);
if (IS_ERR(base)) { if (IS_ERR(base))
dev_err(&ofdev->dev,
"ioremap failed for SATA register address\n");
return PTR_ERR(base); return PTR_ERR(base);
}
dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n"); dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n");
/* Synopsys DWC SATA specific Registers */ /* Synopsys DWC SATA specific Registers */
......
...@@ -45,6 +45,7 @@ enum brcm_sata_phy_version { ...@@ -45,6 +45,7 @@ enum brcm_sata_phy_version {
BRCM_SATA_PHY_STB_28NM, BRCM_SATA_PHY_STB_28NM,
BRCM_SATA_PHY_STB_40NM, BRCM_SATA_PHY_STB_40NM,
BRCM_SATA_PHY_IPROC_NS2, BRCM_SATA_PHY_IPROC_NS2,
BRCM_SATA_PHY_IPROC_NSP,
}; };
struct brcm_sata_port { struct brcm_sata_port {
...@@ -73,6 +74,13 @@ enum sata_phy_regs { ...@@ -73,6 +74,13 @@ enum sata_phy_regs {
PLL_REG_BANK_0 = 0x050, PLL_REG_BANK_0 = 0x050,
PLL_REG_BANK_0_PLLCONTROL_0 = 0x81, PLL_REG_BANK_0_PLLCONTROL_0 = 0x81,
PLLCONTROL_0_FREQ_DET_RESTART = BIT(13),
PLLCONTROL_0_FREQ_MONITOR = BIT(12),
PLLCONTROL_0_SEQ_START = BIT(15),
PLL_CAP_CONTROL = 0x85,
PLL_ACTRL2 = 0x8b,
PLL_ACTRL2_SELDIV_MASK = 0x1f,
PLL_ACTRL2_SELDIV_SHIFT = 9,
PLL1_REG_BANK = 0x060, PLL1_REG_BANK = 0x060,
PLL1_ACTRL2 = 0x82, PLL1_ACTRL2 = 0x82,
...@@ -80,6 +88,7 @@ enum sata_phy_regs { ...@@ -80,6 +88,7 @@ enum sata_phy_regs {
PLL1_ACTRL4 = 0x84, PLL1_ACTRL4 = 0x84,
OOB_REG_BANK = 0x150, OOB_REG_BANK = 0x150,
OOB1_REG_BANK = 0x160,
OOB_CTRL1 = 0x80, OOB_CTRL1 = 0x80,
OOB_CTRL1_BURST_MAX_MASK = 0xf, OOB_CTRL1_BURST_MAX_MASK = 0xf,
OOB_CTRL1_BURST_MAX_SHIFT = 12, OOB_CTRL1_BURST_MAX_SHIFT = 12,
...@@ -271,6 +280,73 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port) ...@@ -271,6 +280,73 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port)
return 0; return 0;
} }
static int brcm_nsp_sata_init(struct brcm_sata_port *port)
{
struct brcm_sata_phy *priv = port->phy_priv;
struct device *dev = port->phy_priv->dev;
void __iomem *base = priv->phy_base;
unsigned int oob_bank;
unsigned int val, try;
/* Configure OOB control */
if (port->portnum == 0)
oob_bank = OOB_REG_BANK;
else if (port->portnum == 1)
oob_bank = OOB1_REG_BANK;
else
return -EINVAL;
val = 0x0;
val |= (0x0f << OOB_CTRL1_BURST_MAX_SHIFT);
val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT);
val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
brcm_sata_phy_wr(base, oob_bank, OOB_CTRL1, 0x0, val);
val = 0x0;
val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT);
val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
brcm_sata_phy_wr(base, oob_bank, OOB_CTRL2, 0x0, val);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL2,
~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT),
0x0c << PLL_ACTRL2_SELDIV_SHIFT);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CONTROL,
0xff0, 0x4f0);
val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR;
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
~val, val);
val = PLLCONTROL_0_SEQ_START;
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
~val, 0);
mdelay(10);
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
~val, val);
/* Wait for pll_seq_done bit */
try = 50;
while (try--) {
val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS);
if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
break;
msleep(20);
}
if (!try) {
/* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum);
return -ETIMEDOUT;
}
dev_dbg(dev, "port%d initialized\n", port->portnum);
return 0;
}
static int brcm_sata_phy_init(struct phy *phy) static int brcm_sata_phy_init(struct phy *phy)
{ {
int rc; int rc;
...@@ -284,6 +360,9 @@ static int brcm_sata_phy_init(struct phy *phy) ...@@ -284,6 +360,9 @@ static int brcm_sata_phy_init(struct phy *phy)
case BRCM_SATA_PHY_IPROC_NS2: case BRCM_SATA_PHY_IPROC_NS2:
rc = brcm_ns2_sata_init(port); rc = brcm_ns2_sata_init(port);
break; break;
case BRCM_SATA_PHY_IPROC_NSP:
rc = brcm_nsp_sata_init(port);
break;
default: default:
rc = -ENODEV; rc = -ENODEV;
}; };
...@@ -303,6 +382,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = { ...@@ -303,6 +382,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = {
.data = (void *)BRCM_SATA_PHY_STB_40NM }, .data = (void *)BRCM_SATA_PHY_STB_40NM },
{ .compatible = "brcm,iproc-ns2-sata-phy", { .compatible = "brcm,iproc-ns2-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_NS2 }, .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
{ .compatible = "brcm,iproc-nsp-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_NSP },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
......
...@@ -233,15 +233,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) ...@@ -233,15 +233,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
task->task_state_flags = SAS_TASK_STATE_PENDING; task->task_state_flags = SAS_TASK_STATE_PENDING;
qc->lldd_task = task; qc->lldd_task = task;
switch (qc->tf.protocol) { task->ata_task.use_ncq = ata_is_ncq(qc->tf.protocol);
case ATA_PROT_NCQ: task->ata_task.dma_xfer = ata_is_dma(qc->tf.protocol);
task->ata_task.use_ncq = 1;
/* fall through */
case ATAPI_PROT_DMA:
case ATA_PROT_DMA:
task->ata_task.dma_xfer = 1;
break;
}
if (qc->scsicmd) if (qc->scsicmd)
ASSIGN_SAS_TASK(qc->scsicmd, task); ASSIGN_SAS_TASK(qc->scsicmd, task);
......
...@@ -46,8 +46,9 @@ enum { ...@@ -46,8 +46,9 @@ enum {
ATA_MAX_SECTORS_128 = 128, ATA_MAX_SECTORS_128 = 128,
ATA_MAX_SECTORS = 256, ATA_MAX_SECTORS = 256,
ATA_MAX_SECTORS_1024 = 1024, ATA_MAX_SECTORS_1024 = 1024,
ATA_MAX_SECTORS_LBA48 = 65535,/* TODO: 65536? */ ATA_MAX_SECTORS_LBA48 = 65535,/* avoid count to be 0000h */
ATA_MAX_SECTORS_TAPE = 65535, ATA_MAX_SECTORS_TAPE = 65535,
ATA_MAX_TRIM_RNUM = 64, /* 512-byte payload / (6-byte LBA + 2-byte range per entry) */
ATA_ID_WORDS = 256, ATA_ID_WORDS = 256,
ATA_ID_CONFIG = 0, ATA_ID_CONFIG = 0,
...@@ -409,6 +410,9 @@ enum { ...@@ -409,6 +410,9 @@ enum {
SETFEATURES_WC_ON = 0x02, /* Enable write cache */ SETFEATURES_WC_ON = 0x02, /* Enable write cache */
SETFEATURES_WC_OFF = 0x82, /* Disable write cache */ SETFEATURES_WC_OFF = 0x82, /* Disable write cache */
SETFEATURES_RA_ON = 0xaa, /* Enable read look-ahead */
SETFEATURES_RA_OFF = 0x55, /* Disable read look-ahead */
/* Enable/Disable Automatic Acoustic Management */ /* Enable/Disable Automatic Acoustic Management */
SETFEATURES_AAM_ON = 0x42, SETFEATURES_AAM_ON = 0x42,
SETFEATURES_AAM_OFF = 0xC2, SETFEATURES_AAM_OFF = 0xC2,
...@@ -519,16 +523,23 @@ enum { ...@@ -519,16 +523,23 @@ enum {
SERR_DEV_XCHG = (1 << 26), /* device exchanged */ SERR_DEV_XCHG = (1 << 26), /* device exchanged */
}; };
enum ata_tf_protocols { enum ata_prot_flags {
/* ATA taskfile protocols */ /* protocol flags */
ATA_PROT_UNKNOWN, /* unknown/invalid */ ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
ATA_PROT_NODATA, /* no data */ ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
ATA_PROT_PIO, /* PIO data xfer */ ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
ATA_PROT_DMA, /* DMA */ ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
ATA_PROT_NCQ, /* NCQ */
ATAPI_PROT_NODATA, /* packet command, no data */ /* taskfile protocols */
ATAPI_PROT_PIO, /* packet command, PIO data xfer*/ ATA_PROT_UNKNOWN = (u8)-1,
ATAPI_PROT_DMA, /* packet command with special DMA sauce */ ATA_PROT_NODATA = 0,
ATA_PROT_PIO = ATA_PROT_FLAG_PIO,
ATA_PROT_DMA = ATA_PROT_FLAG_DMA,
ATA_PROT_NCQ_NODATA = ATA_PROT_FLAG_NCQ,
ATA_PROT_NCQ = ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ,
ATAPI_PROT_NODATA = ATA_PROT_FLAG_ATAPI,
ATAPI_PROT_PIO = ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO,
ATAPI_PROT_DMA = ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA,
}; };
enum ata_ioctls { enum ata_ioctls {
...@@ -1066,12 +1077,12 @@ static inline void ata_id_to_hd_driveid(u16 *id) ...@@ -1066,12 +1077,12 @@ static inline void ata_id_to_hd_driveid(u16 *id)
* TO NV CACHE PINNED SET. * TO NV CACHE PINNED SET.
*/ */
static inline unsigned ata_set_lba_range_entries(void *_buffer, static inline unsigned ata_set_lba_range_entries(void *_buffer,
unsigned buf_size, u64 sector, unsigned long count) unsigned num, u64 sector, unsigned long count)
{ {
__le64 *buffer = _buffer; __le64 *buffer = _buffer;
unsigned i = 0, used_bytes; unsigned i = 0, used_bytes;
while (i < buf_size / 8 ) { /* 6-byte LBA + 2-byte range per entry */ while (i < num) {
u64 entry = sector | u64 entry = sector |
((u64)(count > 0xffff ? 0xffff : count) << 48); ((u64)(count > 0xffff ? 0xffff : count) << 48);
buffer[i++] = __cpu_to_le64(entry); buffer[i++] = __cpu_to_le64(entry);
...@@ -1095,13 +1106,13 @@ static inline bool ata_ok(u8 status) ...@@ -1095,13 +1106,13 @@ static inline bool ata_ok(u8 status)
static inline bool lba_28_ok(u64 block, u32 n_block) static inline bool lba_28_ok(u64 block, u32 n_block)
{ {
/* check the ending block number: must be LESS THAN 0x0fffffff */ /* check the ending block number: must be LESS THAN 0x0fffffff */
return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256); return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= ATA_MAX_SECTORS);
} }
static inline bool lba_48_ok(u64 block, u32 n_block) static inline bool lba_48_ok(u64 block, u32 n_block)
{ {
/* check the ending block number */ /* check the ending block number */
return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= ATA_MAX_SECTORS_LBA48);
} }
#define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff) #define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
......
...@@ -146,13 +146,6 @@ enum { ...@@ -146,13 +146,6 @@ enum {
ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
/* protocol flags */
ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
/* struct ata_device stuff */ /* struct ata_device stuff */
ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */
ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
...@@ -1039,58 +1032,29 @@ extern const unsigned long sata_deb_timing_long[]; ...@@ -1039,58 +1032,29 @@ extern const unsigned long sata_deb_timing_long[];
extern struct ata_port_operations ata_dummy_port_ops; extern struct ata_port_operations ata_dummy_port_ops;
extern const struct ata_port_info ata_dummy_port_info; extern const struct ata_port_info ata_dummy_port_info;
/* static inline bool ata_is_atapi(u8 prot)
* protocol tests
*/
static inline unsigned int ata_prot_flags(u8 prot)
{
switch (prot) {
case ATA_PROT_NODATA:
return 0;
case ATA_PROT_PIO:
return ATA_PROT_FLAG_PIO;
case ATA_PROT_DMA:
return ATA_PROT_FLAG_DMA;
case ATA_PROT_NCQ:
return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
case ATAPI_PROT_NODATA:
return ATA_PROT_FLAG_ATAPI;
case ATAPI_PROT_PIO:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
case ATAPI_PROT_DMA:
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
}
return 0;
}
static inline int ata_is_atapi(u8 prot)
{
return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
}
static inline int ata_is_nodata(u8 prot)
{ {
return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA); return prot & ATA_PROT_FLAG_ATAPI;
} }
static inline int ata_is_pio(u8 prot) static inline bool ata_is_pio(u8 prot)
{ {
return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO; return prot & ATA_PROT_FLAG_PIO;
} }
static inline int ata_is_dma(u8 prot) static inline bool ata_is_dma(u8 prot)
{ {
return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA; return prot & ATA_PROT_FLAG_DMA;
} }
static inline int ata_is_ncq(u8 prot) static inline bool ata_is_ncq(u8 prot)
{ {
return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ; return prot & ATA_PROT_FLAG_NCQ;
} }
static inline int ata_is_data(u8 prot) static inline bool ata_is_data(u8 prot)
{ {
return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA; return prot & (ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA);
} }
static inline int is_multi_taskfile(struct ata_taskfile *tf) static inline int is_multi_taskfile(struct ata_taskfile *tf)
...@@ -1407,7 +1371,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap) ...@@ -1407,7 +1371,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
return ap->nr_pmp_links != 0; return ap->nr_pmp_links != 0;
} }
static inline int ata_is_host_link(const struct ata_link *link) static inline bool ata_is_host_link(const struct ata_link *link)
{ {
return link == &link->ap->link || link == link->ap->slave_link; return link == &link->ap->link || link == link->ap->slave_link;
} }
...@@ -1422,7 +1386,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap) ...@@ -1422,7 +1386,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
return false; return false;
} }
static inline int ata_is_host_link(const struct ata_link *link) static inline bool ata_is_host_link(const struct ata_link *link)
{ {
return 1; return 1;
} }
......
...@@ -126,6 +126,7 @@ ...@@ -126,6 +126,7 @@
ata_protocol_name(ATA_PROT_PIO), \ ata_protocol_name(ATA_PROT_PIO), \
ata_protocol_name(ATA_PROT_DMA), \ ata_protocol_name(ATA_PROT_DMA), \
ata_protocol_name(ATA_PROT_NCQ), \ ata_protocol_name(ATA_PROT_NCQ), \
ata_protocol_name(ATA_PROT_NCQ_NODATA), \
ata_protocol_name(ATAPI_PROT_NODATA), \ ata_protocol_name(ATAPI_PROT_NODATA), \
ata_protocol_name(ATAPI_PROT_PIO), \ ata_protocol_name(ATAPI_PROT_PIO), \
ata_protocol_name(ATAPI_PROT_DMA)) ata_protocol_name(ATAPI_PROT_DMA))
......
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