Subject: Re: pci_read_config_byte
To: Hubert Feyrer <hubert@feyrer.de>
From: Ed <garbageout@sbcglobal.net>
List: tech-kern
Date: 05/28/2005 13:26:29
Hubert Feyrer wrote:
> On Sat, 28 May 2005, Ed wrote:
>
>> I'm borrowing some code from Linux. What is the NetBSD equivalent of
>> the Linux functions pci_read_config_byte and pci_write_config_byte? I
>> found pci_conf_read and pci_conf_write, but that seems to read and
>> write a whole dword. If this is not the correct forum for kernel
>> hacking, please advise.
>
>
> Maybe say (on the list!) what you want to do and/or what
> pci_read_config_byte etc. actually do? A prototype or so may help.
>
>
> - Hubert
So here's the piece of code I'm borrowing from Linux followed by my
implementation in NetBSD. Note that it SEEMS to work correctly, but I
am concerned about whether or not it IS correct. Also, this is a pretty
important patch because it fixes a bunch of siside lost interrupt
problems. Please advise.
Here's the original Linux code:
#define SIS_DETECT_REGISTER 0x40
static void __init quirk_sis_503(struct pci_dev *dev)
{
u8 reg;
u16 devid;
pci_read_config_byte(dev, SIS_DETECT_REGISTER, ®);
pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg | (1 << 6));
pci_read_config_word(dev, PCI_DEVICE_ID, &devid);
if (((devid & 0xfff0) != 0x0960) && (devid != 0x0018)) {
pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg);
return;
}
/* Make people aware that we changed the config.. */
printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503
(compatible=%d)\n", devid, sis_96x_compatible);
/*
* Ok, it now shows up as a 96x.. The 96x quirks are after
* the 503 quirk in the quirk table, so they'll automatically
* run and enable things like the SMBus device
*/
dev->device = devid;
}
Here's my (working, but questionably correct) implementation for NetBSD:
static int
sis_hostbr_quirk(struct pci_attach_args *pa)
{
pcireg_t id, reg;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_SIS ||
PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_SIS_85C503) {
return 0;
}
reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg | (1 << 6));
id = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
if (((PCI_PRODUCT(id) & 0xfff0) != 0x0960)
&& (PCI_PRODUCT(id) != 0x0018)) {
pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg);
return 0;
}
aprint_normal("hidden ");
pa->pa_id = id;
return 1;
}