Re: [PATCH] PCI: clean up the PCIe capability save/restore

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 08, 2009 at 05:53:49AM +0800, Jesse Barnes wrote:
> On Mon, 6 Apr 2009 19:46:37 -0600
> Matthew Wilcox <matthew@xxxxxx> wrote:
> 
> > On Tue, Apr 07, 2009 at 09:31:06AM +0800, Yu Zhao wrote:
> > > -#define PCI_EXP_SAVE_REGS	7
> > > +static const int pcie_save_regs[] = {
> > > +	PCI_EXP_DEVCTL,
> > > +	PCI_EXP_LNKCTL,
> > > +	PCI_EXP_SLTCTL,
> > > +	PCI_EXP_RTCTL,
> > > +	PCI_EXP_DEVCTL2,
> > > +	PCI_EXP_LNKCTL2,
> > > +	PCI_EXP_SLTCTL2
> > > +};
> > 
> > We could save a bit of space and store these as unsigned char, right?
> > 
> > > @@ -698,20 +706,15 @@ static int pci_save_pcie_state(struct pci_dev
> > > *dev) }
> > >  	cap = (u16 *)&save_state->data[0];
> > >  
> > > -	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2,
> > > &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2,
> > > &cap[i++]);
> > > -	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2,
> > > &cap[i++]);
> > > +	for (i = 0; i < ARRAY_SIZE(pcie_save_regs); i++)
> > > +		pci_read_config_word(dev, pos + pcie_save_regs[i],
> > > &cap[i]);
> > 
> > I never looked at this code before ... but this is terribly wrong.
> > None of the capabilities after DEVCTL are guaranteed to be there.  We
> > could be writing to some other register entirely.
> > 
> > Unfortunately, I think we need something like:
> > 
> > 	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
> > 	if (has_link)
> > 		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL,
> > &cap[i++]); if (has_slot)
> > 		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL,
> > &cap[i++]); if (root_port || root event collector)
> > 		pci_read_config_word(dev, pos + PCI_EXP_RTCTL,
> > &cap[i++]); if (cap_version < 2)
> > 		return;
> > 	... and so on ...
> > 
> > and that means that your rather good patch looks a lot harder to
> > implement.  We could maybe implement an array with pairs of (feature,
> > address), but that's probably more complex than it's worth.
> 
> I should have caught that when it went in; Yu can you code up a
> complete fix along the lines of what Matthew suggests?  We really can't
> touch potentially non-existent registers, and we definitely don't want
> to overwrite regs blindly...

Yes, I'll fix this. I was referring to the PCIe 2.0 spec, which requires
all registers that are not implemented by the device to be hardwired to 0.
I should check the PCIe 1.1 spec too...
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux