aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_sis.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_sis.c')
-rw-r--r--drivers/ata/sata_sis.c75
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");
109MODULE_DEVICE_TABLE(pci, sis_pci_tbl); 109MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
110MODULE_VERSION(DRV_VERSION); 110MODULE_VERSION(DRV_VERSION);
111 111
112static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) 112static 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
183static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) 164static 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
208static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) 179static 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
230static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 194static 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