Commit 109a5db5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull libata updates from Tejun Heo:

 - Christoph added support for TCG OPAL self encrypting disks

 - Minwoo added support for ATA PASS-THROUGH(32)

 - Linus Walleij removed spurious drvdata assignments in some drivers

 - Support for a few new device and other fixes

* 'for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (33 commits)
  sd: add support for TCG OPAL self encrypting disks
  libata: fix build warning from unused goto label
  libata: Support for an ATA PASS-THROUGH(32) command.
  ahci: Add Device ID for ASMedia 1061R and 1062R
  sata_via: Enable optional hotplug on VT6420
  ata: ahci_brcm: Avoid writing to read-only registers
  libata: Add the AHCI_HFLAG_NO_WRITE_TO_RO flag
  libata: Add the AHCI_HFLAG_YES_ALPM flag
  ata: ftide010: fix resource printing
  libata: make the function name in comment match the actual function
  ata: sata_rcar: make of_device_ids const.
  ata: pata_octeon_cf: make of_device_ids const.
  libata: Convert bare printks to pr_cont
  libahci: wrong comments in ahci_do_softreset()
  ata: declare ata_port_info structures as const
  ata: Add driver for Faraday Technology FTIDE010
  ata: Add DT bindings for the Gemini SATA bridge
  ata: Add DT bindings for Faraday Technology FTIDE010
  libata: implement SECURITY PROTOCOL IN/OUT
  libata: factor out a ata_identify_page_supported helper
  ...
