summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci_sunxi.c16
-rw-r--r--drivers/ata/libata-core.c20
-rw-r--r--drivers/ata/libata-eh.c7
-rw-r--r--drivers/ata/libata-scsi.c31
-rw-r--r--drivers/ata/libata-transport.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c10
-rw-r--r--drivers/scsi/isci/request.c4
-rw-r--r--drivers/scsi/libsas/sas_ata.c66
-rw-r--r--drivers/scsi/mvsas/mv_sas.c4
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c2
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c2
11 files changed, 84 insertions, 79 deletions
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index e44d675a30ec..b5aedca5ea3c 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -27,6 +27,12 @@
#include <linux/regulator/consumer.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_BISTCR 0x00a4
#define AHCI_BISTFCTR 0x00a8
@@ -184,7 +190,15 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
goto disable_resources;
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);
if (rc)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c5ba15af87d3..5c84fb5c3372 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1043,8 +1043,8 @@ const char *sata_spd_string(unsigned int spd)
* None.
*
* RETURNS:
- * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP or
- * %ATA_DEV_UNKNOWN the event of failure.
+ * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP,
+ * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure.
*/
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;
}
+ if ((tf->lbam == 0xcd) && (tf->lbah == 0xab)) {
+ DPRINTK("found ZAC device by sig\n");
+ return ATA_DEV_ZAC;
+ }
+
DPRINTK("unknown device\n");
return ATA_DEV_UNKNOWN;
}
@@ -1329,7 +1334,7 @@ static int ata_hpa_resize(struct ata_device *dev)
int rc;
/* 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) ||
(dev->horkage & ATA_HORKAGE_BROKEN_HPA))
return 0;
@@ -1889,6 +1894,7 @@ retry:
case ATA_DEV_SEMB:
class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
case ATA_DEV_ATA:
+ case ATA_DEV_ZAC:
tf.command = ATA_CMD_ID_ATA;
break;
case ATA_DEV_ATAPI:
@@ -1980,7 +1986,7 @@ retry:
rc = -EINVAL;
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))
goto err_out;
if (ap->host->flags & ATA_HOST_IGNORE_ATA &&
@@ -2015,7 +2021,8 @@ 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:
* SRST RESET
@@ -2280,7 +2287,7 @@ int ata_dev_configure(struct ata_device *dev)
sizeof(modelbuf));
/* 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)) {
/* CPRM may make this media unusable */
if (id[ATA_ID_CFA_KEY_MGMT] & 1)
@@ -4033,6 +4040,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
if (ata_class_enabled(new_class) &&
new_class != ATA_DEV_ATA &&
new_class != ATA_DEV_ATAPI &&
+ new_class != ATA_DEV_ZAC &&
new_class != ATA_DEV_SEMB) {
ata_dev_info(dev, "class mismatch %u != %u\n",
dev->class, new_class);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dad83df555c4..3dbec8954c86 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1809,6 +1809,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
switch (qc->dev->class) {
case ATA_DEV_ATA:
+ case ATA_DEV_ZAC:
if (err & ATA_ICRC)
qc->err_mask |= AC_ERR_ATA_BUS;
if (err & (ATA_UNC | ATA_AMNF))
@@ -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;
unsigned long tmp;
- if (dev->class != ATA_DEV_ATA)
+ if (dev->class != ATA_DEV_ATA &&
+ dev->class != ATA_DEV_ZAC)
continue;
if (!(ehc->i.dev_action[dev->devno] &
ATA_EH_PARK))
@@ -3873,7 +3875,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
/* retry flush if necessary */
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;
rc = ata_eh_maybe_retry_flush(dev);
if (rc)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index dd45c6a03e5d..e364e86e84d7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -235,7 +235,8 @@ static ssize_t ata_scsi_park_store(struct device *device,
rc = -ENODEV;
goto unlock;
}
- if (dev->class != ATA_DEV_ATA) {
+ if (dev->class != ATA_DEV_ATA &&
+ dev->class != ATA_DEV_ZAC) {
rc = -EOPNOTSUPP;
goto unlock;
}
@@ -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)
{
const u8 versions[] = {
+ 0x00,
0x60, /* SAM-3 (no version claimed) */
0x03,
@@ -1969,6 +1971,20 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
0x02,
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[] = {
TYPE_DISK,
0,
@@ -1983,6 +1999,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
if (ata_id_removeable(args->id))
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[8], "ATA ", 8);
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)
if (rbuf[32] == 0 || rbuf[32] == ' ')
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;
}
@@ -2564,7 +2588,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
DPRINTK("ATAPI request sense\n");
- /* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
#ifdef CONFIG_ATA_SFF
@@ -3405,7 +3428,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
ata_xlat_func_t xlat_func;
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))
goto bad_cdb_len;
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index e37413228228..3227b7c8a05f 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -143,6 +143,7 @@ static struct {
{ ATA_DEV_PMP_UNSUP, "pmp" },
{ ATA_DEV_SEMB, "semb" },
{ ATA_DEV_SEMB_UNSUP, "semb" },
+ { ATA_DEV_ZAC, "zac" },
{ ATA_DEV_NONE, "none" }
};
ata_bitfield_name_search(class, ata_class_names)
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index 5ff1ce7ba1f4..cdd4ab683be9 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -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))
scb->header.opcode = CONTROL_ATA_DEV;
- else if (dev->sata_dev.command_set == ATA_COMMAND_SET)
- scb->header.opcode = INITIATE_ATA_TASK;
- else
+ else if (dev->sata_dev.class == ATA_DEV_ATAPI)
scb->header.opcode = INITIATE_ATAPI_TASK;
+ else
+ scb->header.opcode = INITIATE_ATA_TASK;
scb->ata_task.proto_conn_rate = (1 << 5); /* STP */
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,
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 &= 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,
16);
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,
if (task->ata_task.dma_xfer)
flags |= DATA_XFER_MODE_DMA;
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 |= data_dir_flags[task->data_dir];
scb->ata_task.ata_flags = flags;
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 56e38096f0c4..cfd0084f1cd2 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -694,7 +694,7 @@ sci_io_request_construct_sata(struct isci_request *ireq,
}
/* 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) {
sci_atapi_construct(ireq);
return SCI_SUCCESS;
@@ -2980,7 +2980,7 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
state = SCI_REQ_SMP_WAIT_RESP;
} else if (task && sas_protocol_ata(task->task_proto) &&
!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) {
state = SCI_REQ_ATAPI_WAIT_H2D;
} else if (task->data_dir == DMA_NONE) {
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 577770fdee86..932d9cc98d2f 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -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 ||
((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);
if (!link->sactive) {
@@ -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);
}
-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)
{
@@ -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,
sizeof(struct dev_to_host_fis));
- /* TODO switch to ata_dev_classify() */
- sas_get_ata_command_set(dev);
+ dev->sata_dev.class = sas_get_ata_command_set(dev);
}
return 0;
}
@@ -419,18 +418,7 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
if (ret && ret != -EAGAIN)
sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret);
- /* XXX: if the class changes during the reset the upper layer
- * 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;
- }
+ *class = dev->sata_dev.class;
ap->cbl = ATA_CBL_SATA;
return ret;
@@ -619,50 +607,18 @@ void sas_ata_task_abort(struct sas_task *task)
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 *) dev->frame_rcvd;
+ struct ata_taskfile tf;
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 */
- 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;
+ return ata_dev_classify(&tf);
}
void sas_probe_sata(struct asd_sas_port *port)
@@ -768,7 +724,7 @@ int sas_discover_sata(struct domain_device *dev)
if (dev->dev_type == SAS_SATA_PM)
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);
res = sas_notify_lldd_dev_found(dev);
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 85d86a5cdb60..2d5ab6d969ec 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -479,7 +479,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
if (task->ata_task.use_ncq)
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)
flags |= MCH_ATAPI;
}
@@ -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 */
/* fill in command FIS and ATAPI CDB */
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,
task->ata_task.atapi_packet, 16);
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 933f21471951..96dcc097a463 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -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"));
}
if (task->ata_task.use_ncq &&
- dev->sata_dev.command_set != ATAPI_COMMAND_SET) {
+ dev->sata_dev.class != ATA_DEV_ATAPI) {
ATAP = 0x07; /* FPDMA */
PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n"));
}
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index b06443a0db2d..05cce463ab01 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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"));
}
if (task->ata_task.use_ncq &&
- dev->sata_dev.command_set != ATAPI_COMMAND_SET) {
+ dev->sata_dev.class != ATA_DEV_ATAPI) {
ATAP = 0x07; /* FPDMA */
PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n"));
}