aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c145
1 files changed, 139 insertions, 6 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 9ea102587914..f55b9b3f7b37 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -562,16 +562,28 @@ static const u8 ata_rw_cmds[] = {
562 ATA_CMD_WRITE_MULTI, 562 ATA_CMD_WRITE_MULTI,
563 ATA_CMD_READ_MULTI_EXT, 563 ATA_CMD_READ_MULTI_EXT,
564 ATA_CMD_WRITE_MULTI_EXT, 564 ATA_CMD_WRITE_MULTI_EXT,
565 0,
566 0,
567 0,
568 ATA_CMD_WRITE_MULTI_FUA_EXT,
565 /* pio */ 569 /* pio */
566 ATA_CMD_PIO_READ, 570 ATA_CMD_PIO_READ,
567 ATA_CMD_PIO_WRITE, 571 ATA_CMD_PIO_WRITE,
568 ATA_CMD_PIO_READ_EXT, 572 ATA_CMD_PIO_READ_EXT,
569 ATA_CMD_PIO_WRITE_EXT, 573 ATA_CMD_PIO_WRITE_EXT,
574 0,
575 0,
576 0,
577 0,
570 /* dma */ 578 /* dma */
571 ATA_CMD_READ, 579 ATA_CMD_READ,
572 ATA_CMD_WRITE, 580 ATA_CMD_WRITE,
573 ATA_CMD_READ_EXT, 581 ATA_CMD_READ_EXT,
574 ATA_CMD_WRITE_EXT 582 ATA_CMD_WRITE_EXT,
583 0,
584 0,
585 0,
586 ATA_CMD_WRITE_FUA_EXT
575}; 587};
576 588
577/** 589/**
@@ -584,25 +596,32 @@ static const u8 ata_rw_cmds[] = {
584 * LOCKING: 596 * LOCKING:
585 * caller. 597 * caller.
586 */ 598 */
587void ata_rwcmd_protocol(struct ata_queued_cmd *qc) 599int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
588{ 600{
589 struct ata_taskfile *tf = &qc->tf; 601 struct ata_taskfile *tf = &qc->tf;
590 struct ata_device *dev = qc->dev; 602 struct ata_device *dev = qc->dev;
603 u8 cmd;
591 604
592 int index, lba48, write; 605 int index, fua, lba48, write;
593 606
607 fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
594 lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0; 608 lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
595 write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0; 609 write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
596 610
597 if (dev->flags & ATA_DFLAG_PIO) { 611 if (dev->flags & ATA_DFLAG_PIO) {
598 tf->protocol = ATA_PROT_PIO; 612 tf->protocol = ATA_PROT_PIO;
599 index = dev->multi_count ? 0 : 4; 613 index = dev->multi_count ? 0 : 8;
600 } else { 614 } else {
601 tf->protocol = ATA_PROT_DMA; 615 tf->protocol = ATA_PROT_DMA;
602 index = 8; 616 index = 16;
603 } 617 }
604 618
605 tf->command = ata_rw_cmds[index + lba48 + write]; 619 cmd = ata_rw_cmds[index + fua + lba48 + write];
620 if (cmd) {
621 tf->command = cmd;
622 return 0;
623 }
624 return -1;
606} 625}
607 626
608static const char * const xfer_mode_str[] = { 627static const char * const xfer_mode_str[] = {
@@ -4154,6 +4173,96 @@ err_out:
4154 * Inherited from caller. 4173 * Inherited from caller.
4155 */ 4174 */
4156 4175
4176/*
4177 * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
4178 * without filling any other registers
4179 */
4180static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
4181 u8 cmd)
4182{
4183 struct ata_taskfile tf;
4184 int err;
4185
4186 ata_tf_init(ap, &tf, dev->devno);
4187
4188 tf.command = cmd;
4189 tf.flags |= ATA_TFLAG_DEVICE;
4190 tf.protocol = ATA_PROT_NODATA;
4191
4192 err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
4193 if (err)
4194 printk(KERN_ERR "%s: ata command failed: %d\n",
4195 __FUNCTION__, err);
4196
4197 return err;
4198}
4199
4200static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
4201{
4202 u8 cmd;
4203
4204 if (!ata_try_flush_cache(dev))
4205 return 0;
4206
4207 if (ata_id_has_flush_ext(dev->id))
4208 cmd = ATA_CMD_FLUSH_EXT;
4209 else
4210 cmd = ATA_CMD_FLUSH;
4211
4212 return ata_do_simple_cmd(ap, dev, cmd);
4213}
4214
4215static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
4216{
4217 return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
4218}
4219
4220static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
4221{
4222 return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
4223}
4224
4225/**
4226 * ata_device_resume - wakeup a previously suspended devices
4227 *
4228 * Kick the drive back into action, by sending it an idle immediate
4229 * command and making sure its transfer mode matches between drive
4230 * and host.
4231 *
4232 */
4233int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
4234{
4235 if (ap->flags & ATA_FLAG_SUSPENDED) {
4236 ap->flags &= ~ATA_FLAG_SUSPENDED;
4237 ata_set_mode(ap);
4238 }
4239 if (!ata_dev_present(dev))
4240 return 0;
4241 if (dev->class == ATA_DEV_ATA)
4242 ata_start_drive(ap, dev);
4243
4244 return 0;
4245}
4246
4247/**
4248 * ata_device_suspend - prepare a device for suspend
4249 *
4250 * Flush the cache on the drive, if appropriate, then issue a
4251 * standbynow command.
4252 *
4253 */
4254int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
4255{
4256 if (!ata_dev_present(dev))
4257 return 0;
4258 if (dev->class == ATA_DEV_ATA)
4259 ata_flush_cache(ap, dev);
4260
4261 ata_standby_drive(ap, dev);
4262 ap->flags |= ATA_FLAG_SUSPENDED;
4263 return 0;
4264}
4265
4157int ata_port_start (struct ata_port *ap) 4266int ata_port_start (struct ata_port *ap)
4158{ 4267{
4159 struct device *dev = ap->host_set->dev; 4268 struct device *dev = ap->host_set->dev;
@@ -4902,6 +5011,23 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
4902 5011
4903 return (tmp == bits->val) ? 1 : 0; 5012 return (tmp == bits->val) ? 1 : 0;
4904} 5013}
5014
5015int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
5016{
5017 pci_save_state(pdev);
5018 pci_disable_device(pdev);
5019 pci_set_power_state(pdev, PCI_D3hot);
5020 return 0;
5021}
5022
5023int ata_pci_device_resume(struct pci_dev *pdev)
5024{
5025 pci_set_power_state(pdev, PCI_D0);
5026 pci_restore_state(pdev);
5027 pci_enable_device(pdev);
5028 pci_set_master(pdev);
5029 return 0;
5030}
4905#endif /* CONFIG_PCI */ 5031#endif /* CONFIG_PCI */
4906 5032
4907 5033
@@ -5005,4 +5131,11 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
5005EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); 5131EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
5006EXPORT_SYMBOL_GPL(ata_pci_init_one); 5132EXPORT_SYMBOL_GPL(ata_pci_init_one);
5007EXPORT_SYMBOL_GPL(ata_pci_remove_one); 5133EXPORT_SYMBOL_GPL(ata_pci_remove_one);
5134EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
5135EXPORT_SYMBOL_GPL(ata_pci_device_resume);
5008#endif /* CONFIG_PCI */ 5136#endif /* CONFIG_PCI */
5137
5138EXPORT_SYMBOL_GPL(ata_device_suspend);
5139EXPORT_SYMBOL_GPL(ata_device_resume);
5140EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
5141EXPORT_SYMBOL_GPL(ata_scsi_device_resume);