diff options
| -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 | ||
