diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 81 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
2 files changed, 50 insertions, 32 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 5cc53cd9323e..72bdc91e148c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -4123,6 +4123,53 @@ err_out: | |||
4123 | } | 4123 | } |
4124 | 4124 | ||
4125 | /** | 4125 | /** |
4126 | * ata_host_set_remove - PCI layer callback for device removal | ||
4127 | * @host_set: ATA host set that was removed | ||
4128 | * | ||
4129 | * Unregister all objects associated with this host set. Free those | ||
4130 | * objects. | ||
4131 | * | ||
4132 | * LOCKING: | ||
4133 | * Inherited from calling layer (may sleep). | ||
4134 | */ | ||
4135 | |||
4136 | |||
4137 | void ata_host_set_remove(struct ata_host_set *host_set) | ||
4138 | { | ||
4139 | struct ata_port *ap; | ||
4140 | unsigned int i; | ||
4141 | |||
4142 | for (i = 0; i < host_set->n_ports; i++) { | ||
4143 | ap = host_set->ports[i]; | ||
4144 | scsi_remove_host(ap->host); | ||
4145 | } | ||
4146 | |||
4147 | free_irq(host_set->irq, host_set); | ||
4148 | |||
4149 | for (i = 0; i < host_set->n_ports; i++) { | ||
4150 | ap = host_set->ports[i]; | ||
4151 | |||
4152 | ata_scsi_release(ap->host); | ||
4153 | |||
4154 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | ||
4155 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
4156 | |||
4157 | if (ioaddr->cmd_addr == 0x1f0) | ||
4158 | release_region(0x1f0, 8); | ||
4159 | else if (ioaddr->cmd_addr == 0x170) | ||
4160 | release_region(0x170, 8); | ||
4161 | } | ||
4162 | |||
4163 | scsi_host_put(ap->host); | ||
4164 | } | ||
4165 | |||
4166 | if (host_set->ops->host_stop) | ||
4167 | host_set->ops->host_stop(host_set); | ||
4168 | |||
4169 | kfree(host_set); | ||
4170 | } | ||
4171 | |||
4172 | /** | ||
4126 | * ata_scsi_release - SCSI layer callback hook for host unload | 4173 | * ata_scsi_release - SCSI layer callback hook for host unload |
4127 | * @host: libata host to be unloaded | 4174 | * @host: libata host to be unloaded |
4128 | * | 4175 | * |
@@ -4462,39 +4509,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
4462 | { | 4509 | { |
4463 | struct device *dev = pci_dev_to_dev(pdev); | 4510 | struct device *dev = pci_dev_to_dev(pdev); |
4464 | struct ata_host_set *host_set = dev_get_drvdata(dev); | 4511 | struct ata_host_set *host_set = dev_get_drvdata(dev); |
4465 | struct ata_port *ap; | ||
4466 | unsigned int i; | ||
4467 | |||
4468 | for (i = 0; i < host_set->n_ports; i++) { | ||
4469 | ap = host_set->ports[i]; | ||
4470 | |||
4471 | scsi_remove_host(ap->host); | ||
4472 | } | ||
4473 | |||
4474 | free_irq(host_set->irq, host_set); | ||
4475 | |||
4476 | for (i = 0; i < host_set->n_ports; i++) { | ||
4477 | ap = host_set->ports[i]; | ||
4478 | |||
4479 | ata_scsi_release(ap->host); | ||
4480 | |||
4481 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | ||
4482 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
4483 | |||
4484 | if (ioaddr->cmd_addr == 0x1f0) | ||
4485 | release_region(0x1f0, 8); | ||
4486 | else if (ioaddr->cmd_addr == 0x170) | ||
4487 | release_region(0x170, 8); | ||
4488 | } | ||
4489 | |||
4490 | scsi_host_put(ap->host); | ||
4491 | } | ||
4492 | |||
4493 | if (host_set->ops->host_stop) | ||
4494 | host_set->ops->host_stop(host_set); | ||
4495 | |||
4496 | kfree(host_set); | ||
4497 | 4512 | ||
4513 | ata_host_set_remove(host_set); | ||
4498 | pci_release_regions(pdev); | 4514 | pci_release_regions(pdev); |
4499 | pci_disable_device(pdev); | 4515 | pci_disable_device(pdev); |
4500 | dev_set_drvdata(dev, NULL); | 4516 | dev_set_drvdata(dev, NULL); |
@@ -4564,6 +4580,7 @@ module_exit(ata_exit); | |||
4564 | EXPORT_SYMBOL_GPL(ata_std_bios_param); | 4580 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
4565 | EXPORT_SYMBOL_GPL(ata_std_ports); | 4581 | EXPORT_SYMBOL_GPL(ata_std_ports); |
4566 | EXPORT_SYMBOL_GPL(ata_device_add); | 4582 | EXPORT_SYMBOL_GPL(ata_device_add); |
4583 | EXPORT_SYMBOL_GPL(ata_host_set_remove); | ||
4567 | EXPORT_SYMBOL_GPL(ata_sg_init); | 4584 | EXPORT_SYMBOL_GPL(ata_sg_init); |
4568 | EXPORT_SYMBOL_GPL(ata_sg_init_one); | 4585 | EXPORT_SYMBOL_GPL(ata_sg_init_one); |
4569 | EXPORT_SYMBOL_GPL(ata_qc_complete); | 4586 | EXPORT_SYMBOL_GPL(ata_qc_complete); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 022105c745fc..ceee1fc42c60 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -393,6 +393,7 @@ extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_i | |||
393 | extern void ata_pci_remove_one (struct pci_dev *pdev); | 393 | extern void ata_pci_remove_one (struct pci_dev *pdev); |
394 | #endif /* CONFIG_PCI */ | 394 | #endif /* CONFIG_PCI */ |
395 | extern int ata_device_add(struct ata_probe_ent *ent); | 395 | extern int ata_device_add(struct ata_probe_ent *ent); |
396 | extern void ata_host_set_remove(struct ata_host_set *host_set); | ||
396 | extern int ata_scsi_detect(Scsi_Host_Template *sht); | 397 | extern int ata_scsi_detect(Scsi_Host_Template *sht); |
397 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); | 398 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); |
398 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); | 399 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); |