提交 a1480a16 编写于 作者: L Linus Torvalds

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

Pull libata updates from Tejun Heo:

 - Hannes's patchset implements support for better error reporting
   introduced by the new ATA command spec.

 - the deperecated pci_ dma API usages have been replaced by dma_ ones.

 - a bunch of hardware specific updates and some cleanups.

* 'for-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  ata: remove deprecated use of pci api
  ahci: st: st_configure_oob must be called after IP is clocked.
  ahci: st: Update the ahci_st DT documentation
  ahci: st: Update the DT example for how to obtain the PHY.
  sata_dwc_460ex: indent an if statement
  libata: Add tracepoints
  libata-eh: Set 'information' field for autosense
  libata: Implement support for sense data reporting
  libata: Implement NCQ autosense
  libata: use status bit definitions in ata_dump_status()
  ide,ata: Rename ATA_IDX to ATA_SENSE
  libata: whitespace fixes in ata_to_sense_error()
  libata: whitespace cleanup in ata_get_cmd_descript()
  libata: use READ_LOG_DMA_EXT
  libata: remove ATA_FLAG_LOWTAG
  sata_dwc_460ex: re-use hsdev->dev instead of dwc_dev
  sata_dwc_460ex: move to generic DMA driver
  sata_dwc_460ex: join messages back
  sata: xgene: add ACPI support for APM X-Gene SATA ports
  ata: sata_mv: add proper definitions for LP_PHY_CTL register values
