int verbose_request = 0;
module_param(verbose_request, int, 0644);
-/* TODO remove once this is fixed */
-static int disable_gm45_igfx_flr = 1;
-
struct pcistub_sbr_entry {
struct list_head dev_list;
struct pci_dev *dev;
* device. This uses the Advanced Features Capability extensions to
* the PCI spec.
*/
-static void pciback_do_pci_flr(struct pci_dev *dev, int af_pos)
+static void pciback_do_pci_flr(struct pci_dev *dev, int af_pos, int clear_cmd)
{
u8 status = 0;
pci_block_user_cfg_access(dev);
/* Clear the command register to prevent new transactions */
- pci_write_config_word(dev, PCI_COMMAND, 0);
+ if (clear_cmd)
+ pci_write_config_word(dev, PCI_COMMAND, 0);
/* Wait for Transaction Pending bit clean */
msleep(100);
struct pci_dev *gmch;
int vendor_pos, i;
u32 reg32 = 0;
- u16 device_id;
+ u16 device_id, cmd;
u8 reg8 = 0;
dev_dbg(&dev->dev, "doing vendor specific resets\n");
return -ENXIO;
if ((dev->class >> 8) == PCIBACK_CLASS_ID_VGA) {
- if (disable_gm45_igfx_flr)
- return -ENXIO;
-
if (dev->bus->number != 0 || dev->devfn != PCI_DEVFN(2,0))
return -ENXIO;
goto out;
}
}
-
- /* The rest is the same as a PCI AF FLR */
- pciback_do_pci_flr(dev, vendor_pos);
+
+ /* This specific reset will hang if the command register does not have
+ * memory space access enabled */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_write_config_word(dev, PCI_COMMAND, (cmd | PCI_COMMAND_MEMORY));
+ /* The rest is the same as a PCI AF FLR - use the same routine */
+ pciback_do_pci_flr(dev, vendor_pos, 0);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
} else {
pci_block_user_cfg_access(dev);
}
if (dev_data->dev_type == PCIBACK_TYPE_PCI &&
dev_data->af_flr_offset != 0) {
- pciback_do_pci_flr(dev, dev_data->af_flr_offset);
+ pciback_do_pci_flr(dev, dev_data->af_flr_offset, 1);
break;
}