diff options
author | Dave Jiang <dave.jiang@intel.com> | 2011-05-24 16:18:04 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-26 23:49:33 -0400 |
commit | 1ca1e43e55f4cd068f997154ffaf5fa62b08b802 (patch) | |
tree | 8b705e0088fb362d030caf1eed88ba63e59b7c5e | |
parent | 3673f4bf6a277f4f2944ad153ceb167b340f9ffc (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.c | 40 | ||||
-rw-r--r-- | include/scsi/libsas.h | 1 |
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 | ||
298 | static 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 | |||
298 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) | 336 | static 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 | ||
326 | static struct ata_port_operations sas_sata_ops = { | 364 | static 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 | ||