diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index dd81fa78cdcf..b6a1de8fad5b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |||
893 | return queue_depth; | 893 | return queue_depth; |
894 | } | 894 | } |
895 | 895 | ||
896 | /* XXX: for ata_spindown_compat */ | ||
897 | static void ata_delayed_done_timerfn(unsigned long arg) | ||
898 | { | ||
899 | struct scsi_cmnd *scmd = (void *)arg; | ||
900 | |||
901 | scmd->scsi_done(scmd); | ||
902 | } | ||
903 | |||
904 | /* XXX: for ata_spindown_compat */ | ||
905 | static void ata_delayed_done(struct scsi_cmnd *scmd) | ||
906 | { | ||
907 | static struct timer_list timer; | ||
908 | |||
909 | setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd); | ||
910 | mod_timer(&timer, jiffies + 5 * HZ); | ||
911 | } | ||
912 | |||
896 | /** | 913 | /** |
897 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | 914 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
898 | * @qc: Storage for translated ATA taskfile | 915 | * @qc: Storage for translated ATA taskfile |
@@ -950,21 +967,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
950 | * for more info. | 967 | * for more info. |
951 | */ | 968 | */ |
952 | if (ata_spindown_compat && | 969 | if (ata_spindown_compat && |
970 | (qc->dev->flags & ATA_DFLAG_SPUNDOWN) && | ||
953 | (system_state == SYSTEM_HALT || | 971 | (system_state == SYSTEM_HALT || |
954 | system_state == SYSTEM_POWER_OFF)) { | 972 | system_state == SYSTEM_POWER_OFF)) { |
955 | static int warned = 0; | 973 | static unsigned long warned = 0; |
956 | 974 | ||
957 | if (!warned) { | 975 | if (!test_and_set_bit(0, &warned)) { |
958 | spin_unlock_irq(qc->ap->lock); | ||
959 | ata_dev_printk(qc->dev, KERN_WARNING, | 976 | ata_dev_printk(qc->dev, KERN_WARNING, |
960 | "DISK MIGHT NOT BE SPUN DOWN PROPERLY. " | 977 | "DISK MIGHT NOT BE SPUN DOWN PROPERLY. " |
961 | "UPDATE SHUTDOWN UTILITY\n"); | 978 | "UPDATE SHUTDOWN UTILITY\n"); |
962 | ata_dev_printk(qc->dev, KERN_WARNING, | 979 | ata_dev_printk(qc->dev, KERN_WARNING, |
963 | "For more info, visit " | 980 | "For more info, visit " |
964 | "http://linux-ata.org/shutdown.html\n"); | 981 | "http://linux-ata.org/shutdown.html\n"); |
965 | warned = 1; | 982 | |
966 | ssleep(5); | 983 | /* ->scsi_done is not used, use it for |
967 | spin_lock_irq(qc->ap->lock); | 984 | * delayed completion. |
985 | */ | ||
986 | scmd->scsi_done = qc->scsidone; | ||
987 | qc->scsidone = ata_delayed_done; | ||
968 | } | 988 | } |
969 | scmd->result = SAM_STAT_GOOD; | 989 | scmd->result = SAM_STAT_GOOD; |
970 | return 1; | 990 | return 1; |
@@ -1375,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) | |||
1375 | } | 1395 | } |
1376 | } | 1396 | } |
1377 | 1397 | ||
1398 | /* XXX: track spindown state for spindown_compat */ | ||
1399 | if (unlikely(qc->tf.command == ATA_CMD_STANDBY || | ||
1400 | qc->tf.command == ATA_CMD_STANDBYNOW1)) | ||
1401 | qc->dev->flags |= ATA_DFLAG_SPUNDOWN; | ||
1402 | else if (likely(system_state != SYSTEM_HALT && | ||
1403 | system_state != SYSTEM_POWER_OFF)) | ||
1404 | qc->dev->flags &= ~ATA_DFLAG_SPUNDOWN; | ||
1405 | |||
1378 | if (need_sense && !ap->ops->error_handler) | 1406 | if (need_sense && !ap->ops->error_handler) |
1379 | ata_dump_status(ap->print_id, &qc->result_tf); | 1407 | ata_dump_status(ap->print_id, &qc->result_tf); |
1380 | 1408 | ||
@@ -1488,14 +1516,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
1488 | 1516 | ||
1489 | early_finish: | 1517 | early_finish: |
1490 | ata_qc_free(qc); | 1518 | ata_qc_free(qc); |
1491 | done(cmd); | 1519 | qc->scsidone(cmd); |
1492 | DPRINTK("EXIT - early finish (good or error)\n"); | 1520 | DPRINTK("EXIT - early finish (good or error)\n"); |
1493 | return 0; | 1521 | return 0; |
1494 | 1522 | ||
1495 | err_did: | 1523 | err_did: |
1496 | ata_qc_free(qc); | 1524 | ata_qc_free(qc); |
1497 | cmd->result = (DID_ERROR << 16); | 1525 | cmd->result = (DID_ERROR << 16); |
1498 | done(cmd); | 1526 | qc->scsidone(cmd); |
1499 | err_mem: | 1527 | err_mem: |
1500 | DPRINTK("EXIT - internal\n"); | 1528 | DPRINTK("EXIT - internal\n"); |
1501 | return 0; | 1529 | return 0; |