aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig10
-rw-r--r--drivers/scsi/ata_piix.c4
-rw-r--r--drivers/scsi/libata-core.c114
-rw-r--r--drivers/scsi/libata-scsi.c16
-rw-r--r--drivers/scsi/scsi_sysfs.c31
5 files changed, 170 insertions, 5 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 4c42065dea8..3c606cf8c8c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -914,7 +914,7 @@ config SCSI_INIA100
914 914
915config SCSI_PPA 915config SCSI_PPA
916 tristate "IOMEGA parallel port (ppa - older drives)" 916 tristate "IOMEGA parallel port (ppa - older drives)"
917 depends on SCSI && PARPORT 917 depends on SCSI && PARPORT_PC
918 ---help--- 918 ---help---
919 This driver supports older versions of IOMEGA's parallel port ZIP 919 This driver supports older versions of IOMEGA's parallel port ZIP
920 drive (a 100 MB removable media device). 920 drive (a 100 MB removable media device).
@@ -941,7 +941,7 @@ config SCSI_PPA
941 941
942config SCSI_IMM 942config SCSI_IMM
943 tristate "IOMEGA parallel port (imm - newer drives)" 943 tristate "IOMEGA parallel port (imm - newer drives)"
944 depends on SCSI && PARPORT 944 depends on SCSI && PARPORT_PC
945 ---help--- 945 ---help---
946 This driver supports newer versions of IOMEGA's parallel port ZIP 946 This driver supports newer versions of IOMEGA's parallel port ZIP
947 drive (a 100 MB removable media device). 947 drive (a 100 MB removable media device).
@@ -968,7 +968,7 @@ config SCSI_IMM
968 968
969config SCSI_IZIP_EPP16 969config SCSI_IZIP_EPP16
970 bool "ppa/imm option - Use slow (but safe) EPP-16" 970 bool "ppa/imm option - Use slow (but safe) EPP-16"
971 depends on PARPORT && (SCSI_PPA || SCSI_IMM) 971 depends on SCSI_PPA || SCSI_IMM
972 ---help--- 972 ---help---
973 EPP (Enhanced Parallel Port) is a standard for parallel ports which 973 EPP (Enhanced Parallel Port) is a standard for parallel ports which
974 allows them to act as expansion buses that can handle up to 64 974 allows them to act as expansion buses that can handle up to 64
@@ -983,7 +983,7 @@ config SCSI_IZIP_EPP16
983 983
984config SCSI_IZIP_SLOW_CTR 984config SCSI_IZIP_SLOW_CTR
985 bool "ppa/imm option - Assume slow parport control register" 985 bool "ppa/imm option - Assume slow parport control register"
986 depends on PARPORT && (SCSI_PPA || SCSI_IMM) 986 depends on SCSI_PPA || SCSI_IMM
987 help 987 help
988 Some parallel ports are known to have excessive delays between 988 Some parallel ports are known to have excessive delays between
989 changing the parallel port control register and good data being 989 changing the parallel port control register and good data being
@@ -1815,7 +1815,7 @@ config SCSI_SUNESP
1815 1815
1816config ZFCP 1816config ZFCP
1817 tristate "FCP host bus adapter driver for IBM eServer zSeries" 1817 tristate "FCP host bus adapter driver for IBM eServer zSeries"
1818 depends on ARCH_S390 && QDIO && SCSI 1818 depends on S390 && QDIO && SCSI
1819 select SCSI_FC_ATTRS 1819 select SCSI_FC_ATTRS
1820 help 1820 help
1821 If you want to access SCSI devices attached to your IBM eServer 1821 If you want to access SCSI devices attached to your IBM eServer
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 4b647eefc9a..557788ec4ee 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -166,6 +166,8 @@ static struct pci_driver piix_pci_driver = {
166 .id_table = piix_pci_tbl, 166 .id_table = piix_pci_tbl,
167 .probe = piix_init_one, 167 .probe = piix_init_one,
168 .remove = ata_pci_remove_one, 168 .remove = ata_pci_remove_one,
169 .suspend = ata_pci_device_suspend,
170 .resume = ata_pci_device_resume,
169}; 171};
170 172
171static struct scsi_host_template piix_sht = { 173static struct scsi_host_template piix_sht = {
@@ -185,6 +187,8 @@ static struct scsi_host_template piix_sht = {
185 .dma_boundary = ATA_DMA_BOUNDARY, 187 .dma_boundary = ATA_DMA_BOUNDARY,
186 .slave_configure = ata_scsi_slave_config, 188 .slave_configure = ata_scsi_slave_config,
187 .bios_param = ata_std_bios_param, 189 .bios_param = ata_std_bios_param,
190 .resume = ata_scsi_device_resume,
191 .suspend = ata_scsi_device_suspend,
188}; 192};
189 193
190static const struct ata_port_operations piix_pata_ops = { 194static const struct ata_port_operations piix_pata_ops = {
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index bdfb0a88cd6..f55b9b3f7b3 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4173,6 +4173,96 @@ err_out:
4173 * Inherited from caller. 4173 * Inherited from caller.
4174 */ 4174 */
4175 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
4176int ata_port_start (struct ata_port *ap) 4266int ata_port_start (struct ata_port *ap)
4177{ 4267{
4178 struct device *dev = ap->host_set->dev; 4268 struct device *dev = ap->host_set->dev;
@@ -4921,6 +5011,23 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
4921 5011
4922 return (tmp == bits->val) ? 1 : 0; 5012 return (tmp == bits->val) ? 1 : 0;
4923} 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}
4924#endif /* CONFIG_PCI */ 5031#endif /* CONFIG_PCI */
4925 5032
4926 5033
@@ -5024,4 +5131,11 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
5024EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); 5131EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
5025EXPORT_SYMBOL_GPL(ata_pci_init_one); 5132EXPORT_SYMBOL_GPL(ata_pci_init_one);
5026EXPORT_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);
5027#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);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 2c644cbb6e9..cfbceb50471 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -396,6 +396,22 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
396 } 396 }
397} 397}
398 398
399int ata_scsi_device_resume(struct scsi_device *sdev)
400{
401 struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
402 struct ata_device *dev = &ap->device[sdev->id];
403
404 return ata_device_resume(ap, dev);
405}
406
407int ata_scsi_device_suspend(struct scsi_device *sdev)
408{
409 struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
410 struct ata_device *dev = &ap->device[sdev->id];
411
412 return ata_device_suspend(ap, dev);
413}
414
399/** 415/**
400 * ata_to_sense_error - convert ATA error to SCSI error 416 * ata_to_sense_error - convert ATA error to SCSI error
401 * @id: ATA device number 417 * @id: ATA device number
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 15842b1f0f4..ea7f3a43357 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -263,9 +263,40 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
263 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; 263 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
264} 264}
265 265
266static int scsi_bus_suspend(struct device * dev, pm_message_t state)
267{
268 struct scsi_device *sdev = to_scsi_device(dev);
269 struct scsi_host_template *sht = sdev->host->hostt;
270 int err;
271
272 err = scsi_device_quiesce(sdev);
273 if (err)
274 return err;
275
276 if (sht->suspend)
277 err = sht->suspend(sdev);
278
279 return err;
280}
281
282static int scsi_bus_resume(struct device * dev)
283{
284 struct scsi_device *sdev = to_scsi_device(dev);
285 struct scsi_host_template *sht = sdev->host->hostt;
286 int err = 0;
287
288 if (sht->resume)
289 err = sht->resume(sdev);
290
291 scsi_device_resume(sdev);
292 return err;
293}
294
266struct bus_type scsi_bus_type = { 295struct bus_type scsi_bus_type = {
267 .name = "scsi", 296 .name = "scsi",
268 .match = scsi_bus_match, 297 .match = scsi_bus_match,
298 .suspend = scsi_bus_suspend,
299 .resume = scsi_bus_resume,
269}; 300};
270 301
271int scsi_sysfs_register(void) 302int scsi_sysfs_register(void)