diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ahci_sunxi.c | 16 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 20 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 7 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 31 | ||||
-rw-r--r-- | drivers/ata/libata-transport.c | 1 | ||||
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_task.c | 10 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 66 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 4 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 2 |
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")); } |