aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2011-05-24 16:18:04 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-26 23:49:33 -0400
commit1ca1e43e55f4cd068f997154ffaf5fa62b08b802 (patch)
tree8b705e0088fb362d030caf1eed88ba63e59b7c5e
parent3673f4bf6a277f4f2944ad153ceb167b340f9ffc (diff)
[SCSI] libsas: Add option for SATA soft reset
This allows a libsas driver to optionally provide a soft reset handler for libata to drive. The isci driver allows software to control the assertion/deassertion of SRST. [jejb: checkpatch.pl fixes] Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
-rw-r--r--drivers/scsi/libsas/sas_ata.c40
-rw-r--r--include/scsi/libsas.h1
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index e99301421409..db9238f2ecb8 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -295,6 +295,44 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
295 return ret; 295 return ret;
296} 296}
297 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
298static void sas_ata_post_internal(struct ata_queued_cmd *qc) 336static void sas_ata_post_internal(struct ata_queued_cmd *qc)
299{ 337{
300 if (qc->flags & ATA_QCFLAG_FAILED) 338 if (qc->flags & ATA_QCFLAG_FAILED)
@@ -325,7 +363,7 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
325 363
326static struct ata_port_operations sas_sata_ops = { 364static struct ata_port_operations sas_sata_ops = {
327 .prereset = ata_std_prereset, 365 .prereset = ata_std_prereset,
328 .softreset = NULL, 366 .softreset = sas_ata_soft_reset,
329 .hardreset = sas_ata_hard_reset, 367 .hardreset = sas_ata_hard_reset,
330 .postreset = ata_std_postreset, 368 .postreset = ata_std_postreset,
331 .error_handler = ata_std_error_handler, 369 .error_handler = ata_std_error_handler,
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 8f6bb9c7f3eb..ee866060f8a4 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -604,6 +604,7 @@ struct sas_domain_function_template {
604 int (*lldd_clear_aca)(struct domain_device *, u8 *lun); 604 int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
605 int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); 605 int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
606 int (*lldd_I_T_nexus_reset)(struct domain_device *); 606 int (*lldd_I_T_nexus_reset)(struct domain_device *);
607 int (*lldd_ata_soft_reset)(struct domain_device *);
607 int (*lldd_lu_reset)(struct domain_device *, u8 *lun); 608 int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
608 int (*lldd_query_task)(struct sas_task *); 609 int (*lldd_query_task)(struct sas_task *);
609 610