aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_ata.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r--drivers/scsi/libsas/sas_ata.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 31fc21f4d831..db9238f2ecb8 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -99,19 +99,29 @@ static void sas_ata_task_done(struct sas_task *task)
99 struct sas_ha_struct *sas_ha; 99 struct sas_ha_struct *sas_ha;
100 enum ata_completion_errors ac; 100 enum ata_completion_errors ac;
101 unsigned long flags; 101 unsigned long flags;
102 struct ata_link *link;
102 103
103 if (!qc) 104 if (!qc)
104 goto qc_already_gone; 105 goto qc_already_gone;
105 106
106 dev = qc->ap->private_data; 107 dev = qc->ap->private_data;
107 sas_ha = dev->port->ha; 108 sas_ha = dev->port->ha;
109 link = &dev->sata_dev.ap->link;
108 110
109 spin_lock_irqsave(dev->sata_dev.ap->lock, flags); 111 spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
110 if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || 112 if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
111 ((stat->stat == SAM_STAT_CHECK_CONDITION && 113 ((stat->stat == SAM_STAT_CHECK_CONDITION &&
112 dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { 114 dev->sata_dev.command_set == ATAPI_COMMAND_SET))) {
113 ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); 115 ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
114 qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); 116
117 if (!link->sactive) {
118 qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
119 } else {
120 link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command);
121 if (unlikely(link->eh_info.err_mask))
122 qc->flags |= ATA_QCFLAG_FAILED;
123 }
124
115 dev->sata_dev.sstatus = resp->sstatus; 125 dev->sata_dev.sstatus = resp->sstatus;
116 dev->sata_dev.serror = resp->serror; 126 dev->sata_dev.serror = resp->serror;
117 dev->sata_dev.scontrol = resp->scontrol; 127 dev->sata_dev.scontrol = resp->scontrol;
@@ -121,7 +131,13 @@ static void sas_ata_task_done(struct sas_task *task)
121 SAS_DPRINTK("%s: SAS error %x\n", __func__, 131 SAS_DPRINTK("%s: SAS error %x\n", __func__,
122 stat->stat); 132 stat->stat);
123 /* We saw a SAS error. Send a vague error. */ 133 /* We saw a SAS error. Send a vague error. */
124 qc->err_mask = ac; 134 if (!link->sactive) {
135 qc->err_mask = ac;
136 } else {
137 link->eh_info.err_mask |= AC_ERR_DEV;
138 qc->flags |= ATA_QCFLAG_FAILED;
139 }
140
125 dev->sata_dev.tf.feature = 0x04; /* status err */ 141 dev->sata_dev.tf.feature = 0x04; /* status err */
126 dev->sata_dev.tf.command = ATA_ERR; 142 dev->sata_dev.tf.command = ATA_ERR;
127 } 143 }
@@ -279,6 +295,44 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
279 return ret; 295 return ret;
280} 296}
281 297
298static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class,
299 unsigned long deadline)
300{
301 struct ata_port *ap = link->ap;
302 struct domain_device *dev = ap->private_data;
303 struct sas_internal *i =
304 to_sas_internal(dev->port->ha->core.shost->transportt);
305 int res = TMF_RESP_FUNC_FAILED;
306 int ret = 0;
307
308 if (i->dft->lldd_ata_soft_reset)
309 res = i->dft->lldd_ata_soft_reset(dev);
310
311 if (res != TMF_RESP_FUNC_COMPLETE) {
312 SAS_DPRINTK("%s: Unable to soft reset\n", __func__);
313 ret = -EAGAIN;
314 }
315
316 switch (dev->sata_dev.command_set) {
317 case ATA_COMMAND_SET:
318 SAS_DPRINTK("%s: Found ATA device.\n", __func__);
319 *class = ATA_DEV_ATA;
320 break;
321 case ATAPI_COMMAND_SET:
322 SAS_DPRINTK("%s: Found ATAPI device.\n", __func__);
323 *class = ATA_DEV_ATAPI;
324 break;
325 default:
326 SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
327 __func__, dev->sata_dev.command_set);
328 *class = ATA_DEV_UNKNOWN;
329 break;
330 }
331
332 ap->cbl = ATA_CBL_SATA;
333 return ret;
334}
335
282static void sas_ata_post_internal(struct ata_queued_cmd *qc) 336static void sas_ata_post_internal(struct ata_queued_cmd *qc)
283{ 337{
284 if (qc->flags & ATA_QCFLAG_FAILED) 338 if (qc->flags & ATA_QCFLAG_FAILED)
@@ -309,7 +363,7 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
309 363
310static struct ata_port_operations sas_sata_ops = { 364static struct ata_port_operations sas_sata_ops = {
311 .prereset = ata_std_prereset, 365 .prereset = ata_std_prereset,
312 .softreset = NULL, 366 .softreset = sas_ata_soft_reset,
313 .hardreset = sas_ata_hard_reset, 367 .hardreset = sas_ata_hard_reset,
314 .postreset = ata_std_postreset, 368 .postreset = ata_std_postreset,
315 .error_handler = ata_std_error_handler, 369 .error_handler = ata_std_error_handler,