[PATCH] sata_sis: fix flags handling for the secondary port

sis_init_one() modifies probe_ent->port_flags after allocating and
initializing it using ata_pci_init_native_mode(). This makes port_flags
for the secondary port (probe_ent->pinfo2->flags) go out of sync resulting
in misdetection of device due to incorrectly initialized SCR access flag.

This patch make probe_ent alloc/init happen after the final port flags
value is determined. This is fragile but probe_ent and all the related
mess are scheduled to go away soon for exactly this reason. We just need
to hold everything together till then.

This has been spotted and diagnosed and tested by Patrick McHardy.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Patric McHardy <kaber@trash.net>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Tejun Heo and committed by Jeff Garzik cf0e812f d5b9b787

+10 -11
+10 -11
drivers/ata/sata_sis.c
··· 240 struct ata_probe_ent *probe_ent = NULL; 241 int rc; 242 u32 genctl; 243 - struct ata_port_info *ppi[2]; 244 int pci_dev_busy = 0; 245 u8 pmr; 246 u8 port2_start; ··· 265 if (rc) 266 goto err_out_regions; 267 268 - ppi[0] = ppi[1] = &sis_port_info; 269 - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 270 - if (!probe_ent) { 271 - rc = -ENOMEM; 272 - goto err_out_regions; 273 - } 274 - 275 /* check and see if the SCRs are in IO space or PCI cfg space */ 276 pci_read_config_dword(pdev, SIS_GENCTL, &genctl); 277 if ((genctl & GENCTL_IOMAPPED_SCR) == 0) 278 - probe_ent->port_flags |= SIS_FLAG_CFGSCR; 279 280 /* if hardware thinks SCRs are in IO space, but there are 281 * no IO resources assigned, change to PCI cfg space. 282 */ 283 - if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) && 284 ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || 285 (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { 286 genctl &= ~GENCTL_IOMAPPED_SCR; 287 pci_write_config_dword(pdev, SIS_GENCTL, genctl); 288 - probe_ent->port_flags |= SIS_FLAG_CFGSCR; 289 } 290 291 pci_read_config_byte(pdev, SIS_PMR, &pmr); ··· 297 else { 298 dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n"); 299 port2_start = 0x20; 300 } 301 302 if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
··· 240 struct ata_probe_ent *probe_ent = NULL; 241 int rc; 242 u32 genctl; 243 + struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; 244 int pci_dev_busy = 0; 245 u8 pmr; 246 u8 port2_start; ··· 265 if (rc) 266 goto err_out_regions; 267 268 /* check and see if the SCRs are in IO space or PCI cfg space */ 269 pci_read_config_dword(pdev, SIS_GENCTL, &genctl); 270 if ((genctl & GENCTL_IOMAPPED_SCR) == 0) 271 + pi.flags |= SIS_FLAG_CFGSCR; 272 273 /* if hardware thinks SCRs are in IO space, but there are 274 * no IO resources assigned, change to PCI cfg space. 275 */ 276 + if ((!(pi.flags & SIS_FLAG_CFGSCR)) && 277 ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || 278 (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { 279 genctl &= ~GENCTL_IOMAPPED_SCR; 280 pci_write_config_dword(pdev, SIS_GENCTL, genctl); 281 + pi.flags |= SIS_FLAG_CFGSCR; 282 } 283 284 pci_read_config_byte(pdev, SIS_PMR, &pmr); ··· 304 else { 305 dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n"); 306 port2_start = 0x20; 307 + } 308 + 309 + probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 310 + if (!probe_ent) { 311 + rc = -ENOMEM; 312 + goto err_out_regions; 313 } 314 315 if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {