diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/scsi/ata_piix.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 114 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 16 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 31 |
5 files changed, 170 insertions, 5 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 4c42065dea88..3c606cf8c8ca 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -914,7 +914,7 @@ config SCSI_INIA100 | |||
914 | 914 | ||
915 | config SCSI_PPA | 915 | config 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 | ||
942 | config SCSI_IMM | 942 | config 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 | ||
969 | config SCSI_IZIP_EPP16 | 969 | config 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 | ||
984 | config SCSI_IZIP_SLOW_CTR | 984 | config 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 | ||
1816 | config ZFCP | 1816 | config 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 4b647eefc9a9..557788ec4eec 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 | ||
171 | static struct scsi_host_template piix_sht = { | 173 | static 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 | ||
190 | static const struct ata_port_operations piix_pata_ops = { | 194 | static const struct ata_port_operations piix_pata_ops = { |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index bdfb0a88cd6f..f55b9b3f7b37 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 | */ | ||
4180 | static 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 | |||
4200 | static 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 | |||
4215 | static 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 | |||
4220 | static 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 | */ | ||
4233 | int 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 | */ | ||
4254 | int 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 | |||
4176 | int ata_port_start (struct ata_port *ap) | 4266 | int 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 | |||
5015 | int 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 | |||
5023 | int 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); | |||
5024 | EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); | 5131 | EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); |
5025 | EXPORT_SYMBOL_GPL(ata_pci_init_one); | 5132 | EXPORT_SYMBOL_GPL(ata_pci_init_one); |
5026 | EXPORT_SYMBOL_GPL(ata_pci_remove_one); | 5133 | EXPORT_SYMBOL_GPL(ata_pci_remove_one); |
5134 | EXPORT_SYMBOL_GPL(ata_pci_device_suspend); | ||
5135 | EXPORT_SYMBOL_GPL(ata_pci_device_resume); | ||
5027 | #endif /* CONFIG_PCI */ | 5136 | #endif /* CONFIG_PCI */ |
5137 | |||
5138 | EXPORT_SYMBOL_GPL(ata_device_suspend); | ||
5139 | EXPORT_SYMBOL_GPL(ata_device_resume); | ||
5140 | EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); | ||
5141 | EXPORT_SYMBOL_GPL(ata_scsi_device_resume); | ||
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 2c644cbb6e9c..cfbceb504718 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 | ||
399 | int 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 | |||
407 | int 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 15842b1f0f4a..ea7f3a433572 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 | ||
266 | static 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 | |||
282 | static 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 | |||
266 | struct bus_type scsi_bus_type = { | 295 | struct 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 | ||
271 | int scsi_sysfs_register(void) | 302 | int scsi_sysfs_register(void) |