aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9e92107691f2..b9747fa59e54 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -46,6 +46,7 @@
46#include <linux/libata.h> 46#include <linux/libata.h>
47#include <linux/hdreg.h> 47#include <linux/hdreg.h>
48#include <linux/uaccess.h> 48#include <linux/uaccess.h>
49#include <linux/suspend.h>
49 50
50#include "libata.h" 51#include "libata.h"
51 52
@@ -414,6 +415,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
414 415
415/** 416/**
416 * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl 417 * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
418 * @ap: target port
417 * @sdev: SCSI device to get identify data for 419 * @sdev: SCSI device to get identify data for
418 * @arg: User buffer area for identify data 420 * @arg: User buffer area for identify data
419 * 421 *
@@ -423,9 +425,9 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
423 * RETURNS: 425 * RETURNS:
424 * Zero on success, negative errno on error. 426 * Zero on success, negative errno on error.
425 */ 427 */
426static int ata_get_identity(struct scsi_device *sdev, void __user *arg) 428static int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev,
429 void __user *arg)
427{ 430{
428 struct ata_port *ap = ata_shost_to_port(sdev->host);
429 struct ata_device *dev = ata_scsi_find_dev(ap, sdev); 431 struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
430 u16 __user *dst = arg; 432 u16 __user *dst = arg;
431 char buf[40]; 433 char buf[40];
@@ -645,7 +647,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
645 return rc; 647 return rc;
646} 648}
647 649
648int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) 650int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
651 int cmd, void __user *arg)
649{ 652{
650 int val = -EINVAL, rc = -EINVAL; 653 int val = -EINVAL, rc = -EINVAL;
651 654
@@ -663,7 +666,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
663 return 0; 666 return 0;
664 667
665 case HDIO_GET_IDENTITY: 668 case HDIO_GET_IDENTITY:
666 return ata_get_identity(scsidev, arg); 669 return ata_get_identity(ap, scsidev, arg);
667 670
668 case HDIO_DRIVE_CMD: 671 case HDIO_DRIVE_CMD:
669 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 672 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
@@ -682,6 +685,14 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
682 685
683 return rc; 686 return rc;
684} 687}
688EXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl);
689
690int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
691{
692 return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host),
693 scsidev, cmd, arg);
694}
695EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
685 696
686/** 697/**
687 * ata_scsi_qc_new - acquire new ata_queued_cmd reference 698 * ata_scsi_qc_new - acquire new ata_queued_cmd reference
@@ -1294,6 +1305,17 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
1294 1305
1295 tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ 1306 tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
1296 } else { 1307 } else {
1308 /* Some odd clown BIOSen issue spindown on power off (ACPI S4
1309 * or S5) causing some drives to spin up and down again.
1310 */
1311 if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
1312 system_state == SYSTEM_POWER_OFF)
1313 goto skip;
1314
1315 if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
1316 system_entering_hibernation())
1317 goto skip;
1318
1297 /* XXX: This is for backward compatibility, will be 1319 /* XXX: This is for backward compatibility, will be
1298 * removed. Read Documentation/feature-removal-schedule.txt 1320 * removed. Read Documentation/feature-removal-schedule.txt
1299 * for more info. 1321 * for more info.
@@ -1317,8 +1339,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
1317 scmd->scsi_done = qc->scsidone; 1339 scmd->scsi_done = qc->scsidone;
1318 qc->scsidone = ata_delayed_done; 1340 qc->scsidone = ata_delayed_done;
1319 } 1341 }
1320 scmd->result = SAM_STAT_GOOD; 1342 goto skip;
1321 return 1;
1322 } 1343 }
1323 1344
1324 /* Issue ATA STANDBY IMMEDIATE command */ 1345 /* Issue ATA STANDBY IMMEDIATE command */
@@ -1334,10 +1355,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
1334 1355
1335 return 0; 1356 return 0;
1336 1357
1337invalid_fld: 1358 invalid_fld:
1338 ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); 1359 ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
1339 /* "Invalid field in cbd" */ 1360 /* "Invalid field in cbd" */
1340 return 1; 1361 return 1;
1362 skip:
1363 scmd->result = SAM_STAT_GOOD;
1364 return 1;
1341} 1365}
1342 1366
1343 1367