......@@ -3,29 +3,48 @@ STMicroelectronics STi SATA controller
This binding describes a SATA device.
Required properties:
- compatible : Must be "st,sti-ahci"
- compatible : Must be "st,ahci"
- reg : Physical base addresses and length of register sets
- interrupts : Interrupt associated with the SATA device
- interrupt-names : Associated name must be; "hostc"
- resets : The power-down and soft-reset lines of SATA IP
- reset-names : Associated names must be; "pwr-dwn" and "sw-rst"
- clocks : The phandle for the clock
- clock-names : Associated name must be; "ahci_clk"
- phys : The phandle for the PHY device
- phys : The phandle for the PHY port
- phy-names : Associated name must be; "ahci_phy"
Optional properties:
- resets : The power-down, soft-reset and power-reset lines of SATA IP
- reset-names : Associated names must be; "pwr-dwn", "sw-rst" and "pwr-rst"
Example:
/* Example for stih416 */
sata0: sata@fe380000 {
compatible = "st,sti-ahci";
reg = <0xfe380000 0x1000>;
interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>;
interrupt-names = "hostc";
phys = <&miphy365x_phy MIPHY_PORT_0 MIPHY_TYPE_SATA>;
phy-names = "ahci_phy";
resets = <&powerdown STIH416_SATA0_POWERDOWN>,
compatible = "st,ahci";
reg = <0xfe380000 0x1000>;
interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>;
interrupt-names = "hostc";
phys = <&phy_port0 PHY_TYPE_SATA>;
phy-names = "ahci_phy";
resets = <&powerdown STIH416_SATA0_POWERDOWN>,
<&softreset STIH416_SATA0_SOFTRESET>;
reset-names = "pwr-dwn", "sw-rst";
clocks = <&clk_s_a0_ls CLK_ICN_REG>;
clock-names = "ahci_clk";
reset-names = "pwr-dwn", "sw-rst";
clocks = <&clk_s_a0_ls CLK_ICN_REG>;
clock-names = "ahci_clk";
};
/* Example for stih407 family silicon */
sata0: sata@9b20000 {
compatible = "st,ahci";
reg = <0x9b20000 0x1000>;
interrupts = <GIC_SPI 159 IRQ_TYPE_NONE>;
interrupt-names = "hostc";
phys = <&phy_port0 PHY_TYPE_SATA>;
phy-names = "ahci_phy";
resets = <&powerdown STIH407_SATA0_POWERDOWN>,
<&softreset STIH407_SATA0_SOFTRESET>,
<&softreset STIH407_SATA0_PWR_SOFTRESET>;
reset-names = "pwr-dwn", "sw-rst", "pwr-rst";
clocks = <&clk_s_c0_flexgen CLK_ICN_REG>;
clock-names = "ahci_clk";
};
......@@ -111,7 +111,8 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-y := libata-core.o libata-scsi.o libata-eh.o \
libata-transport.o libata-trace.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
......
......@@ -181,10 +181,10 @@ static int acard_ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
int rc;
if (using_dac &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"64-bit DMA enable failed\n");
......@@ -192,12 +192,12 @@ static int acard_ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"32-bit consistent DMA enable failed\n");
......
......@@ -738,10 +738,10 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
return 0;
if (using_dac &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"64-bit DMA enable failed\n");
......@@ -749,12 +749,12 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"32-bit consistent DMA enable failed\n");
......
......@@ -68,8 +68,6 @@ static int st_ahci_deassert_resets(struct device *dev)
}
}
st_ahci_configure_oob(drv_data->hpriv->mmio);
if (drv_data->sw_rst) {
err = reset_control_deassert(drv_data->sw_rst);
if (err) {
......@@ -172,6 +170,8 @@ static int st_ahci_probe(struct platform_device *pdev)
if (err)
return err;
st_ahci_configure_oob(drv_data->hpriv->mmio);
err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
&ahci_platform_sht);
if (err) {
......@@ -222,6 +222,8 @@ static int st_ahci_resume(struct device *dev)
return err;
}
st_ahci_configure_oob(drv_data->hpriv->mmio);
return ahci_platform_resume_host(dev);
}
#endif
......
......@@ -22,6 +22,7 @@
* NOTE: PM support is not currently available.
*
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ahci_platform.h>
......@@ -718,6 +719,14 @@ static int xgene_ahci_probe(struct platform_device *pdev)
return rc;
}
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgene_ahci_acpi_match[] = {
{ "APMC0D0D", },
{ }
};
MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
#endif
static const struct of_device_id xgene_ahci_of_match[] = {
{.compatible = "apm,xgene-ahci"},
{},
......@@ -730,6 +739,7 @@ static struct platform_driver xgene_ahci_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = xgene_ahci_of_match,
.acpi_match_table = ACPI_PTR(xgene_ahci_acpi_match),
},
};
......
......@@ -70,6 +70,9 @@
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
#define CREATE_TRACE_POINTS
#include <trace/events/libata.h>
#include "libata.h"
#include "libata-transport.h"
......@@ -691,11 +694,11 @@ static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev)
* RETURNS:
* Block address read from @tf.
*/
u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
{
u64 block = 0;
if (tf->flags & ATA_TFLAG_LBA) {
if (!dev || tf->flags & ATA_TFLAG_LBA) {
if (tf->flags & ATA_TFLAG_LBA48) {
block |= (u64)tf->hob_lbah << 40;
block |= (u64)tf->hob_lbam << 32;
......@@ -2144,6 +2147,24 @@ static int ata_dev_config_ncq(struct ata_device *dev,
return 0;
}
static void ata_dev_config_sense_reporting(struct ata_device *dev)
{
unsigned int err_mask;
if (!ata_id_has_sense_reporting(dev->id))
return;
if (ata_id_sense_reporting_enabled(dev->id))
return;
err_mask = ata_dev_set_feature(dev, SETFEATURE_SENSE_DATA, 0x1);
if (err_mask) {
ata_dev_dbg(dev,
"failed to enable Sense Data Reporting, Emask 0x%x\n",
err_mask);
}
}
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
* @dev: Target device to configure
......@@ -2366,7 +2387,7 @@ int ata_dev_configure(struct ata_device *dev)
dev->devslp_timing[i] = sata_setting[j];
}
}
ata_dev_config_sense_reporting(dev);
dev->cdb_len = 16;
}
......@@ -4897,6 +4918,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
*/
if (unlikely(ata_tag_internal(qc->tag))) {
fill_result_tf(qc);
trace_ata_qc_complete_internal(qc);
__ata_qc_complete(qc);
return;
}
......@@ -4907,6 +4929,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
*/
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
fill_result_tf(qc);
trace_ata_qc_complete_failed(qc);
ata_qc_schedule_eh(qc);
return;
}
......@@ -4917,6 +4940,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
if (qc->flags & ATA_QCFLAG_RESULT_TF)
fill_result_tf(qc);
trace_ata_qc_complete_done(qc);
/* Some commands need post-processing after successful
* completion.
*/
......@@ -5064,7 +5088,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
}
ap->ops->qc_prep(qc);
trace_ata_qc_issue(qc);
qc->err_mask |= ap->ops->qc_issue(qc);
if (unlikely(qc->err_mask))
goto err;
......
......@@ -46,6 +46,7 @@
#include <linux/libata.h>
#include <trace/events/libata.h>
#include "libata.h"
enum {
......@@ -1510,13 +1511,18 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);
ata_tf_init(dev, &tf);
tf.command = ATA_CMD_READ_LOG_EXT;
if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id)) {
tf.command = ATA_CMD_READ_LOG_DMA_EXT;
tf.protocol = ATA_PROT_DMA;
} else {
tf.command = ATA_CMD_READ_LOG_EXT;
tf.protocol = ATA_PROT_PIO;
}
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;
tf.protocol = ATA_PROT_PIO;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
buf, sectors * ATA_SECT_SIZE, 0);
......@@ -1575,6 +1581,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
tf->hob_lbah = buf[10];
tf->nsect = buf[12];
tf->hob_nsect = buf[13];
if (ata_id_has_ncq_autosense(dev->id))
tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
return 0;
}
......@@ -1610,6 +1618,70 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
return err_mask;
}
/**
* ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT
* @dev: device to perform REQUEST_SENSE_SENSE_DATA_EXT to
* @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long)
* @dfl_sense_key: default sense key to use
*
* Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK
* SENSE. This function is EH helper.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* encoded sense data on success, 0 on failure or if sense data
* is not available.
*/
static u32 ata_eh_request_sense(struct ata_queued_cmd *qc,
struct scsi_cmnd *cmd)
{
struct ata_device *dev = qc->dev;
struct ata_taskfile tf;
unsigned int err_mask;
if (!cmd)
return 0;
DPRINTK("ATA request sense\n");
ata_dev_warn(dev, "request sense\n");
if (!ata_id_sense_reporting_enabled(dev->id)) {
ata_dev_warn(qc->dev, "sense data reporting disabled\n");
return 0;
}
ata_tf_init(dev, &tf);
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
tf.command = ATA_CMD_REQ_SENSE_DATA;
tf.protocol = ATA_PROT_NODATA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
/*
* ACS-4 states:
* The device may set the SENSE DATA AVAILABLE bit to one in the
* STATUS field and clear the ERROR bit to zero in the STATUS field
* to indicate that the command returned completion without an error
* and the sense data described in table 306 is available.
*
* IOW the 'ATA_SENSE' bit might not be set even though valid
* sense data is available.
* So check for both.
*/
if ((tf.command & ATA_SENSE) ||
tf.lbah != 0 || tf.lbam != 0 || tf.lbal != 0) {
ata_scsi_set_sense(cmd, tf.lbah, tf.lbam, tf.lbal);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
ata_dev_warn(dev, "sense data %02x/%02x/%02x\n",
tf.lbah, tf.lbam, tf.lbal);
} else {
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
tf.command, err_mask);
}
return err_mask;
}
/**
* atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
* @dev: device to perform REQUEST_SENSE to
......@@ -1772,6 +1844,19 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
memcpy(&qc->result_tf, &tf, sizeof(tf));
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
if (qc->result_tf.auxiliary) {
char sense_key, asc, ascq;
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
ascq = qc->result_tf.auxiliary & 0xff;
ata_dev_dbg(dev, "NCQ Autosense %02x/%02x/%02x\n",
sense_key, asc, ascq);
ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq);
ata_scsi_set_sense_information(qc->scsicmd, &qc->result_tf);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
}
ehc->i.err_mask &= ~AC_ERR_DEV;
}
......@@ -1801,6 +1886,27 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
return ATA_EH_RESET;
}
/*
* Sense data reporting does not work if the
* device fault bit is set.
*/
if ((stat & ATA_SENSE) && !(stat & ATA_DF) &&
!(qc->flags & ATA_QCFLAG_SENSE_VALID)) {
if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
tmp = ata_eh_request_sense(qc, qc->scsicmd);
if (tmp)
qc->err_mask |= tmp;
else
ata_scsi_set_sense_information(qc->scsicmd, tf);
} else {
ata_dev_warn(qc->dev, "sense data available but port frozen\n");
}
}
/* Set by NCQ autosense or request sense above */
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
return 0;
if (stat & (ATA_ERR | ATA_DF))
qc->err_mask |= AC_ERR_DEV;
else
......@@ -2186,6 +2292,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
all_err_mask |= qc->err_mask;
if (qc->flags & ATA_QCFLAG_IO)
eflags |= ATA_EFLAG_IS_IO;
trace_ata_eh_link_autopsy_qc(qc);
}
/* enforce default EH actions */
......@@ -2220,7 +2327,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
eflags |= ATA_EFLAG_DUBIOUS_XFER;
ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask);
}
trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask);
DPRINTK("EXIT\n");
}
......@@ -2289,27 +2396,27 @@ const char *ata_get_cmd_descript(u8 command)
const char *text;
} cmd_descr[] = {
{ ATA_CMD_DEV_RESET, "DEVICE RESET" },
{ ATA_CMD_CHK_POWER, "CHECK POWER MODE" },
{ ATA_CMD_STANDBY, "STANDBY" },
{ ATA_CMD_IDLE, "IDLE" },
{ ATA_CMD_EDD, "EXECUTE DEVICE DIAGNOSTIC" },
{ ATA_CMD_DOWNLOAD_MICRO, "DOWNLOAD MICROCODE" },
{ ATA_CMD_CHK_POWER, "CHECK POWER MODE" },
{ ATA_CMD_STANDBY, "STANDBY" },
{ ATA_CMD_IDLE, "IDLE" },
{ ATA_CMD_EDD, "EXECUTE DEVICE DIAGNOSTIC" },
{ ATA_CMD_DOWNLOAD_MICRO, "DOWNLOAD MICROCODE" },
{ ATA_CMD_DOWNLOAD_MICRO_DMA, "DOWNLOAD MICROCODE DMA" },
{ ATA_CMD_NOP, "NOP" },
{ ATA_CMD_FLUSH, "FLUSH CACHE" },
{ ATA_CMD_FLUSH_EXT, "FLUSH CACHE EXT" },
{ ATA_CMD_ID_ATA, "IDENTIFY DEVICE" },
{ ATA_CMD_ID_ATAPI, "IDENTIFY PACKET DEVICE" },
{ ATA_CMD_SERVICE, "SERVICE" },
{ ATA_CMD_READ, "READ DMA" },
{ ATA_CMD_READ_EXT, "READ DMA EXT" },
{ ATA_CMD_READ_QUEUED, "READ DMA QUEUED" },
{ ATA_CMD_READ_STREAM_EXT, "READ STREAM EXT" },
{ ATA_CMD_FLUSH, "FLUSH CACHE" },
{ ATA_CMD_FLUSH_EXT, "FLUSH CACHE EXT" },
{ ATA_CMD_ID_ATA, "IDENTIFY DEVICE" },
{ ATA_CMD_ID_ATAPI, "IDENTIFY PACKET DEVICE" },
{ ATA_CMD_SERVICE, "SERVICE" },
{ ATA_CMD_READ, "READ DMA" },
{ ATA_CMD_READ_EXT, "READ DMA EXT" },
{ ATA_CMD_READ_QUEUED, "READ DMA QUEUED" },
{ ATA_CMD_READ_STREAM_EXT, "READ STREAM EXT" },
{ ATA_CMD_READ_STREAM_DMA_EXT, "READ STREAM DMA EXT" },
{ ATA_CMD_WRITE, "WRITE DMA" },
{ ATA_CMD_WRITE_EXT, "WRITE DMA EXT" },
{ ATA_CMD_WRITE_QUEUED, "WRITE DMA QUEUED EXT" },
{ ATA_CMD_WRITE_STREAM_EXT, "WRITE STREAM EXT" },
{ ATA_CMD_WRITE, "WRITE DMA" },
{ ATA_CMD_WRITE_EXT, "WRITE DMA EXT" },
{ ATA_CMD_WRITE_QUEUED, "WRITE DMA QUEUED EXT" },
{ ATA_CMD_WRITE_STREAM_EXT, "WRITE STREAM EXT" },
{ ATA_CMD_WRITE_STREAM_DMA_EXT, "WRITE STREAM DMA EXT" },
{ ATA_CMD_WRITE_FUA_EXT, "WRITE DMA FUA EXT" },
{ ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" },
......@@ -2325,7 +2432,7 @@ const char *ata_get_cmd_descript(u8 command)
{ ATA_CMD_READ_MULTI_EXT, "READ MULTIPLE EXT" },
{ ATA_CMD_WRITE_MULTI, "WRITE MULTIPLE" },
{ ATA_CMD_WRITE_MULTI_EXT, "WRITE MULTIPLE EXT" },
{ ATA_CMD_WRITE_MULTI_FUA_EXT, "WRITE MULTIPLE FUA EXT" },
{ ATA_CMD_WRITE_MULTI_FUA_EXT, "WRITE MULTIPLE FUA EXT" },
{ ATA_CMD_SET_FEATURES, "SET FEATURES" },
{ ATA_CMD_SET_MULTI, "SET MULTIPLE MODE" },
{ ATA_CMD_VERIFY, "READ VERIFY SECTOR(S)" },
......@@ -2342,12 +2449,12 @@ const char *ata_get_cmd_descript(u8 command)
{ ATA_CMD_READ_LOG_EXT, "READ LOG EXT" },
{ ATA_CMD_WRITE_LOG_EXT, "WRITE LOG EXT" },
{ ATA_CMD_READ_LOG_DMA_EXT, "READ LOG DMA EXT" },
{ ATA_CMD_WRITE_LOG_DMA_EXT, "WRITE LOG DMA EXT" },
{ ATA_CMD_WRITE_LOG_DMA_EXT, "WRITE LOG DMA EXT" },
{ ATA_CMD_TRUSTED_NONDATA, "TRUSTED NON-DATA" },
{ ATA_CMD_TRUSTED_RCV, "TRUSTED RECEIVE" },
{ ATA_CMD_TRUSTED_RCV_DMA, "TRUSTED RECEIVE DMA" },
{ ATA_CMD_TRUSTED_RCV_DMA, "TRUSTED RECEIVE DMA" },
{ ATA_CMD_TRUSTED_SND, "TRUSTED SEND" },
{ ATA_CMD_TRUSTED_SND_DMA, "TRUSTED SEND DMA" },
{ ATA_CMD_TRUSTED_SND_DMA, "TRUSTED SEND DMA" },
{ ATA_CMD_PMP_READ, "READ BUFFER" },
{ ATA_CMD_PMP_READ_DMA, "READ BUFFER DMA" },
{ ATA_CMD_PMP_WRITE, "WRITE BUFFER" },
......@@ -2364,12 +2471,12 @@ const char *ata_get_cmd_descript(u8 command)
{ ATA_CMD_MEDIA_LOCK, "DOOR LOCK" },
{ ATA_CMD_MEDIA_UNLOCK, "DOOR UNLOCK" },
{ ATA_CMD_DSM, "DATA SET MANAGEMENT" },
{ ATA_CMD_CHK_MED_CRD_TYP, "CHECK MEDIA CARD TYPE" },
{ ATA_CMD_CFA_REQ_EXT_ERR, "CFA REQUEST EXTENDED ERROR" },
{ ATA_CMD_CHK_MED_CRD_TYP, "CHECK MEDIA CARD TYPE" },
{ ATA_CMD_CFA_REQ_EXT_ERR, "CFA REQUEST EXTENDED ERROR" },
{ ATA_CMD_CFA_WRITE_NE, "CFA WRITE SECTORS WITHOUT ERASE" },
{ ATA_CMD_CFA_TRANS_SECT, "CFA TRANSLATE SECTOR" },
{ ATA_CMD_CFA_ERASE, "CFA ERASE SECTORS" },
{ ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" },
{ ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" },
{ ATA_CMD_REQ_SENSE_DATA, "REQUEST SENSE DATA EXT" },
{ ATA_CMD_SANITIZE_DEVICE, "SANITIZE DEVICE" },
{ ATA_CMD_READ_LONG, "READ LONG (with retries)" },
......@@ -2543,14 +2650,15 @@ static void ata_eh_link_report(struct ata_link *link)
#ifdef CONFIG_ATA_VERBOSE_ERROR
if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
ATA_ERR)) {
ATA_SENSE | ATA_ERR)) {
if (res->command & ATA_BUSY)
ata_dev_err(qc->dev, "status: { Busy }\n");
else
ata_dev_err(qc->dev, "status: { %s%s%s%s}\n",
ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
res->command & ATA_DRDY ? "DRDY " : "",
res->command & ATA_DF ? "DF " : "",
res->command & ATA_DRQ ? "DRQ " : "",
res->command & ATA_SENSE ? "SENSE " : "",
res->command & ATA_ERR ? "ERR " : "");
}
......
......@@ -270,13 +270,28 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
if (!cmd)
return;
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
}
void ata_scsi_set_sense_information(struct scsi_cmnd *cmd,
const struct ata_taskfile *tf)
{
u64 information;
if (!cmd)
return;
information = ata_tf_read_block(tf, NULL);
scsi_set_sense_information(cmd->sense_buffer, information);
}
static ssize_t
ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
......@@ -799,26 +814,27 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
if (stat & ATA_BUSY) {
printk("Busy }\n"); /* Data is not valid in this case */
} else {
if (stat & 0x40) printk("DriveReady ");
if (stat & 0x20) printk("DeviceFault ");
if (stat & 0x10) printk("SeekComplete ");
if (stat & 0x08) printk("DataRequest ");
if (stat & 0x04) printk("CorrectedError ");
if (stat & 0x02) printk("Index ");
if (stat & 0x01) printk("Error ");
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 (err) {
printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
if (err & 0x04) printk("DriveStatusError ");
if (err & 0x80) {
if (err & 0x04) printk("BadCRC ");
if (err & ATA_ABORTED) printk("DriveStatusError ");
if (err & ATA_ICRC) {
if (err & ATA_ABORTED)
printk("BadCRC ");
else printk("Sector ");
}
if (err & 0x40) printk("UncorrectableError ");
if (err & 0x10) printk("SectorIdNotFound ");
if (err & 0x02) printk("TrackZeroNotFound ");
if (err & 0x01) printk("AddrMarkNotFound ");
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");
}
}
......@@ -849,40 +865,59 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
/* Based on the 3ware driver translation table */
static const unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
{0xd1, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
{0xd1, ABORTED_COMMAND, 0x00, 0x00},
// Device busy Aborted command
/* BBD|ECC|ID */
{0xd0, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
{0xd0, ABORTED_COMMAND, 0x00, 0x00},
// Device busy Aborted command
/* ECC|MC|MARK */
{0x61, HARDWARE_ERROR, 0x00, 0x00}, // Device fault Hardware error
{0x61, HARDWARE_ERROR, 0x00, 0x00},
// Device fault Hardware error
/* ICRC|ABRT */ /* NB: ICRC & !ABRT is BBD */
{0x84, ABORTED_COMMAND, 0x47, 0x00}, // Data CRC error SCSI parity error
{0x84, ABORTED_COMMAND, 0x47, 0x00},
// Data CRC error SCSI parity error
/* MC|ID|ABRT|TRK0|MARK */
{0x37, NOT_READY, 0x04, 0x00}, // Unit offline Not ready
{0x37, NOT_READY, 0x04, 0x00},
// Unit offline Not ready
/* MCR|MARK */
{0x09, NOT_READY, 0x04, 0x00}, // Unrecovered disk error Not ready
{0x09, NOT_READY, 0x04, 0x00},
// Unrecovered disk error Not ready
/* Bad address mark */
{0x01, MEDIUM_ERROR, 0x13, 0x00}, // Address mark not found Address mark not found for data field
/* TRK0 */
{0x02, HARDWARE_ERROR, 0x00, 0x00}, // Track 0 not found Hardware error
{0x01, MEDIUM_ERROR, 0x13, 0x00},
// Address mark not found for data field
/* TRK0 - Track 0 not found */
{0x02, HARDWARE_ERROR, 0x00, 0x00},
// Hardware error
/* Abort: 0x04 is not translated here, see below */
/* Media change request */
{0x08, NOT_READY, 0x04, 0x00}, // Media change request FIXME: faking offline
/* SRV/IDNF */
{0x10, ILLEGAL_REQUEST, 0x21, 0x00}, // ID not found Logical address out of range
/* MC */
{0x20, UNIT_ATTENTION, 0x28, 0x00}, // Media Changed Not ready to ready change, medium may have changed
/* ECC */
{0x40, MEDIUM_ERROR, 0x11, 0x04}, // Uncorrectable ECC error Unrecovered read error
{0x08, NOT_READY, 0x04, 0x00},
// FIXME: faking offline
/* SRV/IDNF - ID not found */
{0x10, ILLEGAL_REQUEST, 0x21, 0x00},
// Logical address out of range
/* MC - Media Changed */
{0x20, UNIT_ATTENTION, 0x28, 0x00},
// Not ready to ready change, medium may have changed
/* ECC - Uncorrectable ECC error */
{0x40, MEDIUM_ERROR, 0x11, 0x04},
// Unrecovered read error
/* BBD - block marked bad */
{0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error
{0x80, MEDIUM_ERROR, 0x11, 0x04},
// Block marked bad Medium error, unrecovered read error
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
static const unsigned char stat_table[][4] = {
/* Must be first because BUSY means no other bits valid */
{0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now
{0x20, HARDWARE_ERROR, 0x44, 0x00}, // Device fault, internal target failure
{0x08, ABORTED_COMMAND, 0x47, 0x00}, // Timed out in xfer, fake parity for now
{0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
{0x80, ABORTED_COMMAND, 0x47, 0x00},
// Busy, fake parity for now
{0x40, ILLEGAL_REQUEST, 0x21, 0x04},
// Device ready, unaligned write command
{0x20, HARDWARE_ERROR, 0x44, 0x00},
// Device fault, internal target failure
{0x08, ABORTED_COMMAND, 0x47, 0x00},
// Timed out in xfer, fake parity for now
{0x04, RECOVERED_ERROR, 0x11, 0x00},
// Recovered ECC error Medium error, recovered
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
......@@ -1757,7 +1792,9 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
((cdb[2] & 0x20) || need_sense)) {
ata_gen_passthru_sense(qc);
} else {
if (!need_sense) {
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
cmd->result = SAM_STAT_CHECK_CONDITION;
} else if (!need_sense) {
cmd->result = SAM_STAT_GOOD;
} else {
/* TODO: decide which descriptor format to use
......@@ -4240,10 +4277,7 @@ int ata_sas_allocate_tag(struct ata_port *ap)
unsigned int i, tag;
for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) {
if (ap->flags & ATA_FLAG_LOWTAG)
tag = 1;
else
tag = tag < max_queue ? tag : 0;
tag = tag < max_queue ? tag : 0;
/* the last tag is reserved for internal command. */
if (tag == ATA_TAG_INTERNAL)
......
......@@ -3220,11 +3220,11 @@ void ata_pci_bmdma_init(struct ata_host *host)
* ->sff_irq_clear method. Try to initialize bmdma_addr
* regardless of dma masks.
*/
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
ata_bmdma_nodma(host, "failed to set dma mask");
if (!rc) {
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
ata_bmdma_nodma(host,
"failed to set consistent dma mask");
......
/*
* libata-trace.c - trace functions for libata
*
* Copyright 2015 Hannes Reinecke
* Copyright 2015 SUSE Linux GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/trace_seq.h>
#include <trace/events/libata.h>
const char *
libata_trace_parse_status(struct trace_seq *p, unsigned char status)
{
const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "{ ");
if (status & ATA_BUSY)
trace_seq_printf(p, "BUSY ");
if (status & ATA_DRDY)
trace_seq_printf(p, "DRDY ");
if (status & ATA_DF)
trace_seq_printf(p, "DF ");
if (status & ATA_DSC)
trace_seq_printf(p, "DSC ");
if (status & ATA_DRQ)
trace_seq_printf(p, "DRQ ");
if (status & ATA_CORR)
trace_seq_printf(p, "CORR ");
if (status & ATA_SENSE)
trace_seq_printf(p, "SENSE ");
if (status & ATA_ERR)
trace_seq_printf(p, "ERR ");
trace_seq_putc(p, '}');
trace_seq_putc(p, 0);
return ret;
}
const char *
libata_trace_parse_eh_action(struct trace_seq *p, unsigned int eh_action)
{
const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "%x", eh_action);
if (eh_action) {
trace_seq_printf(p, "{ ");
if (eh_action & ATA_EH_REVALIDATE)
trace_seq_printf(p, "REVALIDATE ");
if (eh_action & (ATA_EH_SOFTRESET | ATA_EH_HARDRESET))
trace_seq_printf(p, "RESET ");
else if (eh_action & ATA_EH_SOFTRESET)
trace_seq_printf(p, "SOFTRESET ");
else if (eh_action & ATA_EH_HARDRESET)
trace_seq_printf(p, "HARDRESET ");
if (eh_action & ATA_EH_ENABLE_LINK)
trace_seq_printf(p, "ENABLE_LINK ");
if (eh_action & ATA_EH_PARK)
trace_seq_printf(p, "PARK ");
trace_seq_putc(p, '}');
}
trace_seq_putc(p, 0);
return ret;
}
const char *
libata_trace_parse_eh_err_mask(struct trace_seq *p, unsigned int eh_err_mask)
{
const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "%x", eh_err_mask);
if (eh_err_mask) {
trace_seq_printf(p, "{ ");
if (eh_err_mask & AC_ERR_DEV)
trace_seq_printf(p, "DEV ");
if (eh_err_mask & AC_ERR_HSM)
trace_seq_printf(p, "HSM ");
if (eh_err_mask & AC_ERR_TIMEOUT)
trace_seq_printf(p, "TIMEOUT ");
if (eh_err_mask & AC_ERR_MEDIA)
trace_seq_printf(p, "MEDIA ");
if (eh_err_mask & AC_ERR_ATA_BUS)
trace_seq_printf(p, "ATA_BUS ");
if (eh_err_mask & AC_ERR_HOST_BUS)
trace_seq_printf(p, "HOST_BUS ");
if (eh_err_mask & AC_ERR_SYSTEM)
trace_seq_printf(p, "SYSTEM ");
if (eh_err_mask & AC_ERR_INVALID)
trace_seq_printf(p, "INVALID ");
if (eh_err_mask & AC_ERR_OTHER)
trace_seq_printf(p, "OTHER ");
if (eh_err_mask & AC_ERR_NODEV_HINT)
trace_seq_printf(p, "NODEV_HINT ");
if (eh_err_mask & AC_ERR_NCQ)
trace_seq_printf(p, "NCQ ");
trace_seq_putc(p, '}');
}
trace_seq_putc(p, 0);
return ret;
}
const char *
libata_trace_parse_qc_flags(struct trace_seq *p, unsigned int qc_flags)
{
const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "%x", qc_flags);
if (qc_flags) {
trace_seq_printf(p, "{ ");
if (qc_flags & ATA_QCFLAG_ACTIVE)
trace_seq_printf(p, "ACTIVE ");
if (qc_flags & ATA_QCFLAG_DMAMAP)
trace_seq_printf(p, "DMAMAP ");
if (qc_flags & ATA_QCFLAG_IO)
trace_seq_printf(p, "IO ");
if (qc_flags & ATA_QCFLAG_RESULT_TF)
trace_seq_printf(p, "RESULT_TF ");
if (qc_flags & ATA_QCFLAG_CLEAR_EXCL)
trace_seq_printf(p, "CLEAR_EXCL ");
if (qc_flags & ATA_QCFLAG_QUIET)
trace_seq_printf(p, "QUIET ");
if (qc_flags & ATA_QCFLAG_RETRY)
trace_seq_printf(p, "RETRY ");
if (qc_flags & ATA_QCFLAG_FAILED)
trace_seq_printf(p, "FAILED ");
if (qc_flags & ATA_QCFLAG_SENSE_VALID)
trace_seq_printf(p, "SENSE_VALID ");
if (qc_flags & ATA_QCFLAG_EH_SCHEDULED)
trace_seq_printf(p, "EH_SCHEDULED ");
trace_seq_putc(p, '}');
}
trace_seq_putc(p, 0);
return ret;
}
......@@ -67,7 +67,8 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
unsigned int tag);
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
extern u64 ata_tf_read_block(const struct ata_taskfile *tf,
struct ata_device *dev);
extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen,
......@@ -137,6 +138,9 @@ extern int ata_scsi_add_hosts(struct ata_host *host,
struct scsi_host_template *sht);
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
extern int ata_scsi_offline_dev(struct ata_device *dev);
extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_set_sense_information(struct scsi_cmnd *cmd,
const struct ata_taskfile *tf);
extern void ata_scsi_media_change_notify(struct ata_device *dev);
extern void ata_scsi_hotplug(struct work_struct *work);
extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
......
......@@ -475,11 +475,11 @@ static int atp867x_ata_pci_sff_init_host(struct ata_host *host)
atp867x_fixup(host);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
return rc;
}
......
......@@ -164,11 +164,11 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV;
}
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
return -ENODEV;
}
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
return -ENODEV;
}
......
......@@ -221,10 +221,10 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -122,10 +122,10 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return rc;
host->iomap = pcim_iomap_table(dev);
rc = pci_set_dma_mask(dev, ATA_DMA_MASK);
rc = dma_set_mask(&dev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(dev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&dev->dev, ATA_DMA_MASK);
if (rc)
return rc;
pci_set_master(dev);
......
......@@ -730,11 +730,11 @@ static int pdc2027x_init_one(struct pci_dev *pdev,
return rc;
host->iomap = pcim_iomap_table(pdev);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -1029,10 +1029,10 @@ static int scc_host_init(struct ata_host *host)
if (rc)
return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -374,10 +374,10 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
host->iomap = pcim_iomap_table(pdev);
/* Setup DMA masks */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
pci_set_master(pdev);
......
......@@ -593,12 +593,12 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
{
int rc;
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit consistent DMA enable failed\n");
return rc;
......
......@@ -36,11 +36,16 @@
#include <linux/platform_device.h>
#include <linux/libata.h>
#include <linux/slab.h>
#include "libata.h"
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
/* Supported DMA engine drivers */
#include <linux/platform_data/dma-dw.h>
#include <linux/dma/dw.h>
/* These two are defined in "libata.h" */
#undef DRV_NAME
#undef DRV_VERSION
......@@ -60,153 +65,9 @@
#define NO_IRQ 0
#endif
/* SATA DMA driver Globals */
#define DMA_NUM_CHANS 1
#define DMA_NUM_CHAN_REGS 8
/* SATA DMA Register definitions */
#define AHB_DMA_BRST_DFLT 64 /* 16 data items burst length*/
struct dmareg {
u32 low; /* Low bits 0-31 */
u32 high; /* High bits 32-63 */
};
/* DMA Per Channel registers */
struct dma_chan_regs {
struct dmareg sar; /* Source Address */
struct dmareg dar; /* Destination address */
struct dmareg llp; /* Linked List Pointer */
struct dmareg ctl; /* Control */
struct dmareg sstat; /* Source Status not implemented in core */
struct dmareg dstat; /* Destination Status not implemented in core*/
struct dmareg sstatar; /* Source Status Address not impl in core */
struct dmareg dstatar; /* Destination Status Address not implemente */
struct dmareg cfg; /* Config */
struct dmareg sgr; /* Source Gather */
struct dmareg dsr; /* Destination Scatter */
};
/* Generic Interrupt Registers */
struct dma_interrupt_regs {
struct dmareg tfr; /* Transfer Interrupt */
struct dmareg block; /* Block Interrupt */
struct dmareg srctran; /* Source Transfer Interrupt */
struct dmareg dsttran; /* Dest Transfer Interrupt */
struct dmareg error; /* Error */
};
struct ahb_dma_regs {
struct dma_chan_regs chan_regs[DMA_NUM_CHAN_REGS];
struct dma_interrupt_regs interrupt_raw; /* Raw Interrupt */
struct dma_interrupt_regs interrupt_status; /* Interrupt Status */
struct dma_interrupt_regs interrupt_mask; /* Interrupt Mask */
struct dma_interrupt_regs interrupt_clear; /* Interrupt Clear */
struct dmareg statusInt; /* Interrupt combined*/
struct dmareg rq_srcreg; /* Src Trans Req */
struct dmareg rq_dstreg; /* Dst Trans Req */
struct dmareg rq_sgl_srcreg; /* Sngl Src Trans Req*/
struct dmareg rq_sgl_dstreg; /* Sngl Dst Trans Req*/
struct dmareg rq_lst_srcreg; /* Last Src Trans Req*/
struct dmareg rq_lst_dstreg; /* Last Dst Trans Req*/
struct dmareg dma_cfg; /* DMA Config */
struct dmareg dma_chan_en; /* DMA Channel Enable*/
struct dmareg dma_id; /* DMA ID */
struct dmareg dma_test; /* DMA Test */
struct dmareg res1; /* reserved */
struct dmareg res2; /* reserved */
/*
* DMA Comp Params
* Param 6 = dma_param[0], Param 5 = dma_param[1],
* Param 4 = dma_param[2] ...
*/
struct dmareg dma_params[6];
};
/* Data structure for linked list item */
struct lli {
u32 sar; /* Source Address */
u32 dar; /* Destination address */
u32 llp; /* Linked List Pointer */
struct dmareg ctl; /* Control */
struct dmareg dstat; /* Destination Status */
};
enum {
SATA_DWC_DMAC_LLI_SZ = (sizeof(struct lli)),
SATA_DWC_DMAC_LLI_NUM = 256,
SATA_DWC_DMAC_LLI_TBL_SZ = (SATA_DWC_DMAC_LLI_SZ * \
SATA_DWC_DMAC_LLI_NUM),
SATA_DWC_DMAC_TWIDTH_BYTES = 4,
SATA_DWC_DMAC_CTRL_TSIZE_MAX = (0x00000800 * \
SATA_DWC_DMAC_TWIDTH_BYTES),
};
/* DMA Register Operation Bits */
enum {
DMA_EN = 0x00000001, /* Enable AHB DMA */
DMA_CTL_LLP_SRCEN = 0x10000000, /* Blk chain enable Src */
DMA_CTL_LLP_DSTEN = 0x08000000, /* Blk chain enable Dst */
};
#define DMA_CTL_BLK_TS(size) ((size) & 0x000000FFF) /* Blk Transfer size */
#define DMA_CHANNEL(ch) (0x00000001 << (ch)) /* Select channel */
/* Enable channel */
#define DMA_ENABLE_CHAN(ch) ((0x00000001 << (ch)) | \
((0x000000001 << (ch)) << 8))
/* Disable channel */
#define DMA_DISABLE_CHAN(ch) (0x00000000 | ((0x000000001 << (ch)) << 8))
/* Transfer Type & Flow Controller */
#define DMA_CTL_TTFC(type) (((type) & 0x7) << 20)
#define DMA_CTL_SMS(num) (((num) & 0x3) << 25) /* Src Master Select */
#define DMA_CTL_DMS(num) (((num) & 0x3) << 23)/* Dst Master Select */
/* Src Burst Transaction Length */
#define DMA_CTL_SRC_MSIZE(size) (((size) & 0x7) << 14)
/* Dst Burst Transaction Length */
#define DMA_CTL_DST_MSIZE(size) (((size) & 0x7) << 11)
/* Source Transfer Width */
#define DMA_CTL_SRC_TRWID(size) (((size) & 0x7) << 4)
/* Destination Transfer Width */
#define DMA_CTL_DST_TRWID(size) (((size) & 0x7) << 1)
/* Assign HW handshaking interface (x) to destination / source peripheral */
#define DMA_CFG_HW_HS_DEST(int_num) (((int_num) & 0xF) << 11)
#define DMA_CFG_HW_HS_SRC(int_num) (((int_num) & 0xF) << 7)
#define DMA_CFG_HW_CH_PRIOR(int_num) (((int_num) & 0xF) << 5)
#define DMA_LLP_LMS(addr, master) (((addr) & 0xfffffffc) | (master))
/*
* This define is used to set block chaining disabled in the control low
* register. It is already in little endian format so it can be &'d dirctly.
* It is essentially: cpu_to_le32(~(DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN))
*/
enum {
DMA_CTL_LLP_DISABLE_LE32 = 0xffffffe7,
DMA_CTL_TTFC_P2M_DMAC = 0x00000002, /* Per to mem, DMAC cntr */
DMA_CTL_TTFC_M2P_PER = 0x00000003, /* Mem to per, peripheral cntr */
DMA_CTL_SINC_INC = 0x00000000, /* Source Address Increment */
DMA_CTL_SINC_DEC = 0x00000200,
DMA_CTL_SINC_NOCHANGE = 0x00000400,
DMA_CTL_DINC_INC = 0x00000000, /* Destination Address Increment */
DMA_CTL_DINC_DEC = 0x00000080,
DMA_CTL_DINC_NOCHANGE = 0x00000100,
DMA_CTL_INT_EN = 0x00000001, /* Interrupt Enable */
/* Channel Configuration Register high bits */
DMA_CFG_FCMOD_REQ = 0x00000001, /* Flow Control - request based */
DMA_CFG_PROTCTL = (0x00000003 << 2),/* Protection Control */
/* Channel Configuration Register low bits */
DMA_CFG_RELD_DST = 0x80000000, /* Reload Dest / Src Addr */
DMA_CFG_RELD_SRC = 0x40000000,
DMA_CFG_HS_SELSRC = 0x00000800, /* Software handshake Src/ Dest */
DMA_CFG_HS_SELDST = 0x00000400,
DMA_CFG_FIFOEMPTY = (0x00000001 << 9), /* FIFO Empty bit */
/* Channel Linked List Pointer Register */
DMA_LLP_AHBMASTER1 = 0, /* List Master Select */
DMA_LLP_AHBMASTER2 = 1,
SATA_DWC_MAX_PORTS = 1,
SATA_DWC_SCR_OFFSET = 0x24,
......@@ -287,7 +148,7 @@ struct sata_dwc_device {
struct ata_host *host;
u8 __iomem *reg_base;
struct sata_dwc_regs *sata_dwc_regs; /* DW Synopsys SATA specific */
int irq_dma;
struct dw_dma_chip *dma;
};
#define SATA_DWC_QCMD_MAX 32
......@@ -295,10 +156,13 @@ struct sata_dwc_device {
struct sata_dwc_device_port {
struct sata_dwc_device *hsdev;
int cmd_issued[SATA_DWC_QCMD_MAX];
struct lli *llit[SATA_DWC_QCMD_MAX]; /* DMA LLI table */
dma_addr_t llit_dma[SATA_DWC_QCMD_MAX];
u32 dma_chan[SATA_DWC_QCMD_MAX];
int dma_pending[SATA_DWC_QCMD_MAX];
/* DMA info */
struct dw_dma_slave *dws;
struct dma_chan *chan;
struct dma_async_tx_descriptor *desc[SATA_DWC_QCMD_MAX];
u32 dma_interrupt_count;
};
/*
......@@ -330,14 +194,17 @@ struct sata_dwc_host_priv {
void __iomem *scr_addr_sstatus;
u32 sata_dwc_sactive_issued ;
u32 sata_dwc_sactive_queued ;
u32 dma_interrupt_count;
struct ahb_dma_regs *sata_dma_regs;
struct device *dwc_dev;
int dma_channel;
};
static struct sata_dwc_host_priv host_pvt;
static struct dw_dma_slave sata_dwc_dma_dws = {
.src_id = 0,
.dst_id = 0,
.src_master = 0,
.dst_master = 1,
};
/*
* Prototypes
*/
......@@ -347,12 +214,6 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,
static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status);
static void sata_dwc_port_stop(struct ata_port *ap);
static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag);
static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq);
static void dma_dwc_exit(struct sata_dwc_device *hsdev);
static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
struct lli *lli, dma_addr_t dma_lli,
void __iomem *addr, int dir);
static void dma_dwc_xfer_start(int dma_ch);
static const char *get_prot_descript(u8 protocol)
{
......@@ -390,90 +251,23 @@ static const char *get_dma_dir_descript(int dma_dir)
}
}
static void sata_dwc_tf_dump(struct ata_taskfile *tf)
static void sata_dwc_tf_dump(struct ata_port *ap, struct ata_taskfile *tf)
{
dev_vdbg(host_pvt.dwc_dev, "taskfile cmd: 0x%02x protocol: %s flags:"
"0x%lx device: %x\n", tf->command,
get_prot_descript(tf->protocol), tf->flags, tf->device);
dev_vdbg(host_pvt.dwc_dev, "feature: 0x%02x nsect: 0x%x lbal: 0x%x "
"lbam: 0x%x lbah: 0x%x\n", tf->feature, tf->nsect, tf->lbal,
tf->lbam, tf->lbah);
dev_vdbg(host_pvt.dwc_dev, "hob_feature: 0x%02x hob_nsect: 0x%x "
"hob_lbal: 0x%x hob_lbam: 0x%x hob_lbah: 0x%x\n",
dev_vdbg(ap->dev,
"taskfile cmd: 0x%02x protocol: %s flags: 0x%lx device: %x\n",
tf->command, get_prot_descript(tf->protocol), tf->flags,
tf->device);
dev_vdbg(ap->dev,
"feature: 0x%02x nsect: 0x%x lbal: 0x%x lbam: 0x%x lbah: 0x%x\n",
tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah);
dev_vdbg(ap->dev,
"hob_feature: 0x%02x hob_nsect: 0x%x hob_lbal: 0x%x hob_lbam: 0x%x hob_lbah: 0x%x\n",
tf->hob_feature, tf->hob_nsect, tf->hob_lbal, tf->hob_lbam,
tf->hob_lbah);
}
/*
* Function: get_burst_length_encode
* arguments: datalength: length in bytes of data
* returns value to be programmed in register corresponding to data length
* This value is effectively the log(base 2) of the length
*/
static int get_burst_length_encode(int datalength)
{
int items = datalength >> 2; /* div by 4 to get lword count */
if (items >= 64)
return 5;
if (items >= 32)
return 4;
if (items >= 16)
return 3;
if (items >= 8)
return 2;
if (items >= 4)
return 1;
return 0;
}
static void clear_chan_interrupts(int c)
static void dma_dwc_xfer_done(void *hsdev_instance)
{
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.tfr.low),
DMA_CHANNEL(c));
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.block.low),
DMA_CHANNEL(c));
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.srctran.low),
DMA_CHANNEL(c));
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.dsttran.low),
DMA_CHANNEL(c));
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.error.low),
DMA_CHANNEL(c));
}
/*
* Function: dma_request_channel
* arguments: None
* returns channel number if available else -1
* This function assigns the next available DMA channel from the list to the
* requester
*/
static int dma_request_channel(void)
{
/* Check if the channel is not currently in use */
if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &
DMA_CHANNEL(host_pvt.dma_channel)))
return host_pvt.dma_channel;
dev_err(host_pvt.dwc_dev, "%s Channel %d is currently in use\n",
__func__, host_pvt.dma_channel);
return -1;
}
/*
* Function: dma_dwc_interrupt
* arguments: irq, dev_id, pt_regs
* returns channel number if available else -1
* Interrupt Handler for DW AHB SATA DMA
*/
static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
{
int chan;
u32 tfr_reg, err_reg;
unsigned long flags;
struct sata_dwc_device *hsdev = hsdev_instance;
struct ata_host *host = (struct ata_host *)hsdev->host;
......@@ -487,341 +281,65 @@ static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
hsdevp = HSDEVP_FROM_AP(ap);
tag = ap->link.active_tag;
tfr_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.tfr\
.low));
err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error\
.low));
dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n",
tfr_reg, err_reg, hsdevp->dma_pending[tag], port);
chan = host_pvt.dma_channel;
if (chan >= 0) {
/* Check for end-of-transfer interrupt. */
if (tfr_reg & DMA_CHANNEL(chan)) {
/*
* Each DMA command produces 2 interrupts. Only
* complete the command after both interrupts have been
* seen. (See sata_dwc_isr())
*/
host_pvt.dma_interrupt_count++;
sata_dwc_clear_dmacr(hsdevp, tag);
if (hsdevp->dma_pending[tag] ==
SATA_DWC_DMA_PENDING_NONE) {
dev_err(ap->dev, "DMA not pending eot=0x%08x "
"err=0x%08x tag=0x%02x pending=%d\n",
tfr_reg, err_reg, tag,
hsdevp->dma_pending[tag]);
}
if ((host_pvt.dma_interrupt_count % 2) == 0)
sata_dwc_dma_xfer_complete(ap, 1);
/* Clear the interrupt */
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
.tfr.low),
DMA_CHANNEL(chan));
}
/* Check for error interrupt. */
if (err_reg & DMA_CHANNEL(chan)) {
/* TODO Need error handler ! */
dev_err(ap->dev, "error interrupt err_reg=0x%08x\n",
err_reg);
/* Clear the interrupt. */
out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
.error.low),
DMA_CHANNEL(chan));
}
}
spin_unlock_irqrestore(&host->lock, flags);
return IRQ_HANDLED;
}
/*
* Function: dma_request_interrupts
* arguments: hsdev
* returns status
* This function registers ISR for a particular DMA channel interrupt
*/
static int dma_request_interrupts(struct sata_dwc_device *hsdev, int irq)
{
int retval = 0;
int chan = host_pvt.dma_channel;
if (chan >= 0) {
/* Unmask error interrupt */
out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.error.low,
DMA_ENABLE_CHAN(chan));
/* Unmask end-of-transfer interrupt */
out_le32(&(host_pvt.sata_dma_regs)->interrupt_mask.tfr.low,
DMA_ENABLE_CHAN(chan));
}
retval = request_irq(irq, dma_dwc_interrupt, 0, "SATA DMA", hsdev);
if (retval) {
dev_err(host_pvt.dwc_dev, "%s: could not get IRQ %d\n",
__func__, irq);
return -ENODEV;
}
/* Mark this interrupt as requested */
hsdev->irq_dma = irq;
return 0;
}
/*
* Function: map_sg_to_lli
* The Synopsis driver has a comment proposing that better performance
* is possible by only enabling interrupts on the last item in the linked list.
* However, it seems that could be a problem if an error happened on one of the
* first items. The transfer would halt, but no error interrupt would occur.
* Currently this function sets interrupts enabled for each linked list item:
* DMA_CTL_INT_EN.
*/
static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
struct lli *lli, dma_addr_t dma_lli,
void __iomem *dmadr_addr, int dir)
{
int i, idx = 0;
int fis_len = 0;
dma_addr_t next_llp;
int bl;
int sms_val, dms_val;
sms_val = 0;
dms_val = 1 + host_pvt.dma_channel;
dev_dbg(host_pvt.dwc_dev,
"%s: sg=%p nelem=%d lli=%p dma_lli=0x%pad dmadr=0x%p\n",
__func__, sg, num_elems, lli, &dma_lli, dmadr_addr);
bl = get_burst_length_encode(AHB_DMA_BRST_DFLT);
for (i = 0; i < num_elems; i++, sg++) {
u32 addr, offset;
u32 sg_len, len;
addr = (u32) sg_dma_address(sg);
sg_len = sg_dma_len(sg);
dev_dbg(host_pvt.dwc_dev, "%s: elem=%d sg_addr=0x%x sg_len"
"=%d\n", __func__, i, addr, sg_len);
while (sg_len) {
if (idx >= SATA_DWC_DMAC_LLI_NUM) {
/* The LLI table is not large enough. */
dev_err(host_pvt.dwc_dev, "LLI table overrun "
"(idx=%d)\n", idx);
break;
}
len = (sg_len > SATA_DWC_DMAC_CTRL_TSIZE_MAX) ?
SATA_DWC_DMAC_CTRL_TSIZE_MAX : sg_len;
offset = addr & 0xffff;
if ((offset + sg_len) > 0x10000)
len = 0x10000 - offset;
/*
* Make sure a LLI block is not created that will span
* 8K max FIS boundary. If the block spans such a FIS
* boundary, there is a chance that a DMA burst will
* cross that boundary -- this results in an error in
* the host controller.
*/
if (fis_len + len > 8192) {
dev_dbg(host_pvt.dwc_dev, "SPLITTING: fis_len="
"%d(0x%x) len=%d(0x%x)\n", fis_len,
fis_len, len, len);
len = 8192 - fis_len;
fis_len = 0;
} else {
fis_len += len;
}
if (fis_len == 8192)
fis_len = 0;
/*
* Set DMA addresses and lower half of control register
* based on direction.
*/
if (dir == DMA_FROM_DEVICE) {
lli[idx].dar = cpu_to_le32(addr);
lli[idx].sar = cpu_to_le32((u32)dmadr_addr);
lli[idx].ctl.low = cpu_to_le32(
DMA_CTL_TTFC(DMA_CTL_TTFC_P2M_DMAC) |
DMA_CTL_SMS(sms_val) |
DMA_CTL_DMS(dms_val) |
DMA_CTL_SRC_MSIZE(bl) |
DMA_CTL_DST_MSIZE(bl) |
DMA_CTL_SINC_NOCHANGE |
DMA_CTL_SRC_TRWID(2) |
DMA_CTL_DST_TRWID(2) |
DMA_CTL_INT_EN |
DMA_CTL_LLP_SRCEN |
DMA_CTL_LLP_DSTEN);
} else { /* DMA_TO_DEVICE */
lli[idx].sar = cpu_to_le32(addr);
lli[idx].dar = cpu_to_le32((u32)dmadr_addr);
lli[idx].ctl.low = cpu_to_le32(
DMA_CTL_TTFC(DMA_CTL_TTFC_M2P_PER) |
DMA_CTL_SMS(dms_val) |
DMA_CTL_DMS(sms_val) |
DMA_CTL_SRC_MSIZE(bl) |
DMA_CTL_DST_MSIZE(bl) |
DMA_CTL_DINC_NOCHANGE |
DMA_CTL_SRC_TRWID(2) |
DMA_CTL_DST_TRWID(2) |
DMA_CTL_INT_EN |
DMA_CTL_LLP_SRCEN |
DMA_CTL_LLP_DSTEN);
}
dev_dbg(host_pvt.dwc_dev, "%s setting ctl.high len: "
"0x%08x val: 0x%08x\n", __func__,
len, DMA_CTL_BLK_TS(len / 4));
/* Program the LLI CTL high register */
lli[idx].ctl.high = cpu_to_le32(DMA_CTL_BLK_TS\
(len / 4));
/* Program the next pointer. The next pointer must be
* the physical address, not the virtual address.
*/
next_llp = (dma_lli + ((idx + 1) * sizeof(struct \
lli)));
/* The last 2 bits encode the list master select. */
next_llp = DMA_LLP_LMS(next_llp, DMA_LLP_AHBMASTER2);
lli[idx].llp = cpu_to_le32(next_llp);
idx++;
sg_len -= len;
addr += len;
}
}
/*
* The last next ptr has to be zero and the last control low register
* has to have LLP_SRC_EN and LLP_DST_EN (linked list pointer source
* and destination enable) set back to 0 (disabled.) This is what tells
* the core that this is the last item in the linked list.
* Each DMA command produces 2 interrupts. Only
* complete the command after both interrupts have been
* seen. (See sata_dwc_isr())
*/
if (idx) {
lli[idx-1].llp = 0x00000000;
lli[idx-1].ctl.low &= DMA_CTL_LLP_DISABLE_LE32;
hsdevp->dma_interrupt_count++;
sata_dwc_clear_dmacr(hsdevp, tag);
/* Flush cache to memory */
dma_cache_sync(NULL, lli, (sizeof(struct lli) * idx),
DMA_BIDIRECTIONAL);
if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_NONE) {
dev_err(ap->dev, "DMA not pending tag=0x%02x pending=%d\n",
tag, hsdevp->dma_pending[tag]);
}
return idx;
}
if ((hsdevp->dma_interrupt_count % 2) == 0)
sata_dwc_dma_xfer_complete(ap, 1);
/*
* Function: dma_dwc_xfer_start
* arguments: Channel number
* Return : None
* Enables the DMA channel
*/
static void dma_dwc_xfer_start(int dma_ch)
{
/* Enable the DMA channel */
out_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low),
in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) |
DMA_ENABLE_CHAN(dma_ch));
spin_unlock_irqrestore(&host->lock, flags);
}
static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
struct lli *lli, dma_addr_t dma_lli,
void __iomem *addr, int dir)
static struct dma_async_tx_descriptor *dma_dwc_xfer_setup(struct ata_queued_cmd *qc)
{
int dma_ch;
int num_lli;
/* Acquire DMA channel */
dma_ch = dma_request_channel();
if (dma_ch == -1) {
dev_err(host_pvt.dwc_dev, "%s: dma channel unavailable\n",
__func__);
return -EAGAIN;
struct ata_port *ap = qc->ap;
struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
dma_addr_t addr = (dma_addr_t)&hsdev->sata_dwc_regs->dmadr;
struct dma_slave_config sconf;
struct dma_async_tx_descriptor *desc;
if (qc->dma_dir == DMA_DEV_TO_MEM) {
sconf.src_addr = addr;
sconf.device_fc = true;
} else { /* DMA_MEM_TO_DEV */
sconf.dst_addr = addr;
sconf.device_fc = false;
}
/* Convert SG list to linked list of items (LLIs) for AHB DMA */
num_lli = map_sg_to_lli(sg, num_elems, lli, dma_lli, addr, dir);
dev_dbg(host_pvt.dwc_dev, "%s sg: 0x%p, count: %d lli: %p dma_lli:"
" 0x%0xlx addr: %p lli count: %d\n", __func__, sg, num_elems,
lli, (u32)dma_lli, addr, num_lli);
clear_chan_interrupts(dma_ch);
sconf.direction = qc->dma_dir;
sconf.src_maxburst = AHB_DMA_BRST_DFLT;
sconf.dst_maxburst = AHB_DMA_BRST_DFLT;
sconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
sconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
/* Program the CFG register. */
out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.high),
DMA_CFG_HW_HS_SRC(dma_ch) | DMA_CFG_HW_HS_DEST(dma_ch) |
DMA_CFG_PROTCTL | DMA_CFG_FCMOD_REQ);
out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.low),
DMA_CFG_HW_CH_PRIOR(dma_ch));
dmaengine_slave_config(hsdevp->chan, &sconf);
/* Program the address of the linked list */
out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].llp.low),
DMA_LLP_LMS(dma_lli, DMA_LLP_AHBMASTER2));
/* Program the CTL register with src enable / dst enable */
out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].ctl.low),
DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN);
return dma_ch;
}
/*
* Function: dma_dwc_exit
* arguments: None
* returns status
* This function exits the SATA DMA driver
*/
static void dma_dwc_exit(struct sata_dwc_device *hsdev)
{
dev_dbg(host_pvt.dwc_dev, "%s:\n", __func__);
if (host_pvt.sata_dma_regs) {
iounmap((void __iomem *)host_pvt.sata_dma_regs);
host_pvt.sata_dma_regs = NULL;
}
if (hsdev->irq_dma) {
free_irq(hsdev->irq_dma, hsdev);
hsdev->irq_dma = 0;
}
}
/*
* Function: dma_dwc_init
* arguments: hsdev
* returns status
* This function initializes the SATA DMA driver
*/
static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
{
int err;
/* Convert SG list to linked list of items (LLIs) for AHB DMA */
desc = dmaengine_prep_slave_sg(hsdevp->chan, qc->sg, qc->n_elem,
qc->dma_dir,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
err = dma_request_interrupts(hsdev, irq);
if (err) {
dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns"
" %d\n", __func__, err);
return err;
}
if (!desc)
return NULL;
/* Enabe DMA */
out_le32(&(host_pvt.sata_dma_regs->dma_cfg.low), DMA_EN);
desc->callback = dma_dwc_xfer_done;
desc->callback_param = hsdev;
dev_notice(host_pvt.dwc_dev, "DMA initialized\n");
dev_dbg(host_pvt.dwc_dev, "SATA DMA registers=0x%p\n", host_pvt.\
sata_dma_regs);
dev_dbg(hsdev->dev, "%s sg: 0x%p, count: %d addr: %pad\n",
__func__, qc->sg, qc->n_elem, &addr);
return 0;
return desc;
}
static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
......@@ -891,21 +409,18 @@ static void sata_dwc_error_intr(struct ata_port *ap,
struct ata_queued_cmd *qc;
u32 serror;
u8 status, tag;
u32 err_reg;
ata_ehi_clear_desc(ehi);
serror = core_scr_read(SCR_ERROR);
status = ap->ops->sff_check_status(ap);
err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error.\
low));
tag = ap->link.active_tag;
dev_err(ap->dev, "%s SCR_ERROR=0x%08x intpr=0x%08x status=0x%08x "
"dma_intp=%d pending=%d issued=%d dma_err_status=0x%08x\n",
__func__, serror, intpr, status, host_pvt.dma_interrupt_count,
hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag], err_reg);
dev_err(ap->dev,
"%s SCR_ERROR=0x%08x intpr=0x%08x status=0x%08x dma_intp=%d pending=%d issued=%d",
__func__, serror, intpr, status, hsdevp->dma_interrupt_count,
hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag]);
/* Clear error register and interrupt bit */
clear_serror();
......@@ -1003,8 +518,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
/* DEV interrupt w/ no active qc? */
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
dev_err(ap->dev, "%s interrupt with no active qc "
"qc=%p\n", __func__, qc);
dev_err(ap->dev,
"%s interrupt with no active qc qc=%p\n",
__func__, qc);
ap->ops->sff_check_status(ap);
handled = 1;
goto DONE;
......@@ -1031,16 +547,16 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
* operation done interrupt. The command should be
* completed only after both interrupts are seen.
*/
host_pvt.dma_interrupt_count++;
hsdevp->dma_interrupt_count++;
if (hsdevp->dma_pending[tag] == \
SATA_DWC_DMA_PENDING_NONE) {
dev_err(ap->dev, "%s: DMA not pending "
"intpr=0x%08x status=0x%08x pending"
"=%d\n", __func__, intpr, status,
dev_err(ap->dev,
"%s: DMA not pending intpr=0x%08x status=0x%08x pending=%d\n",
__func__, intpr, status,
hsdevp->dma_pending[tag]);
}
if ((host_pvt.dma_interrupt_count % 2) == 0)
if ((hsdevp->dma_interrupt_count % 2) == 0)
sata_dwc_dma_xfer_complete(ap, 1);
} else if (ata_is_pio(qc->tf.protocol)) {
ata_sff_hsm_move(ap, qc, status, 0);
......@@ -1068,17 +584,17 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
if (sactive != 0 || (host_pvt.sata_dwc_sactive_issued) > 1 || \
tag_mask > 1) {
dev_dbg(ap->dev, "%s NCQ:sactive=0x%08x sactive_issued=0x%08x"
"tag_mask=0x%08x\n", __func__, sactive,
host_pvt.sata_dwc_sactive_issued, tag_mask);
dev_dbg(ap->dev,
"%s NCQ:sactive=0x%08x sactive_issued=0x%08x tag_mask=0x%08x\n",
__func__, sactive, host_pvt.sata_dwc_sactive_issued,
tag_mask);
}
if ((tag_mask | (host_pvt.sata_dwc_sactive_issued)) != \
(host_pvt.sata_dwc_sactive_issued)) {
dev_warn(ap->dev, "Bad tag mask? sactive=0x%08x "
"(host_pvt.sata_dwc_sactive_issued)=0x%08x tag_mask"
"=0x%08x\n", sactive, host_pvt.sata_dwc_sactive_issued,
tag_mask);
dev_warn(ap->dev,
"Bad tag mask? sactive=0x%08x (host_pvt.sata_dwc_sactive_issued)=0x%08x tag_mask=0x%08x\n",
sactive, host_pvt.sata_dwc_sactive_issued, tag_mask);
}
/* read just to clear ... not bad if currently still busy */
......@@ -1114,12 +630,12 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
dev_dbg(ap->dev, "%s NCQ command, protocol: %s\n", __func__,
get_prot_descript(qc->tf.protocol));
if (ata_is_dma(qc->tf.protocol)) {
host_pvt.dma_interrupt_count++;
hsdevp->dma_interrupt_count++;
if (hsdevp->dma_pending[tag] == \
SATA_DWC_DMA_PENDING_NONE)
dev_warn(ap->dev, "%s: DMA not pending?\n",
__func__);
if ((host_pvt.dma_interrupt_count % 2) == 0)
if ((hsdevp->dma_interrupt_count % 2) == 0)
sata_dwc_dma_xfer_complete(ap, 1);
} else {
if (unlikely(sata_dwc_qc_complete(ap, qc, 1)))
......@@ -1142,8 +658,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
*/
sactive2 = core_scr_read(SCR_ACTIVE);
if (sactive2 != sactive) {
dev_dbg(ap->dev, "More completed - sactive=0x%x sactive2"
"=0x%x\n", sactive, sactive2);
dev_dbg(ap->dev,
"More completed - sactive=0x%x sactive2=0x%x\n",
sactive, sactive2);
}
handled = 1;
......@@ -1169,11 +686,10 @@ static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag)
* This should not happen, it indicates the driver is out of
* sync. If it does happen, clear dmacr anyway.
*/
dev_err(host_pvt.dwc_dev, "%s DMA protocol RX and"
"TX DMA not pending tag=0x%02x pending=%d"
" dmacr: 0x%08x\n", __func__, tag,
hsdevp->dma_pending[tag],
in_le32(&(hsdev->sata_dwc_regs->dmacr)));
dev_err(hsdev->dev,
"%s DMA protocol RX and TX DMA not pending tag=0x%02x pending=%d dmacr: 0x%08x\n",
__func__, tag, hsdevp->dma_pending[tag],
in_le32(&hsdev->sata_dwc_regs->dmacr));
out_le32(&(hsdev->sata_dwc_regs->dmacr),
SATA_DWC_DMACR_TXRXCH_CLEAR);
}
......@@ -1195,8 +711,9 @@ static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status)
#ifdef DEBUG_NCQ
if (tag > 0) {
dev_info(ap->dev, "%s tag=%u cmd=0x%02x dma dir=%s proto=%s "
"dmacr=0x%08x\n", __func__, qc->tag, qc->tf.command,
dev_info(ap->dev,
"%s tag=%u cmd=0x%02x dma dir=%s proto=%s dmacr=0x%08x\n",
__func__, qc->tag, qc->tf.command,
get_dma_dir_descript(qc->dma_dir),
get_prot_descript(qc->tf.protocol),
in_le32(&(hsdev->sata_dwc_regs->dmacr)));
......@@ -1205,8 +722,9 @@ static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status)
if (ata_is_dma(qc->tf.protocol)) {
if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_NONE) {
dev_err(ap->dev, "%s DMA protocol RX and TX DMA not "
"pending dmacr: 0x%08x\n", __func__,
dev_err(ap->dev,
"%s DMA protocol RX and TX DMA not pending dmacr: 0x%08x\n",
__func__,
in_le32(&(hsdev->sata_dwc_regs->dmacr)));
}
......@@ -1232,9 +750,9 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc,
dev_err(ap->dev, "TX DMA PENDING\n");
else if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_RX)
dev_err(ap->dev, "RX DMA PENDING\n");
dev_dbg(ap->dev, "QC complete cmd=0x%02x status=0x%02x ata%u:"
" protocol=%d\n", qc->tf.command, status, ap->print_id,
qc->tf.protocol);
dev_dbg(ap->dev,
"QC complete cmd=0x%02x status=0x%02x ata%u: protocol=%d\n",
qc->tf.command, status, ap->print_id, qc->tf.protocol);
/* clear active bit */
mask = (~(qcmd_tag_to_mask(tag)));
......@@ -1260,11 +778,23 @@ static void sata_dwc_enable_interrupts(struct sata_dwc_device *hsdev)
*/
out_le32(&hsdev->sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS);
dev_dbg(host_pvt.dwc_dev, "%s: INTMR = 0x%08x, ERRMR = 0x%08x\n",
dev_dbg(hsdev->dev, "%s: INTMR = 0x%08x, ERRMR = 0x%08x\n",
__func__, in_le32(&hsdev->sata_dwc_regs->intmr),
in_le32(&hsdev->sata_dwc_regs->errmr));
}
static bool sata_dwc_dma_filter(struct dma_chan *chan, void *param)
{
struct sata_dwc_device_port *hsdevp = param;
struct dw_dma_slave *dws = hsdevp->dws;
if (dws->dma_dev != chan->device->dev)
return false;
chan->private = dws;
return true;
}
static void sata_dwc_setup_port(struct ata_ioports *port, unsigned long base)
{
port->cmd_addr = (void __iomem *)base + 0x00;
......@@ -1299,6 +829,7 @@ static int sata_dwc_port_start(struct ata_port *ap)
struct sata_dwc_device *hsdev;
struct sata_dwc_device_port *hsdevp = NULL;
struct device *pdev;
dma_cap_mask_t mask;
int i;
hsdev = HSDEV_FROM_AP(ap);
......@@ -1322,29 +853,27 @@ static int sata_dwc_port_start(struct ata_port *ap)
}
hsdevp->hsdev = hsdev;
hsdevp->dws = &sata_dwc_dma_dws;
hsdevp->dws->dma_dev = hsdev->dev;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
/* Acquire DMA channel */
hsdevp->chan = dma_request_channel(mask, sata_dwc_dma_filter, hsdevp);
if (!hsdevp->chan) {
dev_err(hsdev->dev, "%s: dma channel unavailable\n",
__func__);
err = -EAGAIN;
goto CLEANUP_ALLOC;
}
for (i = 0; i < SATA_DWC_QCMD_MAX; i++)
hsdevp->cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT;
ap->bmdma_prd = NULL; /* set these so libata doesn't use them */
ap->bmdma_prd_dma = 0;
/*
* DMA - Assign scatter gather LLI table. We can't use the libata
* version since it's PRD is IDE PCI specific.
*/
for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
hsdevp->llit[i] = dma_alloc_coherent(pdev,
SATA_DWC_DMAC_LLI_TBL_SZ,
&(hsdevp->llit_dma[i]),
GFP_ATOMIC);
if (!hsdevp->llit[i]) {
dev_err(ap->dev, "%s: dma_alloc_coherent failed\n",
__func__);
err = -ENOMEM;
goto CLEANUP_ALLOC;
}
}
if (ap->port_no == 0) {
dev_dbg(ap->dev, "%s: clearing TXCHEN, RXCHEN in DMAC\n",
__func__);
......@@ -1373,22 +902,14 @@ static int sata_dwc_port_start(struct ata_port *ap)
static void sata_dwc_port_stop(struct ata_port *ap)
{
int i;
struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
dev_dbg(ap->dev, "%s: ap->id = %d\n", __func__, ap->print_id);
if (hsdevp && hsdev) {
/* deallocate LLI table */
for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
dma_free_coherent(ap->host->dev,
SATA_DWC_DMAC_LLI_TBL_SZ,
hsdevp->llit[i], hsdevp->llit_dma[i]);
}
dmaengine_terminate_all(hsdevp->chan);
dma_release_channel(hsdevp->chan);
kfree(hsdevp);
}
kfree(hsdevp);
ap->private_data = NULL;
}
......@@ -1444,12 +965,12 @@ static void sata_dwc_bmdma_setup(struct ata_queued_cmd *qc)
static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag)
{
int start_dma;
u32 reg, dma_chan;
u32 reg;
struct sata_dwc_device *hsdev = HSDEV_FROM_QC(qc);
struct ata_port *ap = qc->ap;
struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
struct dma_async_tx_descriptor *desc = hsdevp->desc[tag];
int dir = qc->dma_dir;
dma_chan = hsdevp->dma_chan[tag];
if (hsdevp->cmd_issued[tag] != SATA_DWC_CMD_ISSUED_NOT) {
start_dma = 1;
......@@ -1458,16 +979,17 @@ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag)
else
hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_RX;
} else {
dev_err(ap->dev, "%s: Command not pending cmd_issued=%d "
"(tag=%d) DMA NOT started\n", __func__,
hsdevp->cmd_issued[tag], tag);
dev_err(ap->dev,
"%s: Command not pending cmd_issued=%d (tag=%d) DMA NOT started\n",
__func__, hsdevp->cmd_issued[tag], tag);
start_dma = 0;
}
dev_dbg(ap->dev, "%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s "
"start_dma? %x\n", __func__, qc, tag, qc->tf.command,
dev_dbg(ap->dev,
"%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s start_dma? %x\n",
__func__, qc, tag, qc->tf.command,
get_dma_dir_descript(qc->dma_dir), start_dma);
sata_dwc_tf_dump(&(qc->tf));
sata_dwc_tf_dump(ap, &qc->tf);
if (start_dma) {
reg = core_scr_read(SCR_ERROR);
......@@ -1484,7 +1006,8 @@ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag)
SATA_DWC_DMACR_RXCHEN);
/* Enable AHB DMA transfer on the specified channel */
dma_dwc_xfer_start(dma_chan);
dmaengine_submit(desc);
dma_async_issue_pending(hsdevp->chan);
}
}
......@@ -1510,26 +1033,21 @@ static void sata_dwc_bmdma_start(struct ata_queued_cmd *qc)
*/
static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag)
{
struct scatterlist *sg = qc->sg;
struct dma_async_tx_descriptor *desc;
struct ata_port *ap = qc->ap;
int dma_chan;
struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap);
struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n",
__func__, ap->port_no, get_dma_dir_descript(qc->dma_dir),
qc->n_elem);
dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag],
hsdevp->llit_dma[tag],
(void __iomem *)&hsdev->sata_dwc_regs->dmadr,
qc->dma_dir);
if (dma_chan < 0) {
dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns err %d\n",
__func__, dma_chan);
desc = dma_dwc_xfer_setup(qc);
if (!desc) {
dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns NULL\n",
__func__);
return;
}
hsdevp->dma_chan[tag] = dma_chan;
hsdevp->desc[tag] = desc;
}
static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
......@@ -1540,8 +1058,8 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
#ifdef DEBUG_NCQ
if (qc->tag > 0 || ap->link.sactive > 1)
dev_info(ap->dev, "%s ap id=%d cmd(0x%02x)=%s qc tag=%d "
"prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n",
dev_info(ap->dev,
"%s ap id=%d cmd(0x%02x)=%s qc tag=%d prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n",
__func__, ap->print_id, qc->tf.command,
ata_get_cmd_descript(qc->tf.command),
qc->tag, get_prot_descript(qc->tf.protocol),
......@@ -1557,9 +1075,9 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc)
sactive |= (0x00000001 << tag);
core_scr_write(SCR_ACTIVE, sactive);
dev_dbg(qc->ap->dev, "%s: tag=%d ap->link.sactive = 0x%08x "
"sactive=0x%08x\n", __func__, tag, qc->ap->link.sactive,
sactive);
dev_dbg(qc->ap->dev,
"%s: tag=%d ap->link.sactive = 0x%08x sactive=0x%08x\n",
__func__, tag, qc->ap->link.sactive, sactive);
ap->ops->sff_tf_load(ap, &qc->tf);
sata_dwc_exec_command_by_tag(ap, &qc->tf, qc->tag,
......@@ -1673,7 +1191,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
struct ata_port_info pi = sata_dwc_port_info[0];
const struct ata_port_info *ppi[] = { &pi, NULL };
struct device_node *np = ofdev->dev.of_node;
u32 dma_chan;
/* Allocate DWC SATA device */
host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_DWC_MAX_PORTS);
......@@ -1683,18 +1200,11 @@ static int sata_dwc_probe(struct platform_device *ofdev)
host->private_data = hsdev;
if (of_property_read_u32(np, "dma-channel", &dma_chan)) {
dev_warn(&ofdev->dev, "no dma-channel property set."
" Use channel 0\n");
dma_chan = 0;
}
host_pvt.dma_channel = dma_chan;
/* Ioremap SATA registers */
base = of_iomap(np, 0);
if (!base) {
dev_err(&ofdev->dev, "ioremap failed for SATA register"
" address\n");
dev_err(&ofdev->dev,
"ioremap failed for SATA register address\n");
return -ENODEV;
}
hsdev->reg_base = base;
......@@ -1716,27 +1226,29 @@ static int sata_dwc_probe(struct platform_device *ofdev)
idr, ver[0], ver[1], ver[2]);
/* Get SATA DMA interrupt number */
irq = irq_of_parse_and_map(np, 1);
if (irq == NO_IRQ) {
hsdev->dma->irq = irq_of_parse_and_map(np, 1);
if (hsdev->dma->irq == NO_IRQ) {
dev_err(&ofdev->dev, "no SATA DMA irq\n");
err = -ENODEV;
goto error_iomap;
}
/* Get physical SATA DMA register base address */
host_pvt.sata_dma_regs = (void *)of_iomap(np, 1);
if (!(host_pvt.sata_dma_regs)) {
dev_err(&ofdev->dev, "ioremap failed for AHBDMA register"
" address\n");
hsdev->dma->regs = of_iomap(np, 1);
if (!hsdev->dma->regs) {
dev_err(&ofdev->dev,
"ioremap failed for AHBDMA register address\n");
err = -ENODEV;
goto error_iomap;
}
/* Save dev for later use in dev_xxx() routines */
host_pvt.dwc_dev = &ofdev->dev;
hsdev->dev = &ofdev->dev;
hsdev->dma->dev = &ofdev->dev;
/* Initialize AHB DMAC */
err = dma_dwc_init(hsdev, irq);
err = dw_dma_probe(hsdev->dma, NULL);
if (err)
goto error_dma_iomap;
......@@ -1765,9 +1277,9 @@ static int sata_dwc_probe(struct platform_device *ofdev)
error_out:
/* Free SATA DMA resources */
dma_dwc_exit(hsdev);
dw_dma_remove(hsdev->dma);
error_dma_iomap:
iounmap((void __iomem *)host_pvt.sata_dma_regs);
iounmap(hsdev->dma->regs);
error_iomap:
iounmap(base);
return err;
......@@ -1782,9 +1294,9 @@ static int sata_dwc_remove(struct platform_device *ofdev)
ata_host_detach(host);
/* Free SATA DMA resources */
dma_dwc_exit(hsdev);
dw_dma_remove(hsdev->dma);
iounmap((void __iomem *)host_pvt.sata_dma_regs);
iounmap(hsdev->dma->regs);
iounmap(hsdev->reg_base);
dev_dbg(&ofdev->dev, "done\n");
return 0;
......@@ -1809,5 +1321,5 @@ module_platform_driver(sata_dwc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mark Miesfeld <mmiesfeld@amcc.com>");
MODULE_DESCRIPTION("DesignWare Cores SATA controller low lever driver");
MODULE_DESCRIPTION("DesignWare Cores SATA controller low level driver");
MODULE_VERSION(DRV_VERSION);
......@@ -856,13 +856,13 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Set dma_mask. This devices doesn't support 64bit addressing. */
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit consistent DMA enable failed\n");
return rc;
......
......@@ -306,6 +306,11 @@ enum {
MV5_PHY_CTL = 0x0C,
SATA_IFCFG = 0x050,
LP_PHY_CTL = 0x058,
LP_PHY_CTL_PIN_PU_PLL = (1 << 0),
LP_PHY_CTL_PIN_PU_RX = (1 << 1),
LP_PHY_CTL_PIN_PU_TX = (1 << 2),
LP_PHY_CTL_GEN_TX_3G = (1 << 5),
LP_PHY_CTL_GEN_RX_3G = (1 << 9),
MV_M2_PREAMP_MASK = 0x7e0,
......@@ -1391,10 +1396,17 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
/*
* Set PHY speed according to SControl speed.
*/
if ((val & 0xf0) == 0x10)
writelfl(0x7, lp_phy_addr);
else
writelfl(0x227, lp_phy_addr);
u32 lp_phy_val =
LP_PHY_CTL_PIN_PU_PLL |
LP_PHY_CTL_PIN_PU_RX |
LP_PHY_CTL_PIN_PU_TX;
if ((val & 0xf0) != 0x10)
lp_phy_val |=
LP_PHY_CTL_GEN_TX_3G |
LP_PHY_CTL_GEN_RX_3G;
writelfl(lp_phy_val, lp_phy_addr);
}
}
writelfl(val, addr);
......@@ -4308,10 +4320,10 @@ static int pci_go_64(struct pci_dev *pdev)
{
int rc;
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"64-bit DMA enable failed\n");
......@@ -4319,12 +4331,12 @@ static int pci_go_64(struct pci_dev *pdev)
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"32-bit consistent DMA enable failed\n");
......
......@@ -756,10 +756,10 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
blk_queue_bounce_limit(sdev1->request_queue,
ATA_DMA_MASK);
pci_set_dma_mask(pdev, ATA_DMA_MASK);
dma_set_mask(&pdev->dev, ATA_DMA_MASK);
} else {
/** This shouldn't fail as it was set to this value before */
pci_set_dma_mask(pdev, pp->adma_dma_mask);
dma_set_mask(&pdev->dev, pp->adma_dma_mask);
if (sdev0)
blk_queue_bounce_limit(sdev0->request_queue,
pp->adma_dma_mask);
......@@ -1133,10 +1133,10 @@ static int nv_adma_port_start(struct ata_port *ap)
/* Ensure DMA mask is set to 32-bit before allocating legacy PRD and
pad buffers */
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
return rc;
......@@ -1161,8 +1161,8 @@ static int nv_adma_port_start(struct ata_port *ap)
These are allowed to fail since we store the value that ends up
being used to set as the bounce limit in slave_config later if
needed. */
pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
pp->adma_dma_mask = *dev->dma_mask;
mem = dmam_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
......
......@@ -1246,10 +1246,10 @@ static int pdc_ata_init_one(struct pci_dev *pdev,
/* initialize adapter */
pdc_host_init(host);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -557,10 +557,10 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT);
if (have_64bit_bus &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"64-bit DMA enable failed\n");
......@@ -568,12 +568,12 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"32-bit consistent DMA enable failed\n");
......
......@@ -770,10 +770,10 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
host->iomap = pcim_iomap_table(pdev);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -246,7 +246,7 @@ enum {
/* host flags */
SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
ATA_FLAG_AN | ATA_FLAG_PMP | ATA_FLAG_LOWTAG,
ATA_FLAG_AN | ATA_FLAG_PMP,
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
IRQ_STAT_4PORTS = 0xf,
......@@ -1312,10 +1312,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->iomap = iomap;
/* configure and activate the device */
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"64-bit DMA enable failed\n");
......@@ -1323,12 +1323,12 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev, "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"32-bit consistent DMA enable failed\n");
......
......@@ -496,10 +496,10 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
ata_port_pbar_desc(ap, 5, offset, "port");
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -1476,10 +1476,10 @@ static int pdc_sata_init_one(struct pci_dev *pdev,
}
/* configure and activate */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -502,10 +502,10 @@ static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
for (i = 0; i < host->n_ports; i++)
vt6421_init_addrs(host->ports[i]);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
......
......@@ -387,10 +387,10 @@ static int vsc_sata_init_one(struct pci_dev *pdev,
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
*/
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
return rc;
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
return rc;
......
......@@ -148,8 +148,8 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
printk(KERN_CONT "DataRequest ");
if (stat & ATA_CORR)
printk(KERN_CONT "CorrectedError ");
if (stat & ATA_IDX)
printk(KERN_CONT "Index ");
if (stat & ATA_SENSE)
printk(KERN_CONT "Sense ");
if (stat & ATA_ERR)
printk(KERN_CONT "Error ");
}
......
......@@ -273,7 +273,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
(hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
a = tp_ops->read_altstatus(hwif);
s = tp_ops->read_status(hwif);
if ((a ^ s) & ~ATA_IDX)
if ((a ^ s) & ~ATA_SENSE)
/* ancient Seagate drives, broken interfaces */
printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
"instead of ALTSTATUS(0x%02x)\n",
......
......@@ -26,6 +26,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
......@@ -2586,3 +2587,33 @@ void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
}
}
EXPORT_SYMBOL(scsi_build_sense_buffer);
/**
* scsi_set_sense_information - set the information field in a
* formatted sense data buffer
* @buf: Where to build sense data
* @info: 64-bit information value to be set
*
**/
void scsi_set_sense_information(u8 *buf, u64 info)
{
if ((buf[0] & 0x7f) == 0x72) {
u8 *ucp, len;
len = buf[7];
ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
if (!ucp) {
buf[7] = len + 0xa;
ucp = buf + 8 + len;
}
ucp[0] = 0;
ucp[1] = 0xa;
ucp[2] = 0x80; /* Valid bit */
ucp[3] = 0;
put_unaligned_be64(info, &ucp[4]);
} else if ((buf[0] & 0x7f) == 0x70) {
buf[0] |= 0x80;
put_unaligned_be64(info, &buf[3]);
}
}
EXPORT_SYMBOL(scsi_set_sense_information);
......@@ -94,6 +94,8 @@ enum {
ATA_ID_SECTOR_SIZE = 106,
ATA_ID_WWN = 108,
ATA_ID_LOGICAL_SECTOR_SIZE = 117, /* and 118 */
ATA_ID_COMMAND_SET_3 = 119,
ATA_ID_COMMAND_SET_4 = 120,
ATA_ID_LAST_LUN = 126,
ATA_ID_DLF = 128,
ATA_ID_CSFO = 129,
......@@ -177,7 +179,7 @@ enum {
ATA_DSC = (1 << 4), /* drive seek complete */
ATA_DRQ = (1 << 3), /* data request i/o */
ATA_CORR = (1 << 2), /* corrected data error */
ATA_IDX = (1 << 1), /* index */
ATA_SENSE = (1 << 1), /* sense code available */
ATA_ERR = (1 << 0), /* have an error */
ATA_SRST = (1 << 2), /* software reset */
ATA_ICRC = (1 << 7), /* interface CRC error */
......@@ -382,6 +384,8 @@ enum {
SATA_SSP = 0x06, /* Software Settings Preservation */
SATA_DEVSLP = 0x09, /* Device Sleep */
SETFEATURE_SENSE_DATA = 0xC3, /* Sense Data Reporting feature */
/* feature values for SET_MAX */
ATA_SET_MAX_ADDR = 0x00,
ATA_SET_MAX_PASSWD = 0x01,
......@@ -525,6 +529,8 @@ struct ata_bmdma_prd {
#define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
#define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
#define ata_id_has_ncq_autosense(id) \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
static inline bool ata_id_has_hipm(const u16 *id)
{
......@@ -696,6 +702,27 @@ static inline bool ata_id_wcache_enabled(const u16 *id)
return id[ATA_ID_CFS_ENABLE_1] & (1 << 5);
}
static inline bool ata_id_has_read_log_dma_ext(const u16 *id)
{
if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
return false;
return id[ATA_ID_COMMAND_SET_3] & (1 << 3);
}
static inline bool ata_id_has_sense_reporting(const u16 *id)
{
if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
return false;
return id[ATA_ID_COMMAND_SET_3] & (1 << 6);
}
static inline bool ata_id_sense_reporting_enabled(const u16 *id)
{
if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
return false;
return id[ATA_ID_COMMAND_SET_4] & (1 << 6);
}
/**
* ata_id_major_version - get ATA level of drive
* @id: Identify data
......
......@@ -231,8 +231,7 @@ enum {
ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity
* led */
ATA_FLAG_NO_DIPM = (1 << 23), /* host not happy with DIPM */
ATA_FLAG_LOWTAG = (1 << 24), /* host wants lowest available tag */
ATA_FLAG_SAS_HOST = (1 << 25), /* SAS host */
ATA_FLAG_SAS_HOST = (1 << 24), /* SAS host */
/* bits 24:31 of ap->flags are reserved for LLD specific flags */
......
......@@ -59,6 +59,7 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
u64 * info_out);
extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
extern void scsi_set_sense_information(u8 *buf, u64 info);
extern int scsi_ioctl_reset(struct scsi_device *, int __user *);
......
#undef TRACE_SYSTEM
#define TRACE_SYSTEM libata
#if !defined(_TRACE_LIBATA_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_LIBATA_H
#include <linux/ata.h>
#include <linux/libata.h>
#include <linux/tracepoint.h>
#include <linux/trace_seq.h>
#define ata_opcode_name(opcode) { opcode, #opcode }
#define show_opcode_name(val) \
__print_symbolic(val, \
ata_opcode_name(ATA_CMD_DEV_RESET), \
ata_opcode_name(ATA_CMD_CHK_POWER), \
ata_opcode_name(ATA_CMD_STANDBY), \
ata_opcode_name(ATA_CMD_IDLE), \
ata_opcode_name(ATA_CMD_EDD), \
ata_opcode_name(ATA_CMD_DOWNLOAD_MICRO), \
ata_opcode_name(ATA_CMD_DOWNLOAD_MICRO_DMA), \
ata_opcode_name(ATA_CMD_NOP), \
ata_opcode_name(ATA_CMD_FLUSH), \
ata_opcode_name(ATA_CMD_FLUSH_EXT), \
ata_opcode_name(ATA_CMD_ID_ATA), \
ata_opcode_name(ATA_CMD_ID_ATAPI), \
ata_opcode_name(ATA_CMD_SERVICE), \
ata_opcode_name(ATA_CMD_READ), \
ata_opcode_name(ATA_CMD_READ_EXT), \
ata_opcode_name(ATA_CMD_READ_QUEUED), \
ata_opcode_name(ATA_CMD_READ_STREAM_EXT), \
ata_opcode_name(ATA_CMD_READ_STREAM_DMA_EXT), \
ata_opcode_name(ATA_CMD_WRITE), \
ata_opcode_name(ATA_CMD_WRITE_EXT), \
ata_opcode_name(ATA_CMD_WRITE_QUEUED), \
ata_opcode_name(ATA_CMD_WRITE_STREAM_EXT), \
ata_opcode_name(ATA_CMD_WRITE_STREAM_DMA_EXT), \
ata_opcode_name(ATA_CMD_WRITE_FUA_EXT), \
ata_opcode_name(ATA_CMD_WRITE_QUEUED_FUA_EXT), \
ata_opcode_name(ATA_CMD_FPDMA_READ), \
ata_opcode_name(ATA_CMD_FPDMA_WRITE), \
ata_opcode_name(ATA_CMD_FPDMA_SEND), \
ata_opcode_name(ATA_CMD_FPDMA_RECV), \
ata_opcode_name(ATA_CMD_PIO_READ), \
ata_opcode_name(ATA_CMD_PIO_READ_EXT), \
ata_opcode_name(ATA_CMD_PIO_WRITE), \
ata_opcode_name(ATA_CMD_PIO_WRITE_EXT), \
ata_opcode_name(ATA_CMD_READ_MULTI), \
ata_opcode_name(ATA_CMD_READ_MULTI_EXT), \
ata_opcode_name(ATA_CMD_WRITE_MULTI), \
ata_opcode_name(ATA_CMD_WRITE_MULTI_EXT), \
ata_opcode_name(ATA_CMD_WRITE_MULTI_FUA_EXT), \
ata_opcode_name(ATA_CMD_SET_FEATURES), \
ata_opcode_name(ATA_CMD_SET_MULTI), \
ata_opcode_name(ATA_CMD_PACKET), \
ata_opcode_name(ATA_CMD_VERIFY), \
ata_opcode_name(ATA_CMD_VERIFY_EXT), \
ata_opcode_name(ATA_CMD_WRITE_UNCORR_EXT), \
ata_opcode_name(ATA_CMD_STANDBYNOW1), \
ata_opcode_name(ATA_CMD_IDLEIMMEDIATE), \
ata_opcode_name(ATA_CMD_SLEEP), \
ata_opcode_name(ATA_CMD_INIT_DEV_PARAMS), \
ata_opcode_name(ATA_CMD_READ_NATIVE_MAX), \
ata_opcode_name(ATA_CMD_READ_NATIVE_MAX_EXT), \
ata_opcode_name(ATA_CMD_SET_MAX), \
ata_opcode_name(ATA_CMD_SET_MAX_EXT), \
ata_opcode_name(ATA_CMD_READ_LOG_EXT), \
ata_opcode_name(ATA_CMD_WRITE_LOG_EXT), \
ata_opcode_name(ATA_CMD_READ_LOG_DMA_EXT), \
ata_opcode_name(ATA_CMD_WRITE_LOG_DMA_EXT), \
ata_opcode_name(ATA_CMD_TRUSTED_NONDATA), \
ata_opcode_name(ATA_CMD_TRUSTED_RCV), \
ata_opcode_name(ATA_CMD_TRUSTED_RCV_DMA), \
ata_opcode_name(ATA_CMD_TRUSTED_SND), \
ata_opcode_name(ATA_CMD_TRUSTED_SND_DMA), \
ata_opcode_name(ATA_CMD_PMP_READ), \
ata_opcode_name(ATA_CMD_PMP_READ_DMA), \
ata_opcode_name(ATA_CMD_PMP_WRITE), \
ata_opcode_name(ATA_CMD_PMP_WRITE_DMA), \
ata_opcode_name(ATA_CMD_CONF_OVERLAY), \
ata_opcode_name(ATA_CMD_SEC_SET_PASS), \
ata_opcode_name(ATA_CMD_SEC_UNLOCK), \
ata_opcode_name(ATA_CMD_SEC_ERASE_PREP), \
ata_opcode_name(ATA_CMD_SEC_ERASE_UNIT), \
ata_opcode_name(ATA_CMD_SEC_FREEZE_LOCK), \
ata_opcode_name(ATA_CMD_SEC_DISABLE_PASS), \
ata_opcode_name(ATA_CMD_CONFIG_STREAM), \
ata_opcode_name(ATA_CMD_SMART), \
ata_opcode_name(ATA_CMD_MEDIA_LOCK), \
ata_opcode_name(ATA_CMD_MEDIA_UNLOCK), \
ata_opcode_name(ATA_CMD_DSM), \
ata_opcode_name(ATA_CMD_CHK_MED_CRD_TYP), \
ata_opcode_name(ATA_CMD_CFA_REQ_EXT_ERR), \
ata_opcode_name(ATA_CMD_CFA_WRITE_NE), \
ata_opcode_name(ATA_CMD_CFA_TRANS_SECT), \
ata_opcode_name(ATA_CMD_CFA_ERASE), \
ata_opcode_name(ATA_CMD_CFA_WRITE_MULT_NE), \
ata_opcode_name(ATA_CMD_REQ_SENSE_DATA), \
ata_opcode_name(ATA_CMD_SANITIZE_DEVICE), \
ata_opcode_name(ATA_CMD_RESTORE), \
ata_opcode_name(ATA_CMD_READ_LONG), \
ata_opcode_name(ATA_CMD_READ_LONG_ONCE), \
ata_opcode_name(ATA_CMD_WRITE_LONG), \
ata_opcode_name(ATA_CMD_WRITE_LONG_ONCE))
#define ata_error_name(result) { result, #result }
#define show_error_name(val) \
__print_symbolic(val, \
ata_error_name(ATA_ICRC), \
ata_error_name(ATA_UNC), \
ata_error_name(ATA_MC), \
ata_error_name(ATA_IDNF), \
ata_error_name(ATA_MCR), \
ata_error_name(ATA_ABORTED), \
ata_error_name(ATA_TRK0NF), \
ata_error_name(ATA_AMNF))
#define ata_protocol_name(proto) { proto, #proto }
#define show_protocol_name(val) \
__print_symbolic(val, \
ata_protocol_name(ATA_PROT_UNKNOWN), \
ata_protocol_name(ATA_PROT_NODATA), \
ata_protocol_name(ATA_PROT_PIO), \
ata_protocol_name(ATA_PROT_DMA), \
ata_protocol_name(ATA_PROT_NCQ), \
ata_protocol_name(ATAPI_PROT_NODATA), \
ata_protocol_name(ATAPI_PROT_PIO), \
ata_protocol_name(ATAPI_PROT_DMA))
const char *libata_trace_parse_status(struct trace_seq*, unsigned char);
#define __parse_status(s) libata_trace_parse_status(p, s)
const char *libata_trace_parse_eh_action(struct trace_seq *, unsigned int);
#define __parse_eh_action(a) libata_trace_parse_eh_action(p, a)
const char *libata_trace_parse_eh_err_mask(struct trace_seq *, unsigned int);
#define __parse_eh_err_mask(m) libata_trace_parse_eh_err_mask(p, m)
const char *libata_trace_parse_qc_flags(struct trace_seq *, unsigned int);
#define __parse_qc_flags(f) libata_trace_parse_qc_flags(p, f)
TRACE_EVENT(ata_qc_issue,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc),
TP_STRUCT__entry(
__field( unsigned int, ata_port )
__field( unsigned int, ata_dev )
__field( unsigned int, tag )
__field( unsigned char, cmd )
__field( unsigned char, dev )
__field( unsigned char, lbal )
__field( unsigned char, lbam )
__field( unsigned char, lbah )
__field( unsigned char, nsect )
__field( unsigned char, feature )
__field( unsigned char, hob_lbal )
__field( unsigned char, hob_lbam )
__field( unsigned char, hob_lbah )
__field( unsigned char, hob_nsect )
__field( unsigned char, hob_feature )
__field( unsigned char, ctl )
__field( unsigned char, proto )
__field( unsigned long, flags )
),
TP_fast_assign(
__entry->ata_port = qc->ap->print_id;
__entry->ata_dev = qc->dev->link->pmp + qc->dev->devno;
__entry->tag = qc->tag;
__entry->proto = qc->tf.protocol;
__entry->cmd = qc->tf.command;
__entry->dev = qc->tf.device;
__entry->lbal = qc->tf.lbal;
__entry->lbam = qc->tf.lbam;
__entry->lbah = qc->tf.lbah;
__entry->hob_lbal = qc->tf.hob_lbal;
__entry->hob_lbam = qc->tf.hob_lbam;
__entry->hob_lbah = qc->tf.hob_lbah;
__entry->feature = qc->tf.feature;
__entry->hob_feature = qc->tf.hob_feature;
__entry->nsect = qc->tf.nsect;
__entry->hob_nsect = qc->tf.hob_nsect;
),
TP_printk("ata_port=%u ata_dev=%u tag=%d proto=%s cmd=%s " \
" tf=(%02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x)",
__entry->ata_port, __entry->ata_dev, __entry->tag,
show_protocol_name(__entry->proto),
show_opcode_name(__entry->cmd),
__entry->cmd, __entry->feature, __entry->nsect,
__entry->lbal, __entry->lbam, __entry->lbah,
__entry->hob_feature, __entry->hob_nsect,
__entry->hob_lbal, __entry->hob_lbam, __entry->hob_lbah,
__entry->dev)
);
DECLARE_EVENT_CLASS(ata_qc_complete_template,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc),
TP_STRUCT__entry(
__field( unsigned int, ata_port )
__field( unsigned int, ata_dev )
__field( unsigned int, tag )
__field( unsigned char, status )
__field( unsigned char, dev )
__field( unsigned char, lbal )
__field( unsigned char, lbam )
__field( unsigned char, lbah )
__field( unsigned char, nsect )
__field( unsigned char, error )
__field( unsigned char, hob_lbal )
__field( unsigned char, hob_lbam )
__field( unsigned char, hob_lbah )
__field( unsigned char, hob_nsect )
__field( unsigned char, hob_feature )
__field( unsigned char, ctl )
__field( unsigned long, flags )
),
TP_fast_assign(
__entry->ata_port = qc->ap->print_id;
__entry->ata_dev = qc->dev->link->pmp + qc->dev->devno;
__entry->tag = qc->tag;
__entry->status = qc->result_tf.command;
__entry->dev = qc->result_tf.device;
__entry->lbal = qc->result_tf.lbal;
__entry->lbam = qc->result_tf.lbam;
__entry->lbah = qc->result_tf.lbah;
__entry->hob_lbal = qc->result_tf.hob_lbal;
__entry->hob_lbam = qc->result_tf.hob_lbam;
__entry->hob_lbah = qc->result_tf.hob_lbah;
__entry->error = qc->result_tf.feature;
__entry->hob_feature = qc->result_tf.hob_feature;
__entry->nsect = qc->result_tf.nsect;
__entry->hob_nsect = qc->result_tf.hob_nsect;
),
TP_printk("ata_port=%u ata_dev=%u tag=%d flags=%s status=%s " \
" res=(%02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x)",
__entry->ata_port, __entry->ata_dev, __entry->tag,
__parse_qc_flags(__entry->flags),
__parse_status(__entry->status),
__entry->status, __entry->error, __entry->nsect,
__entry->lbal, __entry->lbam, __entry->lbah,
__entry->hob_feature, __entry->hob_nsect,
__entry->hob_lbal, __entry->hob_lbam, __entry->hob_lbah,
__entry->dev)
);
DEFINE_EVENT(ata_qc_complete_template, ata_qc_complete_internal,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc));
DEFINE_EVENT(ata_qc_complete_template, ata_qc_complete_failed,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc));
DEFINE_EVENT(ata_qc_complete_template, ata_qc_complete_done,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc));
TRACE_EVENT(ata_eh_link_autopsy,
TP_PROTO(struct ata_device *dev, unsigned int eh_action, unsigned int eh_err_mask),
TP_ARGS(dev, eh_action, eh_err_mask),
TP_STRUCT__entry(
__field( unsigned int, ata_port )
__field( unsigned int, ata_dev )
__field( unsigned int, eh_action )
__field( unsigned int, eh_err_mask)
),
TP_fast_assign(
__entry->ata_port = dev->link->ap->print_id;
__entry->ata_dev = dev->link->pmp + dev->devno;
__entry->eh_action = eh_action;
__entry->eh_err_mask = eh_err_mask;
),
TP_printk("ata_port=%u ata_dev=%u eh_action=%s err_mask=%s",
__entry->ata_port, __entry->ata_dev,
__parse_eh_action(__entry->eh_action),
__parse_eh_err_mask(__entry->eh_err_mask))
);
TRACE_EVENT(ata_eh_link_autopsy_qc,
TP_PROTO(struct ata_queued_cmd *qc),
TP_ARGS(qc),
TP_STRUCT__entry(
__field( unsigned int, ata_port )
__field( unsigned int, ata_dev )
__field( unsigned int, tag )
__field( unsigned int, qc_flags )
__field( unsigned int, eh_err_mask)
),
TP_fast_assign(
__entry->ata_port = qc->ap->print_id;
__entry->ata_dev = qc->dev->link->pmp + qc->dev->devno;
__entry->tag = qc->tag;
__entry->qc_flags = qc->flags;
__entry->eh_err_mask = qc->err_mask;
),
TP_printk("ata_port=%u ata_dev=%u tag=%d flags=%s err_mask=%s",
__entry->ata_port, __entry->ata_dev, __entry->tag,
__parse_qc_flags(__entry->qc_flags),
__parse_eh_err_mask(__entry->eh_err_mask))
);
#endif /* _TRACE_LIBATA_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册