|
@@ -295,6 +295,44 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class,
|
|
|
+ unsigned long deadline)
|
|
|
+{
|
|
|
+ struct ata_port *ap = link->ap;
|
|
|
+ struct domain_device *dev = ap->private_data;
|
|
|
+ struct sas_internal *i =
|
|
|
+ to_sas_internal(dev->port->ha->core.shost->transportt);
|
|
|
+ int res = TMF_RESP_FUNC_FAILED;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ if (i->dft->lldd_ata_soft_reset)
|
|
|
+ res = i->dft->lldd_ata_soft_reset(dev);
|
|
|
+
|
|
|
+ if (res != TMF_RESP_FUNC_COMPLETE) {
|
|
|
+ SAS_DPRINTK("%s: Unable to soft reset\n", __func__);
|
|
|
+ ret = -EAGAIN;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (dev->sata_dev.command_set) {
|
|
|
+ case ATA_COMMAND_SET:
|
|
|
+ SAS_DPRINTK("%s: Found ATA device.\n", __func__);
|
|
|
+ *class = ATA_DEV_ATA;
|
|
|
+ break;
|
|
|
+ case ATAPI_COMMAND_SET:
|
|
|
+ SAS_DPRINTK("%s: Found ATAPI device.\n", __func__);
|
|
|
+ *class = ATA_DEV_ATAPI;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
|
|
|
+ __func__, dev->sata_dev.command_set);
|
|
|
+ *class = ATA_DEV_UNKNOWN;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ap->cbl = ATA_CBL_SATA;
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static void sas_ata_post_internal(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
if (qc->flags & ATA_QCFLAG_FAILED)
|
|
@@ -325,7 +363,7 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
|
|
|
|
|
|
static struct ata_port_operations sas_sata_ops = {
|
|
|
.prereset = ata_std_prereset,
|
|
|
- .softreset = NULL,
|
|
|
+ .softreset = sas_ata_soft_reset,
|
|
|
.hardreset = sas_ata_hard_reset,
|
|
|
.postreset = ata_std_postreset,
|
|
|
.error_handler = ata_std_error_handler,
|