parents a4c20b9a d80210f2
* Cortina Systems Gemini SATA Bridge
The Gemini SATA bridge in a SoC-internal PATA to SATA bridge that
takes two Faraday Technology FTIDE010 PATA controllers and bridges
them in different configurations to two SATA ports.
Required properties:
- compatible: should be
"cortina,gemini-sata-bridge"
- reg: registers and size for the block
- resets: phandles to the reset lines for both SATA bridges
- reset-names: must be "sata0", "sata1"
- clocks: phandles to the compulsory peripheral clocks
- clock-names: must be "SATA0_PCLK", "SATA1_PCLK"
- syscon: a phandle to the global Gemini system controller
- cortina,gemini-ata-muxmode: tell the desired multiplexing mode for
the ATA controller and SATA bridges. Values 0..3:
Mode 0: ata0 master <-> sata0
ata1 master <-> sata1
ata0 slave interface brought out on IDE pads
Mode 1: ata0 master <-> sata0
ata1 master <-> sata1
ata1 slave interface brought out on IDE pads
Mode 2: ata1 master <-> sata1
ata1 slave <-> sata0
ata0 master and slave interfaces brought out
on IDE pads
Mode 3: ata0 master <-> sata0
ata0 slave <-> sata1
ata1 master and slave interfaces brought out
on IDE pads
Optional boolean properties:
- cortina,gemini-enable-ide-pins: enables the PATA to IDE connection.
The muxmode setting decides whether ATA0 or ATA1 is brought out,
and whether master, slave or both interfaces get brought out.
- cortina,gemini-enable-sata-bridge: enables the PATA to SATA bridge
inside the Gemnini SoC. The Muxmode decides what PATA blocks will
be muxed out and how.
Example:
sata: sata@46000000 {
compatible = "cortina,gemini-sata-bridge";
reg = <0x46000000 0x100>;
resets = <&rcon 26>, <&rcon 27>;
reset-names = "sata0", "sata1";
clocks = <&gcc GEMINI_CLK_GATE_SATA0>,
<&gcc GEMINI_CLK_GATE_SATA1>;
clock-names = "SATA0_PCLK", "SATA1_PCLK";
syscon = <&syscon>;
cortina,gemini-ata-muxmode = <3>;
cortina,gemini-enable-ide-pins;
cortina,gemini-enable-sata-bridge;
};
* Faraday Technology FTIDE010 PATA controller
This controller is the first Faraday IDE interface block, used in the
StorLink SL2312 and SL3516, later known as the Cortina Systems Gemini
platform. The controller can do PIO modes 0 through 4, Multi-word DMA
(MWDM)modes 0 through 2 and Ultra DMA modes 0 through 6.
On the Gemini platform, this PATA block is accompanied by a PATA to
SATA bridge in order to support SATA. This is why a phandle to that
controller is compulsory on that platform.
The timing properties are unique per-SoC, not per-board.
Required properties:
- compatible: should be one of
"cortina,gemini-pata", "faraday,ftide010"
"faraday,ftide010"
- interrupts: interrupt for the block
- reg: registers and size for the block
Optional properties:
- clocks: a SoC clock running the peripheral.
- clock-names: should be set to "PCLK" for the peripheral clock.
Required properties for "cortina,gemini-pata" compatible:
- sata: a phande to the Gemini PATA to SATA bridge, see
cortina,gemini-sata-bridge.txt for details.
Example:
ata@63000000 {
compatible = "cortina,gemini-pata", "faraday,ftide010";
reg = <0x63000000 0x100>;
interrupts = <4 IRQ_TYPE_EDGE_RISING>;
clocks = <&gcc GEMINI_CLK_GATE_IDE>;
clock-names = "PCLK";
sata = <&sata>;
};
......@@ -7593,6 +7593,15 @@ S: Maintained
F: drivers/ata/pata_*.c
F: drivers/ata/ata_generic.c
LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-ide@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
S: Maintained
F: drivers/ata/pata_ftide010.c
F: drivers/ata/sata_gemini.c
F: drivers/ata/sata_gemini.h
LIBATA SATA AHCI PLATFORM devices support
M: Hans de Goede <hdegoede@redhat.com>
M: Tejun Heo <tj@kernel.org>
......
......@@ -213,6 +213,16 @@ config SATA_FSL
If unsure, say N.
config SATA_GEMINI
tristate "Gemini SATA bridge support"
depends on PATA_FTIDE010
default ARCH_GEMINI
help
This enabled support for the FTIDE010 to SATA bridge
found in Cortina Systems Gemini platform.
If unsure, say N.
config SATA_AHCI_SEATTLE
tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support"
depends on ARCH_SEATTLE
......@@ -599,6 +609,17 @@ config PATA_EP93XX
If unsure, say N.
config PATA_FTIDE010
tristate "Faraday Technology FTIDE010 PATA support"
depends on OF
depends on ARM
default ARCH_GEMINI
help
This option enables support for the Faraday FTIDE010
PATA controller found in the Cortina Gemini SoCs.
If unsure, say N.
config PATA_HPT366
tristate "HPT 366/368 PATA support"
depends on PCI
......
......@@ -7,6 +7,7 @@ obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_GEMINI) += sata_gemini.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
......@@ -60,6 +61,7 @@ obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o
obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
obj-$(CONFIG_PATA_EFAR) += pata_efar.o
obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o
obj-$(CONFIG_PATA_FTIDE010) += pata_ftide010.o
obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
......
......@@ -548,6 +548,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */
{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */
{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */
{ PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */
{ PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */
/*
* Samsung SSDs found on some macbooks. NCQ times out if MSI is
......
......@@ -248,6 +248,9 @@ enum {
AHCI_HFLAG_MULTI_MSI = 0,
#endif
AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */
AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */
AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read
only registers */
/* ap->flags bits */
......
......@@ -39,7 +39,6 @@
#define PIODATA_ENDIAN_SHIFT 6
#define ENDIAN_SWAP_NONE 0
#define ENDIAN_SWAP_FULL 2
#define OVERRIDE_HWINIT BIT(16)
#define SATA_TOP_CTRL_TP_CTRL 0x8
#define SATA_TOP_CTRL_PHY_CTRL 0xc
#define SATA_TOP_CTRL_PHY_CTRL_1 0x0
......@@ -126,17 +125,13 @@ static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
{
struct brcm_ahci_priv *priv = hpriv->plat_data;
u32 bus_ctrl, port_ctrl, host_caps;
u32 port_ctrl, host_caps;
int i;
/* Enable support for ALPM */
bus_ctrl = brcm_sata_readreg(priv->top_ctrl +
SATA_TOP_CTRL_BUS_CTRL);
brcm_sata_writereg(bus_ctrl | OVERRIDE_HWINIT,
priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
host_caps = readl(hpriv->mmio + HOST_CAP);
writel(host_caps | HOST_CAP_ALPM, hpriv->mmio);
brcm_sata_writereg(bus_ctrl, priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
if (!(host_caps & HOST_CAP_ALPM))
hpriv->flags |= AHCI_HFLAG_YES_ALPM;
/*
* Adjust timeout to allow PLL sufficient time to lock while waking
......@@ -360,6 +355,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ)
hpriv->flags |= AHCI_HFLAG_NO_NCQ;
hpriv->flags |= AHCI_HFLAG_NO_WRITE_TO_RO;
ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
&ahci_platform_sht);
......
......@@ -47,12 +47,14 @@
#define SATA_ECC_DISABLE 0x00020000
#define ECC_DIS_ARMV8_CH2 0x80000000
#define ECC_DIS_LS1088A 0x40000000
enum ahci_qoriq_type {
AHCI_LS1021A,
AHCI_LS1043A,
AHCI_LS2080A,
AHCI_LS1046A,
AHCI_LS1088A,
AHCI_LS2088A,
};
......@@ -68,6 +70,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
{ .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
{ .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
{ .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
{ .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
{},
};
......@@ -203,6 +206,17 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
case AHCI_LS1088A:
if (!qpriv->ecc_addr)
return -EINVAL;
writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
qpriv->ecc_addr);
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
if (qpriv->is_dmacoherent)
writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
break;
case AHCI_LS2088A:
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
......
......@@ -504,6 +504,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
cap &= ~HOST_CAP_FBS;
}
if (!(cap & HOST_CAP_ALPM) && (hpriv->flags & AHCI_HFLAG_YES_ALPM)) {
dev_info(dev, "controller can do ALPM, turning on CAP_ALPM\n");
cap |= HOST_CAP_ALPM;
}
if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
port_map, hpriv->force_port_map);
......@@ -940,7 +945,8 @@ int ahci_reset_controller(struct ata_host *host)
/* Some registers might be cleared on reset. Restore
* initial values.
*/
ahci_restore_initial_config(host);
if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO))
ahci_restore_initial_config(host);
} else
dev_info(host->dev, "skipping global host reset\n");
......@@ -1400,7 +1406,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
ata_tf_init(link->device, &tf);
/* issue the first D2H Register FIS */
/* issue the first H2D Register FIS */
msecs = 0;
now = jiffies;
if (time_after(deadline, now))
......@@ -1417,7 +1423,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
/* spec says at least 5us, but be generous and sleep for 1ms */
ata_msleep(ap, 1);
/* issue the second D2H Register FIS */
/* issue the second H2D Register FIS */
tf.ctl &= ~ATA_SRST;
ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0);
......
......@@ -2047,6 +2047,110 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
return rc;
}
/**
* ata_read_log_page - read a specific log page
* @dev: target device
* @log: log to read
* @page: page to read
* @buf: buffer to store read page
* @sectors: number of sectors to read
*
* Read log page using READ_LOG_EXT command.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0 on success, AC_ERR_* mask otherwise.
*/
unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
u8 page, void *buf, unsigned int sectors)
{
unsigned long ap_flags = dev->link->ap->flags;
struct ata_taskfile tf;
unsigned int err_mask;
bool dma = false;
DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);
/*
* Return error without actually issuing the command on controllers
* which e.g. lockup on a read log page.
*/
if (ap_flags & ATA_FLAG_NO_LOG_PAGE)
return AC_ERR_DEV;
retry:
ata_tf_init(dev, &tf);
if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) &&
!(dev->horkage & ATA_HORKAGE_NO_NCQ_LOG)) {
tf.command = ATA_CMD_READ_LOG_DMA_EXT;
tf.protocol = ATA_PROT_DMA;
dma = true;
} else {
tf.command = ATA_CMD_READ_LOG_EXT;
tf.protocol = ATA_PROT_PIO;
dma = false;
}
tf.lbal = log;
tf.lbam = page;
tf.nsect = sectors;
tf.hob_nsect = sectors >> 8;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
buf, sectors * ATA_SECT_SIZE, 0);
if (err_mask && dma) {
dev->horkage |= ATA_HORKAGE_NO_NCQ_LOG;
ata_dev_warn(dev, "READ LOG DMA EXT failed, trying unqueued\n");
goto retry;
}
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
}
static bool ata_log_supported(struct ata_device *dev, u8 log)
{
struct ata_port *ap = dev->link->ap;
if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1))
return false;
return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false;
}
static bool ata_identify_page_supported(struct ata_device *dev, u8 page)
{
struct ata_port *ap = dev->link->ap;
unsigned int err, i;
if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE)) {
ata_dev_warn(dev, "ATA Identify Device Log not supported\n");
return false;
}
/*
* Read IDENTIFY DEVICE data log, page 0, to figure out if the page is
* supported.
*/
err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, ap->sector_buf,
1);
if (err) {
ata_dev_info(dev,
"failed to get Device Identify Log Emask 0x%x\n",
err);
return false;
}
for (i = 0; i < ap->sector_buf[8]; i++) {
if (ap->sector_buf[9 + i] == page)
return true;
}
return false;
}
static int ata_do_link_spd_horkage(struct ata_device *dev)
{
struct ata_link *plink = ata_dev_phys_link(dev);
......@@ -2094,21 +2198,9 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev)
{
struct ata_port *ap = dev->link->ap;
unsigned int err_mask;
int log_index = ATA_LOG_NCQ_SEND_RECV * 2;
u16 log_pages;
err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
0, ap->sector_buf, 1);
if (err_mask) {
ata_dev_dbg(dev,
"failed to get Log Directory Emask 0x%x\n",
err_mask);
return;
}
log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
if (!log_pages) {
ata_dev_warn(dev,
"NCQ Send/Recv Log not supported\n");
if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) {
ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n");
return;
}
err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
......@@ -2135,19 +2227,8 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
{
struct ata_port *ap = dev->link->ap;
unsigned int err_mask;
int log_index = ATA_LOG_NCQ_NON_DATA * 2;
u16 log_pages;
err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
0, ap->sector_buf, 1);
if (err_mask) {
ata_dev_dbg(dev,
"failed to get Log Directory Emask 0x%x\n",
err_mask);
return;
}
log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
if (!log_pages) {
if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) {
ata_dev_warn(dev,
"NCQ Send/Recv Log not supported\n");
return;
......@@ -2176,7 +2257,7 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
}
err_mask = ata_read_log_page(dev,
ATA_LOG_SATA_ID_DEV_DATA,
ATA_LOG_IDENTIFY_DEVICE,
ATA_LOG_SATA_SETTINGS,
ap->sector_buf,
1);
......@@ -2275,8 +2356,6 @@ static void ata_dev_config_zac(struct ata_device *dev)
struct ata_port *ap = dev->link->ap;
unsigned int err_mask;
u8 *identify_buf = ap->sector_buf;
int log_index = ATA_LOG_SATA_ID_DEV_DATA * 2, i, found = 0;
u16 log_pages;
dev->zac_zones_optimal_open = U32_MAX;
dev->zac_zones_optimal_nonseq = U32_MAX;
......@@ -2296,44 +2375,7 @@ static void ata_dev_config_zac(struct ata_device *dev)
if (!(dev->flags & ATA_DFLAG_ZAC))
return;
/*
* Read Log Directory to figure out if IDENTIFY DEVICE log
* is supported.
*/
err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
0, ap->sector_buf, 1);
if (err_mask) {
ata_dev_info(dev,
"failed to get Log Directory Emask 0x%x\n",
err_mask);
return;
}
log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
if (log_pages == 0) {
ata_dev_warn(dev,
"ATA Identify Device Log not supported\n");
return;
}
/*
* Read IDENTIFY DEVICE data log, page 0, to figure out
* if page 9 is supported.
*/
err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA, 0,
identify_buf, 1);
if (err_mask) {
ata_dev_info(dev,
"failed to get Device Identify Log Emask 0x%x\n",
err_mask);
return;
}
log_pages = identify_buf[8];
for (i = 0; i < log_pages; i++) {
if (identify_buf[9 + i] == ATA_LOG_ZONED_INFORMATION) {
found++;
break;
}
}
if (!found) {
if (!ata_identify_page_supported(dev, ATA_LOG_ZONED_INFORMATION)) {
ata_dev_warn(dev,
"ATA Zoned Information Log not supported\n");
return;
......@@ -2342,7 +2384,7 @@ static void ata_dev_config_zac(struct ata_device *dev)
/*
* Read IDENTIFY DEVICE data log, page 9 (Zoned-device information)
*/
err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA,
err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE,
ATA_LOG_ZONED_INFORMATION,
identify_buf, 1);
if (!err_mask) {
......@@ -2363,6 +2405,37 @@ static void ata_dev_config_zac(struct ata_device *dev)
}
}
static void ata_dev_config_trusted(struct ata_device *dev)
{
struct ata_port *ap = dev->link->ap;
u64 trusted_cap;
unsigned int err;
if (!ata_identify_page_supported(dev, ATA_LOG_SECURITY)) {
ata_dev_warn(dev,
"Security Log not supported\n");
return;
}
err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SECURITY,
ap->sector_buf, 1);
if (err) {
ata_dev_dbg(dev,
"failed to read Security Log, Emask 0x%x\n", err);
return;
}
trusted_cap = get_unaligned_le64(&ap->sector_buf[40]);
if (!(trusted_cap & (1ULL << 63))) {
ata_dev_dbg(dev,
"Trusted Computing capability qword not valid!\n");
return;
}
if (trusted_cap & (1 << 0))
dev->flags |= ATA_DFLAG_TRUSTED;
}
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
* @dev: Target device to configure
......@@ -2571,7 +2644,7 @@ int ata_dev_configure(struct ata_device *dev)
dev->flags |= ATA_DFLAG_DEVSLP;
err_mask = ata_read_log_page(dev,
ATA_LOG_SATA_ID_DEV_DATA,
ATA_LOG_IDENTIFY_DEVICE,
ATA_LOG_SATA_SETTINGS,
sata_setting,
1);
......@@ -2587,7 +2660,8 @@ int ata_dev_configure(struct ata_device *dev)
}
ata_dev_config_sense_reporting(dev);
ata_dev_config_zac(dev);
dev->cdb_len = 16;
ata_dev_config_trusted(dev);
dev->cdb_len = 32;
}
/* ATAPI-specific feature tests */
......
......@@ -1487,70 +1487,6 @@ static const char *ata_err_string(unsigned int err_mask)
return "unknown error";
}
/**
* ata_read_log_page - read a specific log page
* @dev: target device
* @log: log to read
* @page: page to read
* @buf: buffer to store read page
* @sectors: number of sectors to read
*
* Read log page using READ_LOG_EXT command.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0 on success, AC_ERR_* mask otherwise.
*/
unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
u8 page, void *buf, unsigned int sectors)
{
unsigned long ap_flags = dev->link->ap->flags;
struct ata_taskfile tf;
unsigned int err_mask;
bool dma = false;
DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);
/*
* Return error without actually issuing the command on controllers
* which e.g. lockup on a read log page.
*/
if (ap_flags & ATA_FLAG_NO_LOG_PAGE)
return AC_ERR_DEV;
retry:
ata_tf_init(dev, &tf);
if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) &&
!(dev->horkage & ATA_HORKAGE_NO_NCQ_LOG)) {
tf.command = ATA_CMD_READ_LOG_DMA_EXT;
tf.protocol = ATA_PROT_DMA;
dma = true;
} else {
tf.command = ATA_CMD_READ_LOG_EXT;
tf.protocol = ATA_PROT_PIO;
dma = false;
}
tf.lbal = log;
tf.lbam = page;
tf.nsect = sectors;
tf.hob_nsect = sectors >> 8;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
buf, sectors * ATA_SECT_SIZE, 0);
if (err_mask && dma) {
dev->horkage |= ATA_HORKAGE_NO_NCQ_LOG;
ata_dev_warn(dev, "READ LOG DMA EXT failed, trying unqueued\n");
goto retry;
}
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
}
/**
* ata_eh_read_log_10h - Read log page 10h for NCQ error details
* @dev: Device to read log page 10h from
......
......@@ -903,32 +903,32 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
{
u8 stat = tf->command, err = tf->feature;
printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
pr_warn("ata%u: status=0x%02x { ", id, stat);
if (stat & ATA_BUSY) {
printk("Busy }\n"); /* Data is not valid in this case */
pr_cont("Busy }\n"); /* Data is not valid in this case */
} else {
if (stat & ATA_DRDY) printk("DriveReady ");
if (stat & ATA_DF) printk("DeviceFault ");
if (stat & ATA_DSC) printk("SeekComplete ");
if (stat & ATA_DRQ) printk("DataRequest ");
if (stat & ATA_CORR) printk("CorrectedError ");
if (stat & ATA_SENSE) printk("Sense ");
if (stat & ATA_ERR) printk("Error ");
printk("}\n");
if (stat & ATA_DRDY) pr_cont("DriveReady ");
if (stat & ATA_DF) pr_cont("DeviceFault ");
if (stat & ATA_DSC) pr_cont("SeekComplete ");
if (stat & ATA_DRQ) pr_cont("DataRequest ");
if (stat & ATA_CORR) pr_cont("CorrectedError ");
if (stat & ATA_SENSE) pr_cont("Sense ");
if (stat & ATA_ERR) pr_cont("Error ");
pr_cont("}\n");
if (err) {
printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
if (err & ATA_ABORTED) printk("DriveStatusError ");
pr_warn("ata%u: error=0x%02x { ", id, err);
if (err & ATA_ABORTED) pr_cont("DriveStatusError ");
if (err & ATA_ICRC) {
if (err & ATA_ABORTED)
printk("BadCRC ");
else printk("Sector ");
pr_cont("BadCRC ");
else pr_cont("Sector ");
}
if (err & ATA_UNC) printk("UncorrectableError ");
if (err & ATA_IDNF) printk("SectorIdNotFound ");
if (err & ATA_TRK0NF) printk("TrackZeroNotFound ");
if (err & ATA_AMNF) printk("AddrMarkNotFound ");
printk("}\n");
if (err & ATA_UNC) pr_cont("UncorrectableError ");
if (err & ATA_IDNF) pr_cont("SectorIdNotFound ");
if (err & ATA_TRK0NF) pr_cont("TrackZeroNotFound ");
if (err & ATA_AMNF) pr_cont("AddrMarkNotFound ");
pr_cont("}\n");
}
}
}
......@@ -1059,8 +1059,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
translate_done:
if (verbose)
printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x "
"to SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n",
pr_err("ata%u: translated ATA stat/err 0x%02x/%02x to SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n",
id, drv_stat, drv_err, *sk, *asc, *ascq);
return;
}
......@@ -1322,6 +1321,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
blk_queue_flush_queueable(q, false);
if (dev->flags & ATA_DFLAG_TRUSTED)
sdev->security_supported = 1;
dev->sdev = sdev;
return 0;
}
......@@ -3127,7 +3129,7 @@ ata_scsi_map_proto(u8 byte1)
* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
* @qc: command structure to be initialized
*
* Handles either 12 or 16-byte versions of the CDB.
* Handles either 12, 16, or 32-byte versions of the CDB.
*
* RETURNS:
* Zero on success, non-zero on failure.
......@@ -3139,13 +3141,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
struct ata_device *dev = qc->dev;
const u8 *cdb = scmd->cmnd;
u16 fp;
u16 cdb_offset = 0;
/* 7Fh variable length cmd means a ata pass-thru(32) */
if (cdb[0] == VARIABLE_LENGTH_CMD)
cdb_offset = 9;
if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) {
tf->protocol = ata_scsi_map_proto(cdb[1 + cdb_offset]);
if (tf->protocol == ATA_PROT_UNKNOWN) {
fp = 1;
goto invalid_fld;
}
if (ata_is_ncq(tf->protocol) && (cdb[2] & 0x3) == 0)
if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
tf->protocol = ATA_PROT_NCQ_NODATA;
/* enable LBA */
......@@ -3181,7 +3189,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->lbah = cdb[12];
tf->device = cdb[13];
tf->command = cdb[14];
} else {
} else if (cdb[0] == ATA_12) {
/*
* 12-byte CDB - incapable of extended commands.
*/
......@@ -3194,6 +3202,30 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->lbah = cdb[7];
tf->device = cdb[8];
tf->command = cdb[9];
} else {
/*
* 32-byte CDB - may contain extended command fields.
*
* If that is the case, copy the upper byte register values.
*/
if (cdb[10] & 0x01) {
tf->hob_feature = cdb[20];
tf->hob_nsect = cdb[22];
tf->hob_lbal = cdb[16];
tf->hob_lbam = cdb[15];
tf->hob_lbah = cdb[14];
tf->flags |= ATA_TFLAG_LBA48;
} else
tf->flags &= ~ATA_TFLAG_LBA48;
tf->feature = cdb[21];
tf->nsect = cdb[23];
tf->lbal = cdb[19];
tf->lbam = cdb[18];
tf->lbah = cdb[17];
tf->device = cdb[24];
tf->command = cdb[25];
tf->auxiliary = get_unaligned_be32(&cdb[28]);
}
/* For NCQ commands copy the tag value */
......@@ -3564,6 +3596,11 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
dev->class == ATA_DEV_ZAC)
supported = 3;
break;
case SECURITY_PROTOCOL_IN:
case SECURITY_PROTOCOL_OUT:
if (dev->flags & ATA_DFLAG_TRUSTED)
supported = 3;
break;
default:
break;
}
......@@ -3910,7 +3947,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
}
/**
* ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands
* ata_scsi_mode_select_xlat - Simulate MODE SELECT 6, 10 commands
* @qc: Storage for translated ATA taskfile
*
* Converts a MODE SELECT command to an ATA SET FEATURES taskfile.
......@@ -4068,6 +4105,99 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
return 1;
}
static u8 ata_scsi_trusted_op(u32 len, bool send, bool dma)
{
if (len == 0)
return ATA_CMD_TRUSTED_NONDATA;
else if (send)
return dma ? ATA_CMD_TRUSTED_SND_DMA : ATA_CMD_TRUSTED_SND;
else
return dma ? ATA_CMD_TRUSTED_RCV_DMA : ATA_CMD_TRUSTED_RCV;
}
static unsigned int ata_scsi_security_inout_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
const u8 *cdb = scmd->cmnd;
struct ata_taskfile *tf = &qc->tf;
u8 secp = cdb[1];
bool send = (cdb[0] == SECURITY_PROTOCOL_OUT);
u16 spsp = get_unaligned_be16(&cdb[2]);
u32 len = get_unaligned_be32(&cdb[6]);
bool dma = !(qc->dev->flags & ATA_DFLAG_PIO);
/*
* We don't support the ATA "security" protocol.
*/
if (secp == 0xef) {
ata_scsi_set_invalid_field(qc->dev, scmd, 1, 0);
return 1;
}
if (cdb[4] & 7) { /* INC_512 */
if (len > 0xffff) {
ata_scsi_set_invalid_field(qc->dev, scmd, 6, 0);
return 1;
}
} else {
if (len > 0x01fffe00) {
ata_scsi_set_invalid_field(qc->dev, scmd, 6, 0);
return 1;
}
/* convert to the sector-based ATA addressing */
len = (len + 511) / 512;
}
tf->protocol = dma ? ATA_PROT_DMA : ATA_PROT_PIO;
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR | ATA_TFLAG_LBA;
if (send)
tf->flags |= ATA_TFLAG_WRITE;
tf->command = ata_scsi_trusted_op(len, send, dma);
tf->feature = secp;
tf->lbam = spsp & 0xff;
tf->lbah = spsp >> 8;
if (len) {
tf->nsect = len & 0xff;
tf->lbal = len >> 8;
} else {
if (!send)
tf->lbah = (1 << 7);
}
ata_qc_set_pc_nbytes(qc);
return 0;
}
/**
* ata_scsi_var_len_cdb_xlat - SATL variable length CDB to Handler
* @qc: Command to be translated
*
* Translate a SCSI variable length CDB to specified commands.
* It checks a service action value in CDB to call corresponding handler.
*
* RETURNS:
* Zero on success, non-zero on failure
*
*/
static unsigned int ata_scsi_var_len_cdb_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
const u8 *cdb = scmd->cmnd;
const u16 sa = get_unaligned_be16(&cdb[8]);
/*
* if service action represents a ata pass-thru(32) command,
* then pass it to ata_scsi_pass_thru handler.
*/
if (sa == ATA_32)
return ata_scsi_pass_thru(qc);
/* unsupported service action */
return 1;
}
/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
......@@ -4108,6 +4238,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case ATA_16:
return ata_scsi_pass_thru;
case VARIABLE_LENGTH_CMD:
return ata_scsi_var_len_cdb_xlat;
case MODE_SELECT:
case MODE_SELECT_10:
return ata_scsi_mode_select_xlat;
......@@ -4119,6 +4252,12 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case ZBC_OUT:
return ata_scsi_zbc_out_xlat;
case SECURITY_PROTOCOL_IN:
case SECURITY_PROTOCOL_OUT:
if (!(dev->flags & ATA_DFLAG_TRUSTED))
break;
return ata_scsi_security_inout_xlat;
case START_STOP:
return ata_scsi_start_stop_xlat;
}
......@@ -4386,7 +4525,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
shost->max_id = 16;
shost->max_lun = 1;
shost->max_channel = 1;
shost->max_cmd_len = 16;
shost->max_cmd_len = 32;
/* Schedule policy is determined by ->qc_defer()
* callback and it needs to see every deferred qc.
......
......@@ -716,24 +716,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
if (PageHighMem(page)) {
unsigned long flags;
/* FIXME: use a bounce buffer */
local_irq_save(flags);
buf = kmap_atomic(page);
/* do the actual data transfer */
ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size,
do_write);
kunmap_atomic(buf);
local_irq_restore(flags);
} else {
buf = page_address(page);
ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size,
do_write);
}
/* do the actual data transfer */
buf = kmap_atomic(page);
ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write);
kunmap_atomic(buf);
if (!do_write && !PageSlab(page))
flush_dcache_page(page);
......@@ -861,24 +847,10 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
if (PageHighMem(page)) {
unsigned long flags;
/* FIXME: use bounce buffer */
local_irq_save(flags);
buf = kmap_atomic(page);
/* do the actual data transfer */
consumed = ap->ops->sff_data_xfer(qc, buf + offset,
count, rw);
kunmap_atomic(buf);
local_irq_restore(flags);
} else {
buf = page_address(page);
consumed = ap->ops->sff_data_xfer(qc, buf + offset,
count, rw);
}
/* do the actual data transfer */
buf = kmap_atomic(page);
consumed = ap->ops->sff_data_xfer(qc, buf + offset, count, rw);
kunmap_atomic(buf);
bytes -= min(bytes, consumed);
qc->curbytes += count;
......
......@@ -98,6 +98,8 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
extern const char *sata_spd_string(unsigned int spd);
extern int ata_port_probe(struct ata_port *ap);
extern void __ata_port_probe(struct ata_port *ap);
extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
u8 page, void *buf, unsigned int sectors);
#define to_ata_port(d) container_of(d, struct ata_port, tdev)
......@@ -160,8 +162,6 @@ extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
unsigned int action);
extern void ata_eh_done(struct ata_link *link, struct ata_device *dev,
unsigned int action);
extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
u8 page, void *buf, unsigned int sectors);
extern void ata_eh_autopsy(struct ata_port *ap);
const char *ata_get_cmd_descript(u8 command);
extern void ata_eh_report(struct ata_port *ap);
......
......@@ -1597,8 +1597,6 @@ static int bfin_atapi_probe(struct platform_device *pdev)
return -ENODEV;
}
platform_set_drvdata(pdev, host);
return 0;
}
......
......@@ -944,7 +944,6 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
goto err_rel_gpio;
}
platform_set_drvdata(pdev, drv_data);
drv_data->pdev = pdev;
drv_data->ide_base = ide_base;
drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN;
......
This diff is collapsed.
......@@ -1038,7 +1038,7 @@ static void octeon_cf_shutdown(struct device *dev)
}
}
static struct of_device_id octeon_cf_match[] = {
static const struct of_device_id octeon_cf_match[] = {
{
.compatible = "cavium,ebt3000-compact-flash",
},
......
......@@ -148,8 +148,6 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
if (!ah)
return -ENOMEM;
platform_set_drvdata(pdev, ah);
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
......
......@@ -292,7 +292,7 @@ static struct ata_port_operations rdc_pata_ops = {
.prereset = rdc_pata_prereset,
};
static struct ata_port_info rdc_port_info = {
static const struct ata_port_info rdc_port_info = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
......
......@@ -582,8 +582,6 @@ static int __init pata_s3c_probe(struct platform_device *pdev)
/* Set endianness and enable the interface */
pata_s3c_hwinit(info, pdata);
platform_set_drvdata(pdev, host);
ret = ata_host_activate(host, info->irq,
info->irq ? pata_s3c_irq : NULL,
0, &pata_s3c_sht);
......
......@@ -81,7 +81,7 @@ static struct ata_port_operations sch_pata_ops = {
.set_dmamode = sch_set_dmamode,
};
static struct ata_port_info sch_port_info = {
static const struct ata_port_info sch_port_info = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
......
......@@ -1285,7 +1285,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
if (err)
dev_err(&ofdev->dev, "failed to activate host");
dev_set_drvdata(&ofdev->dev, host);
return 0;
error_out:
......
......@@ -1523,8 +1523,6 @@ static int sata_fsl_probe(struct platform_device *ofdev)
ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
&sata_fsl_sht);
platform_set_drvdata(ofdev, host);
host_priv->intr_coalescing.show = fsl_sata_intr_coalescing_show;
host_priv->intr_coalescing.store = fsl_sata_intr_coalescing_store;
sysfs_attr_init(&host_priv->intr_coalescing.attr);
......
This diff is collapsed.
/* Header for the Gemini SATA bridge */
#ifndef SATA_GEMINI_H
#define SATA_GEMINI_H
struct sata_gemini;
enum gemini_muxmode {
GEMINI_MUXMODE_0 = 0,
GEMINI_MUXMODE_1,
GEMINI_MUXMODE_2,
GEMINI_MUXMODE_3,
};
struct sata_gemini *gemini_sata_bridge_get(void);
bool gemini_sata_bridge_enabled(struct sata_gemini *sg, bool is_ata1);
enum gemini_muxmode gemini_sata_get_muxmode(struct sata_gemini *sg);
int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge);
void gemini_sata_stop_bridge(struct sata_gemini *sg, unsigned int bridge);
int gemini_sata_reset_bridge(struct sata_gemini *sg, unsigned int bridge);
#endif
......@@ -737,7 +737,7 @@ static struct ata_port_operations inic_port_ops = {
.port_start = inic_port_start,
};
static struct ata_port_info inic_port_info = {
static const struct ata_port_info inic_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
......
......@@ -828,7 +828,7 @@ static void sata_rcar_init_controller(struct ata_host *host)
iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
}
static struct of_device_id sata_rcar_match[] = {
static const struct of_device_id sata_rcar_match[] = {
{
/* Deprecated by "renesas,sata-r8a7779" */
.compatible = "renesas,rcar-sata",
......
......@@ -80,6 +80,10 @@ struct svia_priv {
bool wd_workaround;
};
static int vt6420_hotplug;
module_param_named(vt6420_hotplug, vt6420_hotplug, int, 0644);
MODULE_PARM_DESC(vt6420_hotplug, "Enable hot-plug support for VT6420 (0=Don't support, 1=support)");
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM_SLEEP
static int svia_pci_device_resume(struct pci_dev *pdev);
......@@ -166,7 +170,7 @@ static const struct ata_port_info vt6420_port_info = {
.port_ops = &vt6420_sata_ops,
};
static struct ata_port_info vt6421_sport_info = {
static const struct ata_port_info vt6421_sport_info = {
.flags = ATA_FLAG_SATA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
......@@ -174,7 +178,7 @@ static struct ata_port_info vt6421_sport_info = {
.port_ops = &vt6421_sata_ops,
};
static struct ata_port_info vt6421_pport_info = {
static const struct ata_port_info vt6421_pport_info = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
/* No MWDMA */
......@@ -182,7 +186,7 @@ static struct ata_port_info vt6421_pport_info = {
.port_ops = &vt6421_pata_ops,
};
static struct ata_port_info vt8251_port_info = {
static const struct ata_port_info vt8251_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
......@@ -473,6 +477,11 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
struct ata_host *host;
int rc;
if (vt6420_hotplug) {
ppi[0]->port_ops->scr_read = svia_scr_read;
ppi[0]->port_ops->scr_write = svia_scr_write;
}
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
......@@ -556,7 +565,7 @@ static void svia_wd_fix(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x52, tmp8 | BIT(2));
}
static irqreturn_t vt6421_interrupt(int irq, void *dev_instance)
static irqreturn_t vt642x_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
irqreturn_t rc = ata_bmdma_interrupt(irq, dev_instance);
......@@ -644,7 +653,7 @@ static void svia_configure(struct pci_dev *pdev, int board_id,
pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
}
if (board_id == vt6421) {
if ((board_id == vt6420 && vt6420_hotplug) || board_id == vt6421) {
/* enable IRQ on hotplug */
pci_read_config_byte(pdev, SVIA_MISC_3, &tmp8);
if ((tmp8 & SATA_HOTPLUG) != SATA_HOTPLUG) {
......@@ -744,8 +753,8 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
svia_configure(pdev, board_id, hpriv);
pci_set_master(pdev);
if (board_id == vt6421)
return ata_host_activate(host, pdev->irq, vt6421_interrupt,
if ((board_id == vt6420 && vt6420_hotplug) || board_id == vt6421)
return ata_host_activate(host, pdev->irq, vt642x_interrupt,
IRQF_SHARED, &svia_sht);
else
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
......
......@@ -50,6 +50,7 @@
#include <linux/string_helpers.h>
#include <linux/async.h>
#include <linux/slab.h>
#include <linux/sed-opal.h>
#include <linux/pm_runtime.h>
#include <linux/pr.h>
#include <linux/t10-pi.h>
......@@ -643,6 +644,26 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
mutex_unlock(&sd_ref_mutex);
}
#ifdef CONFIG_BLK_SED_OPAL
static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
size_t len, bool send)
{
struct scsi_device *sdev = data;
u8 cdb[12] = { 0, };
int ret;
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
cdb[1] = secp;
put_unaligned_be16(spsp, &cdb[2]);
put_unaligned_be32(len, &cdb[6]);
ret = scsi_execute_req(sdev, cdb,
send ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
buffer, len, NULL, SD_TIMEOUT, SD_MAX_RETRIES, NULL);
return ret <= 0 ? ret : -EIO;
}
#endif /* CONFIG_BLK_SED_OPAL */
static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int dix, unsigned int dif)
{
......@@ -1454,6 +1475,9 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
if (error)
goto out;
if (is_sed_ioctl(cmd))
return sed_ioctl(sdkp->opal_dev, cmd, p);
/*
* Send SCSI addressing ioctls directly to mid level, send other
* ioctls to block level and then onto mid level if they can't be
......@@ -3014,6 +3038,20 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
sdkp->ws10 = 1;
}
static void sd_read_security(struct scsi_disk *sdkp, unsigned char *buffer)
{
struct scsi_device *sdev = sdkp->device;
if (!sdev->security_supported)
return;
if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE,
SECURITY_PROTOCOL_IN) == 1 &&
scsi_report_opcode(sdev, buffer, SD_BUF_SIZE,
SECURITY_PROTOCOL_OUT) == 1)
sdkp->security = 1;
}
/**
* sd_revalidate_disk - called the first time a new disk is seen,
* performs disk spin up, read_capacity, etc.
......@@ -3067,6 +3105,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
sd_read_write_same(sdkp, buffer);
sd_read_security(sdkp, buffer);
}
sdkp->first_scan = 0;
......@@ -3227,6 +3266,12 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
sd_revalidate_disk(gd);
if (sdkp->security) {
sdkp->opal_dev = init_opal_dev(sdp, &sd_sec_submit);
if (sdkp->opal_dev)
sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
}
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
scsi_autopm_put_device(sdp);
......@@ -3376,6 +3421,8 @@ static int sd_remove(struct device *dev)
sd_zbc_remove(sdkp);
free_opal_dev(sdkp->opal_dev);
blk_register_region(devt, SD_MINORS, NULL,
sd_default_probe, NULL, NULL);
......@@ -3528,6 +3575,7 @@ static int sd_suspend_runtime(struct device *dev)
static int sd_resume(struct device *dev)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
int ret;
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
return 0;
......@@ -3536,7 +3584,10 @@ static int sd_resume(struct device *dev)
return 0;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
return sd_start_stop_device(sdkp, 1);
ret = sd_start_stop_device(sdkp, 1);
if (!ret)
opal_unlock_from_suspend(sdkp->opal_dev);
return ret;
}
/**
......
......@@ -71,6 +71,7 @@ struct scsi_disk {
struct scsi_device *device;
struct device dev;
struct gendisk *disk;
struct opal_dev *opal_dev;
#ifdef CONFIG_BLK_DEV_ZONED
unsigned int nr_zones;
unsigned int zone_blocks;
......@@ -114,6 +115,7 @@ struct scsi_disk {
unsigned rc_basis: 2;
unsigned zoned: 2;
unsigned urswrz : 1;
unsigned security : 1;
unsigned ignore_medium_access_errors : 1;
};
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
......
......@@ -336,11 +336,16 @@ enum {
/* READ_LOG_EXT pages */
ATA_LOG_DIRECTORY = 0x0,
ATA_LOG_SATA_NCQ = 0x10,
ATA_LOG_NCQ_NON_DATA = 0x12,
ATA_LOG_NCQ_SEND_RECV = 0x13,
ATA_LOG_SATA_ID_DEV_DATA = 0x30,
ATA_LOG_NCQ_NON_DATA = 0x12,
ATA_LOG_NCQ_SEND_RECV = 0x13,
ATA_LOG_IDENTIFY_DEVICE = 0x30,
/* Identify device log pages: */
ATA_LOG_SECURITY = 0x06,
ATA_LOG_SATA_SETTINGS = 0x08,
ATA_LOG_ZONED_INFORMATION = 0x09,
/* Identify device SATA settings log:*/
ATA_LOG_DEVSLP_OFFSET = 0x30,
ATA_LOG_DEVSLP_SIZE = 0x08,
ATA_LOG_DEVSLP_MDAT = 0x00,
......
......@@ -156,6 +156,7 @@ enum {
ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */
ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */
ATA_DFLAG_AN = (1 << 7), /* AN configured */
ATA_DFLAG_TRUSTED = (1 << 8), /* device supports trusted send/recv */
ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */
ATA_DFLAG_CFG_MASK = (1 << 12) - 1,
......
......@@ -176,6 +176,7 @@ struct scsi_device {
unsigned no_read_disc_info:1; /* Avoid READ_DISC_INFO cmds */
unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */
unsigned try_rc_10_first:1; /* Try READ_CAPACACITY_10 first */
unsigned security_supported:1; /* Supports Security Protocols */
unsigned is_visible:1; /* is the device visible in sysfs */
unsigned wce_default_on:1; /* Cache is ON by default */
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
......
......@@ -162,6 +162,7 @@
#define VERIFY_32 0x0a
#define WRITE_32 0x0b
#define WRITE_SAME_32 0x0d
#define ATA_32 0x1ff0
/* Values for T10/04-262r7 */
#define ATA_16 0x85 /* 16-byte pass-thru */
......
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