diff options
Diffstat (limited to 'drivers/ata/sata_sis.c')
-rw-r--r-- | drivers/ata/sata_sis.c | 75 |
1 files changed, 25 insertions, 50 deletions
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 8f9833228619..f8a91bfd66a8 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -109,8 +109,9 @@ MODULE_LICENSE("GPL"); | |||
109 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); | 109 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); |
110 | MODULE_VERSION(DRV_VERSION); | 110 | MODULE_VERSION(DRV_VERSION); |
111 | 111 | ||
112 | static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) | 112 | static unsigned int get_scr_cfg_addr(struct ata_link *link, unsigned int sc_reg) |
113 | { | 113 | { |
114 | struct ata_port *ap = link->ap; | ||
114 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 115 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
115 | unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); | 116 | unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); |
116 | u8 pmr; | 117 | u8 pmr; |
@@ -131,6 +132,9 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) | |||
131 | break; | 132 | break; |
132 | } | 133 | } |
133 | } | 134 | } |
135 | if (link->pmp) | ||
136 | addr += 0x10; | ||
137 | |||
134 | return addr; | 138 | return addr; |
135 | } | 139 | } |
136 | 140 | ||
@@ -138,24 +142,12 @@ static u32 sis_scr_cfg_read(struct ata_link *link, | |||
138 | unsigned int sc_reg, u32 *val) | 142 | unsigned int sc_reg, u32 *val) |
139 | { | 143 | { |
140 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); | 144 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); |
141 | unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg); | 145 | unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg); |
142 | u32 val2 = 0; | ||
143 | u8 pmr; | ||
144 | 146 | ||
145 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ | 147 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
146 | return -EINVAL; | 148 | return -EINVAL; |
147 | 149 | ||
148 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | ||
149 | |||
150 | pci_read_config_dword(pdev, cfg_addr, val); | 150 | pci_read_config_dword(pdev, cfg_addr, val); |
151 | |||
152 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | ||
153 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | ||
154 | pci_read_config_dword(pdev, cfg_addr+0x10, &val2); | ||
155 | |||
156 | *val |= val2; | ||
157 | *val &= 0xfffffffb; /* avoid problems with powerdowned ports */ | ||
158 | |||
159 | return 0; | 151 | return 0; |
160 | } | 152 | } |
161 | 153 | ||
@@ -163,28 +155,16 @@ static int sis_scr_cfg_write(struct ata_link *link, | |||
163 | unsigned int sc_reg, u32 val) | 155 | unsigned int sc_reg, u32 val) |
164 | { | 156 | { |
165 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); | 157 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); |
166 | unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg); | 158 | unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg); |
167 | u8 pmr; | ||
168 | |||
169 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ | ||
170 | return -EINVAL; | ||
171 | |||
172 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | ||
173 | 159 | ||
174 | pci_write_config_dword(pdev, cfg_addr, val); | 160 | pci_write_config_dword(pdev, cfg_addr, val); |
175 | |||
176 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | ||
177 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | ||
178 | pci_write_config_dword(pdev, cfg_addr+0x10, val); | ||
179 | |||
180 | return 0; | 161 | return 0; |
181 | } | 162 | } |
182 | 163 | ||
183 | static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) | 164 | static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) |
184 | { | 165 | { |
185 | struct ata_port *ap = link->ap; | 166 | struct ata_port *ap = link->ap; |
186 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 167 | void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10; |
187 | u8 pmr; | ||
188 | 168 | ||
189 | if (sc_reg > SCR_CONTROL) | 169 | if (sc_reg > SCR_CONTROL) |
190 | return -EINVAL; | 170 | return -EINVAL; |
@@ -192,39 +172,23 @@ static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) | |||
192 | if (ap->flags & SIS_FLAG_CFGSCR) | 172 | if (ap->flags & SIS_FLAG_CFGSCR) |
193 | return sis_scr_cfg_read(link, sc_reg, val); | 173 | return sis_scr_cfg_read(link, sc_reg, val); |
194 | 174 | ||
195 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 175 | *val = ioread32(base + sc_reg * 4); |
196 | |||
197 | *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); | ||
198 | |||
199 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | ||
200 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | ||
201 | *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); | ||
202 | |||
203 | *val &= 0xfffffffb; | ||
204 | |||
205 | return 0; | 176 | return 0; |
206 | } | 177 | } |
207 | 178 | ||
208 | static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) | 179 | static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) |
209 | { | 180 | { |
210 | struct ata_port *ap = link->ap; | 181 | struct ata_port *ap = link->ap; |
211 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 182 | void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10; |
212 | u8 pmr; | ||
213 | 183 | ||
214 | if (sc_reg > SCR_CONTROL) | 184 | if (sc_reg > SCR_CONTROL) |
215 | return -EINVAL; | 185 | return -EINVAL; |
216 | 186 | ||
217 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | ||
218 | |||
219 | if (ap->flags & SIS_FLAG_CFGSCR) | 187 | if (ap->flags & SIS_FLAG_CFGSCR) |
220 | return sis_scr_cfg_write(link, sc_reg, val); | 188 | return sis_scr_cfg_write(link, sc_reg, val); |
221 | else { | 189 | |
222 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 190 | iowrite32(val, base + (sc_reg * 4)); |
223 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | 191 | return 0; |
224 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | ||
225 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); | ||
226 | return 0; | ||
227 | } | ||
228 | } | 192 | } |
229 | 193 | ||
230 | static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 194 | static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
@@ -236,7 +200,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
236 | u32 genctl, val; | 200 | u32 genctl, val; |
237 | u8 pmr; | 201 | u8 pmr; |
238 | u8 port2_start = 0x20; | 202 | u8 port2_start = 0x20; |
239 | int rc; | 203 | int i, rc; |
240 | 204 | ||
241 | if (!printed_version++) | 205 | if (!printed_version++) |
242 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); | 206 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -319,6 +283,17 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
319 | if (rc) | 283 | if (rc) |
320 | return rc; | 284 | return rc; |
321 | 285 | ||
286 | for (i = 0; i < 2; i++) { | ||
287 | struct ata_port *ap = host->ports[i]; | ||
288 | |||
289 | if (ap->flags & ATA_FLAG_SATA && | ||
290 | ap->flags & ATA_FLAG_SLAVE_POSS) { | ||
291 | rc = ata_slave_link_init(ap); | ||
292 | if (rc) | ||
293 | return rc; | ||
294 | } | ||
295 | } | ||
296 | |||
322 | if (!(pi.flags & SIS_FLAG_CFGSCR)) { | 297 | if (!(pi.flags & SIS_FLAG_CFGSCR)) { |
323 | void __iomem *mmio; | 298 | void __iomem *mmio; |
324 | 299 | ||