.. | .. |
---|
3051 | 3051 | */ |
---|
3052 | 3052 | if (spd > 1) |
---|
3053 | 3053 | mask &= (1 << (spd - 1)) - 1; |
---|
3054 | | - else |
---|
| 3054 | + else if (link->sata_spd) |
---|
3055 | 3055 | return -EINVAL; |
---|
3056 | 3056 | |
---|
3057 | 3057 | /* were we already at the bottom? */ |
---|
.. | .. |
---|
4974 | 4974 | struct ata_link *link; |
---|
4975 | 4975 | unsigned long flags; |
---|
4976 | 4976 | |
---|
4977 | | - /* Previous resume operation might still be in |
---|
4978 | | - * progress. Wait for PM_PENDING to clear. |
---|
4979 | | - */ |
---|
4980 | | - if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
---|
4981 | | - ata_port_wait_eh(ap); |
---|
4982 | | - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
---|
4983 | | - } |
---|
4984 | | - |
---|
4985 | | - /* request PM ops to EH */ |
---|
4986 | 4977 | spin_lock_irqsave(ap->lock, flags); |
---|
4987 | 4978 | |
---|
| 4979 | + /* |
---|
| 4980 | + * A previous PM operation might still be in progress. Wait for |
---|
| 4981 | + * ATA_PFLAG_PM_PENDING to clear. |
---|
| 4982 | + */ |
---|
| 4983 | + if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
---|
| 4984 | + spin_unlock_irqrestore(ap->lock, flags); |
---|
| 4985 | + ata_port_wait_eh(ap); |
---|
| 4986 | + spin_lock_irqsave(ap->lock, flags); |
---|
| 4987 | + } |
---|
| 4988 | + |
---|
| 4989 | + /* Request PM operation to EH */ |
---|
4988 | 4990 | ap->pm_mesg = mesg; |
---|
4989 | 4991 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
---|
4990 | 4992 | ata_for_each_link(link, ap, HOST_FIRST) { |
---|
.. | .. |
---|
4996 | 4998 | |
---|
4997 | 4999 | spin_unlock_irqrestore(ap->lock, flags); |
---|
4998 | 5000 | |
---|
4999 | | - if (!async) { |
---|
| 5001 | + if (!async) |
---|
5000 | 5002 | ata_port_wait_eh(ap); |
---|
5001 | | - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
---|
5002 | | - } |
---|
5003 | 5003 | } |
---|
5004 | 5004 | |
---|
5005 | 5005 | /* |
---|
.. | .. |
---|
5167 | 5167 | #endif |
---|
5168 | 5168 | |
---|
5169 | 5169 | const struct device_type ata_port_type = { |
---|
5170 | | - .name = "ata_port", |
---|
| 5170 | + .name = ATA_PORT_TYPE_NAME, |
---|
5171 | 5171 | #ifdef CONFIG_PM |
---|
5172 | 5172 | .pm = &ata_port_pm_ops, |
---|
5173 | 5173 | #endif |
---|
.. | .. |
---|
5915 | 5915 | if (!ap->ops->error_handler) |
---|
5916 | 5916 | goto skip_eh; |
---|
5917 | 5917 | |
---|
5918 | | - /* tell EH we're leaving & flush EH */ |
---|
| 5918 | + /* Wait for any ongoing EH */ |
---|
| 5919 | + ata_port_wait_eh(ap); |
---|
| 5920 | + |
---|
| 5921 | + mutex_lock(&ap->scsi_scan_mutex); |
---|
5919 | 5922 | spin_lock_irqsave(ap->lock, flags); |
---|
| 5923 | + |
---|
| 5924 | + /* Remove scsi devices */ |
---|
| 5925 | + ata_for_each_link(link, ap, HOST_FIRST) { |
---|
| 5926 | + ata_for_each_dev(dev, link, ALL) { |
---|
| 5927 | + if (dev->sdev) { |
---|
| 5928 | + spin_unlock_irqrestore(ap->lock, flags); |
---|
| 5929 | + scsi_remove_device(dev->sdev); |
---|
| 5930 | + spin_lock_irqsave(ap->lock, flags); |
---|
| 5931 | + dev->sdev = NULL; |
---|
| 5932 | + } |
---|
| 5933 | + } |
---|
| 5934 | + } |
---|
| 5935 | + |
---|
| 5936 | + /* Tell EH to disable all devices */ |
---|
5920 | 5937 | ap->pflags |= ATA_PFLAG_UNLOADING; |
---|
5921 | 5938 | ata_port_schedule_eh(ap); |
---|
| 5939 | + |
---|
5922 | 5940 | spin_unlock_irqrestore(ap->lock, flags); |
---|
| 5941 | + mutex_unlock(&ap->scsi_scan_mutex); |
---|
5923 | 5942 | |
---|
5924 | 5943 | /* wait till EH commits suicide */ |
---|
5925 | 5944 | ata_port_wait_eh(ap); |
---|