Commit 4e8790f7 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull libata changes from Tejun Heo:
 "The only interesting piece is the support for shingled drives.  The
  changes in libata layer are minimal.  All it does is identifying the
  new class of device and report upwards accordingly"

* 'for-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  libata: Remove FIXME comment in atapi_request_sense()
  sata_rcar: Document deprecated "renesas,rcar-sata"
  sata_rcar: Add clocks to sata_rcar bindings
  ahci_sunxi: Make AHCI_HFLAG_NO_PMP flag configurable with a module option
  libata-scsi: Update SATL for ZAC drives
  libata: Implement ATA_DEV_ZAC
  libsas: use ata_dev_classify()
parents 0a27044c 2ba520f0
...@@ -3,18 +3,21 @@ ...@@ -3,18 +3,21 @@
Required properties: Required properties:
- compatible : should contain one of the following: - compatible : should contain one of the following:
- "renesas,sata-r8a7779" for R-Car H1 - "renesas,sata-r8a7779" for R-Car H1
("renesas,rcar-sata" is deprecated)
- "renesas,sata-r8a7790-es1" for R-Car H2 ES1 - "renesas,sata-r8a7790-es1" for R-Car H2 ES1
- "renesas,sata-r8a7790" for R-Car H2 other than ES1 - "renesas,sata-r8a7790" for R-Car H2 other than ES1
- "renesas,sata-r8a7791" for R-Car M2-W - "renesas,sata-r8a7791" for R-Car M2-W
- "renesas,sata-r8a7793" for R-Car M2-N - "renesas,sata-r8a7793" for R-Car M2-N
- reg : address and length of the SATA registers; - reg : address and length of the SATA registers;
- interrupts : must consist of one interrupt specifier. - interrupts : must consist of one interrupt specifier.
- clocks : must contain a reference to the functional clock.
Example: Example:
sata: sata@fc600000 { sata0: sata@ee300000 {
compatible = "renesas,sata-r8a7779"; compatible = "renesas,sata-r8a7791";
reg = <0xfc600000 0x2000>; reg = <0 0xee300000 0 0x2000>;
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
}; };
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include "ahci.h" #include "ahci.h"
/* Insmod parameters */
static bool enable_pmp;
module_param(enable_pmp, bool, 0);
MODULE_PARM_DESC(enable_pmp,
"Enable support for sata port multipliers, only use if you use a pmp!");
#define AHCI_BISTAFR 0x00a0 #define AHCI_BISTAFR 0x00a0
#define AHCI_BISTCR 0x00a4 #define AHCI_BISTCR 0x00a4
#define AHCI_BISTFCTR 0x00a8 #define AHCI_BISTFCTR 0x00a8
...@@ -184,7 +190,15 @@ static int ahci_sunxi_probe(struct platform_device *pdev) ...@@ -184,7 +190,15 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
goto disable_resources; goto disable_resources;
hpriv->flags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | hpriv->flags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ; AHCI_HFLAG_YES_NCQ;
/*
* The sunxi sata controller seems to be unable to successfully do a
* soft reset if no pmp is attached, so disable pmp use unless
* requested, otherwise directly attached disks do not work.
*/
if (!enable_pmp)
hpriv->flags |= AHCI_HFLAG_NO_PMP;
rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info); rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info);
if (rc) if (rc)
......
...@@ -1043,8 +1043,8 @@ const char *sata_spd_string(unsigned int spd) ...@@ -1043,8 +1043,8 @@ const char *sata_spd_string(unsigned int spd)
* None. * None.
* *
* RETURNS: * RETURNS:
* Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP or * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP,
* %ATA_DEV_UNKNOWN the event of failure. * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure.
*/ */
unsigned int ata_dev_classify(const struct ata_taskfile *tf) unsigned int ata_dev_classify(const struct ata_taskfile *tf)
{ {
...@@ -1089,6 +1089,11 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) ...@@ -1089,6 +1089,11 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
return ATA_DEV_SEMB; return ATA_DEV_SEMB;
} }
if ((tf->lbam == 0xcd) && (tf->lbah == 0xab)) {
DPRINTK("found ZAC device by sig\n");
return ATA_DEV_ZAC;
}
DPRINTK("unknown device\n"); DPRINTK("unknown device\n");
return ATA_DEV_UNKNOWN; return ATA_DEV_UNKNOWN;
} }
...@@ -1329,7 +1334,7 @@ static int ata_hpa_resize(struct ata_device *dev) ...@@ -1329,7 +1334,7 @@ static int ata_hpa_resize(struct ata_device *dev)
int rc; int rc;
/* do we need to do it? */ /* do we need to do it? */
if (dev->class != ATA_DEV_ATA || if ((dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) ||
!ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) || !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) (dev->horkage & ATA_HORKAGE_BROKEN_HPA))
return 0; return 0;
...@@ -1889,6 +1894,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1889,6 +1894,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
case ATA_DEV_SEMB: case ATA_DEV_SEMB:
class = ATA_DEV_ATA; /* some hard drives report SEMB sig */ class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
case ATA_DEV_ATA: case ATA_DEV_ATA:
case ATA_DEV_ZAC:
tf.command = ATA_CMD_ID_ATA; tf.command = ATA_CMD_ID_ATA;
break; break;
case ATA_DEV_ATAPI: case ATA_DEV_ATAPI:
...@@ -1980,7 +1986,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1980,7 +1986,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
rc = -EINVAL; rc = -EINVAL;
reason = "device reports invalid type"; reason = "device reports invalid type";
if (class == ATA_DEV_ATA) { if (class == ATA_DEV_ATA || class == ATA_DEV_ZAC) {
if (!ata_id_is_ata(id) && !ata_id_is_cfa(id)) if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
goto err_out; goto err_out;
if (ap->host->flags & ATA_HOST_IGNORE_ATA && if (ap->host->flags & ATA_HOST_IGNORE_ATA &&
...@@ -2015,7 +2021,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -2015,7 +2021,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
goto retry; goto retry;
} }
if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) { if ((flags & ATA_READID_POSTRESET) &&
(class == ATA_DEV_ATA || class == ATA_DEV_ZAC)) {
/* /*
* The exact sequence expected by certain pre-ATA4 drives is: * The exact sequence expected by certain pre-ATA4 drives is:
* SRST RESET * SRST RESET
...@@ -2280,7 +2287,7 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -2280,7 +2287,7 @@ int ata_dev_configure(struct ata_device *dev)
sizeof(modelbuf)); sizeof(modelbuf));
/* ATA-specific feature tests */ /* ATA-specific feature tests */
if (dev->class == ATA_DEV_ATA) { if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) {
if (ata_id_is_cfa(id)) { if (ata_id_is_cfa(id)) {
/* CPRM may make this media unusable */ /* CPRM may make this media unusable */
if (id[ATA_ID_CFA_KEY_MGMT] & 1) if (id[ATA_ID_CFA_KEY_MGMT] & 1)
...@@ -4033,6 +4040,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, ...@@ -4033,6 +4040,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
if (ata_class_enabled(new_class) && if (ata_class_enabled(new_class) &&
new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATA &&
new_class != ATA_DEV_ATAPI && new_class != ATA_DEV_ATAPI &&
new_class != ATA_DEV_ZAC &&
new_class != ATA_DEV_SEMB) { new_class != ATA_DEV_SEMB) {
ata_dev_info(dev, "class mismatch %u != %u\n", ata_dev_info(dev, "class mismatch %u != %u\n",
dev->class, new_class); dev->class, new_class);
......
...@@ -1809,6 +1809,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, ...@@ -1809,6 +1809,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
switch (qc->dev->class) { switch (qc->dev->class) {
case ATA_DEV_ATA: case ATA_DEV_ATA:
case ATA_DEV_ZAC:
if (err & ATA_ICRC) if (err & ATA_ICRC)
qc->err_mask |= AC_ERR_ATA_BUS; qc->err_mask |= AC_ERR_ATA_BUS;
if (err & (ATA_UNC | ATA_AMNF)) if (err & (ATA_UNC | ATA_AMNF))
...@@ -3792,7 +3793,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -3792,7 +3793,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
unsigned long tmp; unsigned long tmp;
if (dev->class != ATA_DEV_ATA) if (dev->class != ATA_DEV_ATA &&
dev->class != ATA_DEV_ZAC)
continue; continue;
if (!(ehc->i.dev_action[dev->devno] & if (!(ehc->i.dev_action[dev->devno] &
ATA_EH_PARK)) ATA_EH_PARK))
...@@ -3873,7 +3875,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -3873,7 +3875,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
/* retry flush if necessary */ /* retry flush if necessary */
ata_for_each_dev(dev, link, ALL) { ata_for_each_dev(dev, link, ALL) {
if (dev->class != ATA_DEV_ATA) if (dev->class != ATA_DEV_ATA &&
dev->class != ATA_DEV_ZAC)
continue; continue;
rc = ata_eh_maybe_retry_flush(dev); rc = ata_eh_maybe_retry_flush(dev);
if (rc) if (rc)
......
...@@ -235,7 +235,8 @@ static ssize_t ata_scsi_park_store(struct device *device, ...@@ -235,7 +235,8 @@ static ssize_t ata_scsi_park_store(struct device *device,
rc = -ENODEV; rc = -ENODEV;
goto unlock; goto unlock;
} }
if (dev->class != ATA_DEV_ATA) { if (dev->class != ATA_DEV_ATA &&
dev->class != ATA_DEV_ZAC) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto unlock; goto unlock;
} }
...@@ -1961,6 +1962,7 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, ...@@ -1961,6 +1962,7 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
{ {
const u8 versions[] = { const u8 versions[] = {
0x00,
0x60, /* SAM-3 (no version claimed) */ 0x60, /* SAM-3 (no version claimed) */
0x03, 0x03,
...@@ -1969,6 +1971,20 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -1969,6 +1971,20 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
0x02, 0x02,
0x60 /* SPC-3 (no version claimed) */ 0x60 /* SPC-3 (no version claimed) */
}; };
const u8 versions_zbc[] = {
0x00,
0xA0, /* SAM-5 (no version claimed) */
0x04,
0xC0, /* SBC-3 (no version claimed) */
0x04,
0x60, /* SPC-4 (no version claimed) */
0x60,
0x20, /* ZBC (no version claimed) */
};
u8 hdr[] = { u8 hdr[] = {
TYPE_DISK, TYPE_DISK,
0, 0,
...@@ -1983,6 +1999,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -1983,6 +1999,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
if (ata_id_removeable(args->id)) if (ata_id_removeable(args->id))
hdr[1] |= (1 << 7); hdr[1] |= (1 << 7);
if (args->dev->class == ATA_DEV_ZAC) {
hdr[0] = TYPE_ZBC;
hdr[2] = 0x6; /* ZBC is defined in SPC-4 */
}
memcpy(rbuf, hdr, sizeof(hdr)); memcpy(rbuf, hdr, sizeof(hdr));
memcpy(&rbuf[8], "ATA ", 8); memcpy(&rbuf[8], "ATA ", 8);
ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
...@@ -1995,7 +2016,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) ...@@ -1995,7 +2016,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
if (rbuf[32] == 0 || rbuf[32] == ' ') if (rbuf[32] == 0 || rbuf[32] == ' ')
memcpy(&rbuf[32], "n/a ", 4); memcpy(&rbuf[32], "n/a ", 4);
memcpy(rbuf + 59, versions, sizeof(versions)); if (args->dev->class == ATA_DEV_ZAC)
memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
else
memcpy(rbuf + 58, versions, sizeof(versions));
return 0; return 0;
} }
...@@ -2564,7 +2588,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) ...@@ -2564,7 +2588,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
DPRINTK("ATAPI request sense\n"); DPRINTK("ATAPI request sense\n");
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
#ifdef CONFIG_ATA_SFF #ifdef CONFIG_ATA_SFF
...@@ -3405,7 +3428,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, ...@@ -3405,7 +3428,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
ata_xlat_func_t xlat_func; ata_xlat_func_t xlat_func;
int rc = 0; int rc = 0;
if (dev->class == ATA_DEV_ATA) { if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) {
if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len))
goto bad_cdb_len; goto bad_cdb_len;
......
...@@ -143,6 +143,7 @@ static struct { ...@@ -143,6 +143,7 @@ static struct {
{ ATA_DEV_PMP_UNSUP, "pmp" }, { ATA_DEV_PMP_UNSUP, "pmp" },
{ ATA_DEV_SEMB, "semb" }, { ATA_DEV_SEMB, "semb" },
{ ATA_DEV_SEMB_UNSUP, "semb" }, { ATA_DEV_SEMB_UNSUP, "semb" },
{ ATA_DEV_ZAC, "zac" },
{ ATA_DEV_NONE, "none" } { ATA_DEV_NONE, "none" }
}; };
ata_bitfield_name_search(class, ata_class_names) ata_bitfield_name_search(class, ata_class_names)
......
...@@ -373,10 +373,10 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task, ...@@ -373,10 +373,10 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
if (unlikely(task->ata_task.device_control_reg_update)) if (unlikely(task->ata_task.device_control_reg_update))
scb->header.opcode = CONTROL_ATA_DEV; scb->header.opcode = CONTROL_ATA_DEV;
else if (dev->sata_dev.command_set == ATA_COMMAND_SET) else if (dev->sata_dev.class == ATA_DEV_ATAPI)
scb->header.opcode = INITIATE_ATA_TASK;
else
scb->header.opcode = INITIATE_ATAPI_TASK; scb->header.opcode = INITIATE_ATAPI_TASK;
else
scb->header.opcode = INITIATE_ATA_TASK;
scb->ata_task.proto_conn_rate = (1 << 5); /* STP */ scb->ata_task.proto_conn_rate = (1 << 5); /* STP */
if (dev->port->oob_mode == SAS_OOB_MODE) if (dev->port->oob_mode == SAS_OOB_MODE)
...@@ -387,7 +387,7 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task, ...@@ -387,7 +387,7 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
if (likely(!task->ata_task.device_control_reg_update)) if (likely(!task->ata_task.device_control_reg_update))
scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */ scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */
if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) if (dev->sata_dev.class == ATA_DEV_ATAPI)
memcpy(scb->ata_task.atapi_packet, task->ata_task.atapi_packet, memcpy(scb->ata_task.atapi_packet, task->ata_task.atapi_packet,
16); 16);
scb->ata_task.sister_scb = cpu_to_le16(0xFFFF); scb->ata_task.sister_scb = cpu_to_le16(0xFFFF);
...@@ -399,7 +399,7 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task, ...@@ -399,7 +399,7 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
if (task->ata_task.dma_xfer) if (task->ata_task.dma_xfer)
flags |= DATA_XFER_MODE_DMA; flags |= DATA_XFER_MODE_DMA;
if (task->ata_task.use_ncq && if (task->ata_task.use_ncq &&
dev->sata_dev.command_set != ATAPI_COMMAND_SET) dev->sata_dev.class != ATA_DEV_ATAPI)
flags |= ATA_Q_TYPE_NCQ; flags |= ATA_Q_TYPE_NCQ;
flags |= data_dir_flags[task->data_dir]; flags |= data_dir_flags[task->data_dir];
scb->ata_task.ata_flags = flags; scb->ata_task.ata_flags = flags;
......
...@@ -694,7 +694,7 @@ sci_io_request_construct_sata(struct isci_request *ireq, ...@@ -694,7 +694,7 @@ sci_io_request_construct_sata(struct isci_request *ireq,
} }
/* ATAPI */ /* ATAPI */
if (dev->sata_dev.command_set == ATAPI_COMMAND_SET && if (dev->sata_dev.class == ATA_DEV_ATAPI &&
task->ata_task.fis.command == ATA_CMD_PACKET) { task->ata_task.fis.command == ATA_CMD_PACKET) {
sci_atapi_construct(ireq); sci_atapi_construct(ireq);
return SCI_SUCCESS; return SCI_SUCCESS;
...@@ -2980,7 +2980,7 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm) ...@@ -2980,7 +2980,7 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
state = SCI_REQ_SMP_WAIT_RESP; state = SCI_REQ_SMP_WAIT_RESP;
} else if (task && sas_protocol_ata(task->task_proto) && } else if (task && sas_protocol_ata(task->task_proto) &&
!task->ata_task.use_ncq) { !task->ata_task.use_ncq) {
if (dev->sata_dev.command_set == ATAPI_COMMAND_SET && if (dev->sata_dev.class == ATA_DEV_ATAPI &&
task->ata_task.fis.command == ATA_CMD_PACKET) { task->ata_task.fis.command == ATA_CMD_PACKET) {
state = SCI_REQ_ATAPI_WAIT_H2D; state = SCI_REQ_ATAPI_WAIT_H2D;
} else if (task->data_dir == DMA_NONE) { } else if (task->data_dir == DMA_NONE) {
......
...@@ -138,7 +138,7 @@ static void sas_ata_task_done(struct sas_task *task) ...@@ -138,7 +138,7 @@ static void sas_ata_task_done(struct sas_task *task)
if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
((stat->stat == SAM_STAT_CHECK_CONDITION && ((stat->stat == SAM_STAT_CHECK_CONDITION &&
dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { dev->sata_dev.class == ATA_DEV_ATAPI))) {
memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE); memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE);
if (!link->sactive) { if (!link->sactive) {
...@@ -272,7 +272,7 @@ static struct sas_internal *dev_to_sas_internal(struct domain_device *dev) ...@@ -272,7 +272,7 @@ static struct sas_internal *dev_to_sas_internal(struct domain_device *dev)
return to_sas_internal(dev->port->ha->core.shost->transportt); return to_sas_internal(dev->port->ha->core.shost->transportt);
} }
static void sas_get_ata_command_set(struct domain_device *dev); static int sas_get_ata_command_set(struct domain_device *dev);
int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
{ {
...@@ -297,8 +297,7 @@ int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) ...@@ -297,8 +297,7 @@ int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
} }
memcpy(dev->frame_rcvd, &dev->sata_dev.rps_resp.rps.fis, memcpy(dev->frame_rcvd, &dev->sata_dev.rps_resp.rps.fis,
sizeof(struct dev_to_host_fis)); sizeof(struct dev_to_host_fis));
/* TODO switch to ata_dev_classify() */ dev->sata_dev.class = sas_get_ata_command_set(dev);
sas_get_ata_command_set(dev);
} }
return 0; return 0;
} }
...@@ -419,18 +418,7 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, ...@@ -419,18 +418,7 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
if (ret && ret != -EAGAIN) if (ret && ret != -EAGAIN)
sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret); sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret);
/* XXX: if the class changes during the reset the upper layer *class = dev->sata_dev.class;
* should be informed, if the device has gone away we assume
* libsas will eventually delete it
*/
switch (dev->sata_dev.command_set) {
case ATA_COMMAND_SET:
*class = ATA_DEV_ATA;
break;
case ATAPI_COMMAND_SET:
*class = ATA_DEV_ATAPI;
break;
}
ap->cbl = ATA_CBL_SATA; ap->cbl = ATA_CBL_SATA;
return ret; return ret;
...@@ -619,50 +607,18 @@ void sas_ata_task_abort(struct sas_task *task) ...@@ -619,50 +607,18 @@ void sas_ata_task_abort(struct sas_task *task)
complete(waiting); complete(waiting);
} }
static void sas_get_ata_command_set(struct domain_device *dev) static int sas_get_ata_command_set(struct domain_device *dev)
{ {
struct dev_to_host_fis *fis = struct dev_to_host_fis *fis =
(struct dev_to_host_fis *) dev->frame_rcvd; (struct dev_to_host_fis *) dev->frame_rcvd;
struct ata_taskfile tf;
if (dev->dev_type == SAS_SATA_PENDING) if (dev->dev_type == SAS_SATA_PENDING)
return; return ATA_DEV_UNKNOWN;
ata_tf_from_fis((const u8 *)fis, &tf);
if ((fis->sector_count == 1 && /* ATA */ return ata_dev_classify(&tf);
fis->lbal == 1 &&
fis->lbam == 0 &&
fis->lbah == 0 &&
fis->device == 0)
||
(fis->sector_count == 0 && /* CE-ATA (mATA) */
fis->lbal == 0 &&
fis->lbam == 0xCE &&
fis->lbah == 0xAA &&
(fis->device & ~0x10) == 0))
dev->sata_dev.command_set = ATA_COMMAND_SET;
else if ((fis->interrupt_reason == 1 && /* ATAPI */
fis->lbal == 1 &&
fis->byte_count_low == 0x14 &&
fis->byte_count_high == 0xEB &&
(fis->device & ~0x10) == 0))
dev->sata_dev.command_set = ATAPI_COMMAND_SET;
else if ((fis->sector_count == 1 && /* SEMB */
fis->lbal == 1 &&
fis->lbam == 0x3C &&
fis->lbah == 0xC3 &&
fis->device == 0)
||
(fis->interrupt_reason == 1 && /* SATA PM */
fis->lbal == 1 &&
fis->byte_count_low == 0x69 &&
fis->byte_count_high == 0x96 &&
(fis->device & ~0x10) == 0))
/* Treat it as a superset? */
dev->sata_dev.command_set = ATAPI_COMMAND_SET;
} }
void sas_probe_sata(struct asd_sas_port *port) void sas_probe_sata(struct asd_sas_port *port)
...@@ -768,7 +724,7 @@ int sas_discover_sata(struct domain_device *dev) ...@@ -768,7 +724,7 @@ int sas_discover_sata(struct domain_device *dev)
if (dev->dev_type == SAS_SATA_PM) if (dev->dev_type == SAS_SATA_PM)
return -ENODEV; return -ENODEV;
sas_get_ata_command_set(dev); dev->sata_dev.class = sas_get_ata_command_set(dev);
sas_fill_in_rphy(dev, dev->rphy); sas_fill_in_rphy(dev, dev->rphy);
res = sas_notify_lldd_dev_found(dev); res = sas_notify_lldd_dev_found(dev);
......
...@@ -479,7 +479,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, ...@@ -479,7 +479,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
if (task->ata_task.use_ncq) if (task->ata_task.use_ncq)
flags |= MCH_FPDMA; flags |= MCH_FPDMA;
if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { if (dev->sata_dev.class == ATA_DEV_ATAPI) {
if (task->ata_task.fis.command != ATA_CMD_ID_ATAPI) if (task->ata_task.fis.command != ATA_CMD_ID_ATAPI)
flags |= MCH_ATAPI; flags |= MCH_ATAPI;
} }
...@@ -546,7 +546,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, ...@@ -546,7 +546,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
/* fill in command FIS and ATAPI CDB */ /* fill in command FIS and ATAPI CDB */
memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis)); memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) if (dev->sata_dev.class == ATA_DEV_ATAPI)
memcpy(buf_cmd + STP_ATAPI_CMD, memcpy(buf_cmd + STP_ATAPI_CMD,
task->ata_task.atapi_packet, 16); task->ata_task.atapi_packet, 16);
......
...@@ -4367,7 +4367,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4367,7 +4367,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n"));
} }
if (task->ata_task.use_ncq && if (task->ata_task.use_ncq &&
dev->sata_dev.command_set != ATAPI_COMMAND_SET) { dev->sata_dev.class != ATA_DEV_ATAPI) {
ATAP = 0x07; /* FPDMA */ ATAP = 0x07; /* FPDMA */
PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n"));
} }
......
...@@ -4077,7 +4077,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4077,7 +4077,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n"));
} }
if (task->ata_task.use_ncq && if (task->ata_task.use_ncq &&
dev->sata_dev.command_set != ATAPI_COMMAND_SET) { dev->sata_dev.class != ATA_DEV_ATAPI) {
ATAP = 0x07; /* FPDMA */ ATAP = 0x07; /* FPDMA */
PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n"));
} }
......
...@@ -191,7 +191,8 @@ enum { ...@@ -191,7 +191,8 @@ enum {
ATA_DEV_PMP_UNSUP = 6, /* SATA port multiplier (unsupported) */ ATA_DEV_PMP_UNSUP = 6, /* SATA port multiplier (unsupported) */
ATA_DEV_SEMB = 7, /* SEMB */ ATA_DEV_SEMB = 7, /* SEMB */
ATA_DEV_SEMB_UNSUP = 8, /* SEMB (unsupported) */ ATA_DEV_SEMB_UNSUP = 8, /* SEMB (unsupported) */
ATA_DEV_NONE = 9, /* no device */ ATA_DEV_ZAC = 9, /* ZAC device */
ATA_DEV_NONE = 10, /* no device */
/* struct ata_link flags */ /* struct ata_link flags */
ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */ ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */
...@@ -1491,7 +1492,8 @@ static inline unsigned int ata_tag_internal(unsigned int tag) ...@@ -1491,7 +1492,8 @@ static inline unsigned int ata_tag_internal(unsigned int tag)
static inline unsigned int ata_class_enabled(unsigned int class) static inline unsigned int ata_class_enabled(unsigned int class)
{ {
return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI || return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI ||
class == ATA_DEV_PMP || class == ATA_DEV_SEMB; class == ATA_DEV_PMP || class == ATA_DEV_SEMB ||
class == ATA_DEV_ZAC;
} }
static inline unsigned int ata_class_disabled(unsigned int class) static inline unsigned int ata_class_disabled(unsigned int class)
......
...@@ -161,17 +161,12 @@ struct expander_device { ...@@ -161,17 +161,12 @@ struct expander_device {
}; };
/* ---------- SATA device ---------- */ /* ---------- SATA device ---------- */
enum ata_command_set {
ATA_COMMAND_SET = 0,
ATAPI_COMMAND_SET = 1,
};
#define ATA_RESP_FIS_SIZE 24 #define ATA_RESP_FIS_SIZE 24
struct sata_device { struct sata_device {
enum ata_command_set command_set; unsigned int class;
struct smp_resp rps_resp; /* report_phy_sata_resp */ struct smp_resp rps_resp; /* report_phy_sata_resp */
u8 port_no; /* port number, if this is a PM (Port) */ u8 port_no; /* port number, if this is a PM (Port) */
struct ata_port *ap; struct ata_port *ap;
struct ata_host ata_host; struct ata_host ata_host;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment