diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-23 21:52:44 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-24 23:42:47 -0400 |
commit | 8e5443a09851d99084098ecc4066805aa2610d92 (patch) | |
tree | 8a8046ac3eef4bf1f817451097d540eecbf0c488 /drivers/ata/sata_sis.c | |
parent | 2b4221bb545899b05872e7b51f55567c10b3894b (diff) |
sata_sis: SCR accessors return -EINVAL when requested SCR isn't available
sis_scr_cfg_read() can't access SError and was incorrectly returning
-1 instead of -EINVAL. This went unnoticed because SError used to be
cleared in @postreset() and it didn't care about how scr_read() failed
but commit ac371987 moved SError clearing into sata_link_resume() and
SCR access failure other than -EINVAL is considered an error condition
and exposes the incorrect return value bug as detection failure. Fix
it.
Also, scsi_scr_cfg_write() was incorrectly returning 0 after it
ignored the request to write to SError. Make it also return -EINVAL.
This was bisected and reported by Patrick McHardy.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Patrick McHardy <kaber@trash.net>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_sis.c')
-rw-r--r-- | drivers/ata/sata_sis.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 6b8e45ba32e8..1010b3069bd5 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -142,7 +142,7 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | |||
142 | u8 pmr; | 142 | u8 pmr; |
143 | 143 | ||
144 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ | 144 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
145 | return 0xffffffff; | 145 | return -EINVAL; |
146 | 146 | ||
147 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 147 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
148 | 148 | ||
@@ -158,14 +158,14 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | |||
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
161 | static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) | 161 | static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
162 | { | 162 | { |
163 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 163 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
164 | unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); | 164 | unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); |
165 | u8 pmr; | 165 | u8 pmr; |
166 | 166 | ||
167 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ | 167 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
168 | return; | 168 | return -EINVAL; |
169 | 169 | ||
170 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 170 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
171 | 171 | ||
@@ -174,6 +174,8 @@ static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
174 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | 174 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || |
175 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | 175 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) |
176 | pci_write_config_dword(pdev, cfg_addr+0x10, val); | 176 | pci_write_config_dword(pdev, cfg_addr+0x10, val); |
177 | |||
178 | return 0; | ||
177 | } | 179 | } |
178 | 180 | ||
179 | static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | 181 | static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
@@ -211,14 +213,14 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
211 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 213 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
212 | 214 | ||
213 | if (ap->flags & SIS_FLAG_CFGSCR) | 215 | if (ap->flags & SIS_FLAG_CFGSCR) |
214 | sis_scr_cfg_write(ap, sc_reg, val); | 216 | return sis_scr_cfg_write(ap, sc_reg, val); |
215 | else { | 217 | else { |
216 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 218 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
217 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | 219 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || |
218 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | 220 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) |
219 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); | 221 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); |
222 | return 0; | ||
220 | } | 223 | } |
221 | return 0; | ||
222 | } | 224 | } |
223 | 225 | ||
224 | static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 226 | static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |