Slightly off-topic, have you done any more work on the vt8237? I've resumed work on it, but I'm still stuck on the northbridge at the moment.
I'm attaching some files (except the NB code). I just did some minor tweaks, hope it compiles ;) The code is working well.
I have still old early smbus code - this works but maybe you have updated version?
Rudolf
/* * This file is part of the LinuxBIOS project. * * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define SMBUS_IO_BASE 0x0400 //static /* With this, is SMBUS_IO_BASE added during compile or runtime? */ #define SMBHSTSTAT SMBUS_IO_BASE + 0x0 #define SMBSLVSTAT SMBUS_IO_BASE + 0x1 #define SMBHSTCTL SMBUS_IO_BASE + 0x2 #define SMBHSTCMD SMBUS_IO_BASE + 0x3 #define SMBXMITADD SMBUS_IO_BASE + 0x4 #define SMBHSTDAT0 SMBUS_IO_BASE + 0x5 /* Rest of these aren't used... */ #define SMBHSTDAT1 SMBUS_IO_BASE + 0x6 #define SMBBLKDAT SMBUS_IO_BASE + 0x7 #define SMBSLVCTL SMBUS_IO_BASE + 0x8 #define SMBTRNSADD SMBUS_IO_BASE + 0x9 #define SMBSLVDATA SMBUS_IO_BASE + 0xa #define SMLINK_PIN_CTL SMBUS_IO_BASE + 0xe #define SMBUS_PIN_CTL SMBUS_IO_BASE + 0xf /* Define register settings */ #define HOST_RESET 0xff #define DIMM_BASE 0xa0 // 1010000 is base for DIMM in SMBus #define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ #define SMBUS_TIMEOUT (100*1000*10) #define I2C_TRANS_CMD 0x40 #define CLOCK_SLAVE_ADDRESS 0x69 /* Debugging macros. Only necessary if something isn't working right */ //#define DEBUG_SMBUS = 1 #ifdef DEBUG_SMBUS #define PRINT_DEBUG(x) print_debug(x) #define PRINT_DEBUG_HEX16(x) print_debug_hex16(x) #else #define PRINT_DEBUG(x) #define PRINT_DEBUG_HEX16(x) #endif /* TODO: datasheet link here */ /* See datasheet pages 125 and 137-139 */ /* Internal functions */ /* TODO: make define? */ #define SMBUS_DELAY() outb(0x80, 0x80) static void smbus_print_error(unsigned char host_status_register, int loops) { /* Check if there actually was an error */ if ( host_status_register == 0x00 || host_status_register == 0x40 || host_status_register == 0x42) return; print_err("smbus_error: "); print_err_hex8(host_status_register); print_err("Wait was \r\n"); print_err_hex8(loops); print_err("\r\n"); if (loops >= SMBUS_TIMEOUT) { print_err("SMBus Timout\r\n"); } if (host_status_register & (1 << 4)) { print_err("Interrup/SMI# was Failed Bus Transaction\r\n"); } if (host_status_register & (1 << 3)) { print_err("Bus Error\r\n"); } if (host_status_register & (1 << 2)) { print_err("Device Error\r\n"); } if (host_status_register & (1 << 1)) { print_err("Interrupt/SMI# was Successful Completion\r\n"); } if (host_status_register & (1 << 0)) { print_err("Host Busy\r\n"); } } static void smbus_wait_until_ready(void) { int loops; PRINT_DEBUG("Waiting until smbus ready\r\n"); loops = 0; /* Yes, this is a mess, but it's the easiest way to do it */ while((inb(SMBHSTSTAT) & 1) == 1 && loops <= SMBUS_TIMEOUT) ++loops; smbus_print_error(inb(SMBHSTSTAT), loops); } static void smbus_reset(void) { /* four resets? a little overboard? or just frustrated? */ outb(HOST_RESET, SMBHSTSTAT); #if 0 outb(HOST_RESET, SMBHSTSTAT); outb(HOST_RESET, SMBHSTSTAT); outb(HOST_RESET, SMBHSTSTAT); #endif /* Datasheet says we have to read it to take ownership of SMBus */ inb(SMBHSTSTAT); PRINT_DEBUG("After reset status: "); PRINT_DEBUG_HEX16( inb(SMBHSTSTAT)); PRINT_DEBUG("\r\n"); } /* Public functions */ static unsigned int get_spd_data(unsigned int dimm, unsigned int offset) { unsigned int val; print_debug("DIMM "); print_debug_hex8(dimm); print_debug(" OFFSET "); print_debug_hex8(offset); print_debug("\r\n"); smbus_reset(); /* clear host data port */ outb(0x00, SMBHSTDAT0); SMBUS_DELAY(); smbus_wait_until_ready(); /* Do some mathmatic magic */ dimm = (dimm << 1); // dimm &= 0x0E; // dimm |= 0xA1; dimm |= 1; outb(dimm, SMBXMITADD); outb(offset, SMBHSTCMD); outb(0x48, SMBHSTCTL); SMBUS_DELAY(); smbus_wait_until_ready(); val = inb(SMBHSTDAT0); print_debug("GOT "); print_debug_hex8(val); smbus_reset(); /* probably don't have to do this, but it can't hurt */ return val; /* can I just "return inb(SMBHSTDAT0)"? */ } static unsigned int smbus_read_byte(unsigned int dimm, unsigned int offset) { unsigned int data; data = get_spd_data(dimm, offset); return data; } /* Debugging Function */ #ifdef DEBUG_SMBUS static void dump_spd_data(void) { int dimm, offset, regs; unsigned int val; for(dimm = 0; dimm < 8; dimm++) { print_debug("SPD Data for DIMM "); print_debug_hex8(dimm); print_debug("\r\n"); val = get_spd_data(dimm, 0); if(val == 0xff) { regs = 256; } else if(val == 0x80) { regs = 128; } else { print_debug("No DIMM present\r\n"); regs = 0; } for(offset = 0; offset < regs; offset++) { print_debug(" Offset "); print_debug_hex8(offset); print_debug(" = 0x"); print_debug_hex8(get_spd_data(0x50 + dimm, offset)); print_debug("\r\n"); } } } #else #define dump_spd_data() #endif static void enable_smbus(void) { int c; device_t dev; /* Power management controller */ /* This should work, but there are more important things to work on */ /* dev = PCI_DEV(0, 0x11, 0); */ dev = pci_locate_device(PCI_ID(0x1106, 0x3227), 0); if (dev == PCI_DEV_INVALID) { die("Power Managment Controller not found\r\n"); } /* Set clock source */ pci_write_config8(dev, 0x94, 0xa0); /* Write SMBus IO base to 0xd0, and enable SMBus */ pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1); /* Set to Award value */ pci_write_config8(dev, 0xd2, 0x01); /* make it work for I/O ...*/ pci_write_config16(dev, 0x04, 0x0001); /* The other, slightly hackish, fixup method */ for(c = 0; c < 30; c++) get_spd_data(0x50, c); }
/* * This file is part of the LinuxBIOS project. * * Based on other VIA SB code, no native mode. Interrupts from unconnected HDDs * might occur if IRQ14/15 is used for PCI. Therefore no native mode support. * * Copyright (C) 2007 Rudolf Marek <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> #include <device/pci_ids.h> #include <console/console.h> #include "vt8237r.h" #include "chip.h" static void ide_init(struct device *dev) { struct southbridge_via_vt8237r_config *conf = dev->chip_info; unsigned char enables; printk_info("Enabling VIA IDE.\n"); enables = pci_read_config8(dev, 0x40); printk_debug("enables in reg 0x40 0x%x\n", enables); enables |= 3; //enable both channels pci_write_config8(dev, 0x40, enables); enables = pci_read_config8(dev, 0x40); printk_debug("enables in reg 0x40 read back as 0x%x\n", enables); printk_info("%s: enabling compatibility IDE addresses\n", __FUNCTION__); enables = pci_read_config8(dev, 0x42); printk_debug("enables in reg 0x42 0x%x\n", enables); enables &= ~0xc0; // compatability mode pci_write_config8(dev, 0x42, enables); enables = pci_read_config8(dev, 0x42); printk_debug("enables in reg 0x42 read back as 0x%x\n", enables); // Enable prefetch buffers enables = pci_read_config8(dev, 0x41); enables |= 0xf0; pci_write_config8(dev, 0x41, enables); // Lower thresholds (cause award does it) enables = pci_read_config8(dev, 0x43); enables &= ~0x0f; enables |= 0x05; pci_write_config8(dev, 0x43, enables); // PIO read prefetch counter (cause award does it) pci_write_config8(dev, 0x44, 0x18); // Use memory read multiple pci_write_config8(dev, 0x45, 0x1c); // address decoding. // we want "flexible", i.e. 1f0-1f7 etc. or native PCI // [EMAIL PROTECTED] - the standard linux drivers seem ass slow when // used in native mode - I've changed back to classic enables = pci_read_config8(dev, 0x9); printk_debug("enables in reg 0x9 0x%x\n", enables); enables &= ~0x5; pci_write_config8(dev, 0x9, enables); enables = pci_read_config8(dev, 0x9); printk_debug("enables in reg 0x9 read back as 0x%x\n", enables); // standard bios sets master bit. enables = pci_read_config8(dev, 0x4); printk_debug("command in reg 0x4 0x%x\n", enables); enables |= 5; // No need for stepping - [EMAIL PROTECTED] //enables &= ~0x80; pci_write_config8(dev, 0x4, enables); enables = pci_read_config8(dev, 0x4); printk_debug("command in reg 0x4 reads back as 0x%x\n", enables); pci_write_config32(dev, 0x10, 0x0); pci_write_config32(dev, 0x14, 0x0); pci_write_config32(dev, 0x18, 0x0); pci_write_config32(dev, 0x1c, 0x0); // Force interrupts to use compat mode - just like Award bios pci_write_config8(dev, 0x3d, 0x0); pci_write_config8(dev, 0x3c, 0xff); } static struct device_operations ide_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = ide_init, .enable = 0, .ops_pci = 0, }; static struct pci_driver northbridge_driver __pci_driver = { .ops = &ide_ops, .vendor = PCI_VENDOR_ID_VIA, .device = PCI_DEVICE_ID_VIA_82C586_1, };
/* * This file is part of the LinuxBIOS project. * * Based on other VIA SB code. * Copyright (C) 2007 Rudolf Marek <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <arch/io.h> #include <console/console.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> #include <device/pci_ids.h> #include <pc80/mc146818rtc.h> #include "vt8237r.h" #include "chip.h" #include <cpu/x86/lapic.h> static void pic_read_resources(device_t dev) { struct resource *res; /* Get the normal pci resources of this device */ //pci_dev_read_resources(dev); res = new_resource(dev, 0x44); res->base = 0xfec00000; res->size = 256; res->limit = res->base + res->size -1; res->align = 8; res->gran = 8; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; res = new_resource(dev, 0x45); res->base = 0xfecc0000; res->size = 256; res->limit = res->base + res->size -1; res->align = 8; res->gran = 8; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; // res = new_resource(dev, 0x46); // res->base = 0xe0000000; // res->size = 256*1024*1024; //MMIO space placeholder // res->limit = res->base + res->size -1; // res->align = 8; // res->gran = 8; // res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | // IORESOURCE_STORED | IORESOURCE_ASSIGNED; /* Add a MMCONFIG resource */ res = new_resource(dev, 0x46); res->size = 256*1024*1024; res->align = log2(res->size); res->gran = log2(res->size); res->limit = 0xffffffff; /* 4G */ res->flags = IORESOURCE_MEM; } struct ioapicreg { unsigned int reg; unsigned int value_low, value_high; }; extern void dump_south(device_t dev0); static struct ioapicreg ioapicregvalues[] = { #define ALL (0xff << 24) #define NONE (0) #define DISABLED (1 << 16) #define ENABLED (0 << 16) #define TRIGGER_EDGE (0 << 15) #define TRIGGER_LEVEL (1 << 15) #define POLARITY_HIGH (0 << 13) #define POLARITY_LOW (1 << 13) #define PHYSICAL_DEST (0 << 11) #define LOGICAL_DEST (1 << 11) #define ExtINT (7 << 8) #define NMI (4 << 8) #define SMI (2 << 8) #define INT (1 << 8) /* IO-APIC virtual wire mode configuration */ /* mask, trigger, polarity, destination, delivery, vector */ { 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE}, { 1, DISABLED, NONE}, { 2, DISABLED, NONE}, { 3, DISABLED, NONE}, { 4, DISABLED, NONE}, { 5, DISABLED, NONE}, { 6, DISABLED, NONE}, { 7, DISABLED, NONE}, { 8, DISABLED, NONE}, { 9, DISABLED, NONE}, { 10, DISABLED, NONE}, { 11, DISABLED, NONE}, { 12, DISABLED, NONE}, { 13, DISABLED, NONE}, { 14, DISABLED, NONE}, { 15, DISABLED, NONE}, { 16, DISABLED, NONE}, { 17, DISABLED, NONE}, { 18, DISABLED, NONE}, { 19, DISABLED, NONE}, { 20, DISABLED, NONE}, { 21, DISABLED, NONE}, { 22, DISABLED, NONE}, { 23, DISABLED, NONE}, /* Be careful and don't write past the end... */ }; static void setup_ioapic(unsigned long ioapic_base) { int i; unsigned long value_low, value_high, adr; // unsigned long ioapic_base = 0xfec00000; volatile unsigned long *l; struct ioapicreg *a = ioapicregvalues; //delivered to CPU0 ioapicregvalues[0].value_high = (lapicid())<<(56-32); l = (unsigned long *) ioapic_base; l[0] = 3; //set APIC to FSB message adr = l[4]; l[4] = (adr & 0xFFFFFE) | 1; l[0] = 0; //set APIC ADDR adr = l[4]; l[4] = (adr & 0xF0FFFF) | (2<<24); for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]); i++, a++) { l[0] = (a->reg * 2) + 0x10; l[4] = a->value_low; value_low = l[4]; l[0] = (a->reg *2) + 0x11; l[4] = a->value_high; value_high = l[4]; if ((i==0) && (value_low == 0xffffffff)) { printk_warning("IO APIC not responding.\n"); return; } printk_debug("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n", a->reg, a->value_low, a->value_high); } ioapic_base = 0xfecc0000; l = (unsigned long *) ioapic_base; l[0] = 3; //set APIC to FSB message adr = l[4]; l[4] = (adr & 0xFFFFFE) | 1; // FIXME this belongs to other FILE! l[0] = 0; //set APIC ADDR of the NB APIC adr = l[4]; l[4] = (adr & 0xF0FFFF) | (3<<24); } static void pci_routing_fixup(struct device *dev) { /* set up PCI IRQ routing, route everything through APIC */ pci_write_config8(dev, 0x44, 0x00); /* PCI PNP Interrupt Routing INTE/F - disable */ pci_write_config8(dev, 0x45, 0x00); /* PCI PNP Interrupt Routing INTG/H - disable */ pci_write_config8(dev, 0x46, 0x10); /* Route INTE-INTH through registers above, no map to INTA-INTD */ pci_write_config8(dev, 0x54, 0x00); /* PCI Interrupt Polarity */ pci_write_config8(dev, 0x55, 0x00); /* PCI INTA# Routing */ pci_write_config8(dev, 0x56, 0x00); /* PCI INTB#/C# Routing */ pci_write_config8(dev, 0x57, 0x00); /* PCI INTD# Routing */ } /* * Set up the power management capabilities directly into ACPI mode. This * avoids having to handle any System Management Interrupts (SMI's) which I * can't figure out how to do !!!! */ void setup_pm(device_t dev) { // Set gen config 0 pci_write_config8(dev, 0x80, 0x20); // Set ACPI base address to IO 0x500 pci_write_config16(dev, 0x88, 0x501); // set ACPI irq to 9, need to FIXME set it to LEVEL! pci_write_config8(dev, 0x82, 0x49); // primary interupt channel pci_write_config16(dev, 0x84, 0x30b2); // throttle / stop clock control pci_write_config8(dev, 0x8d, 0x18); pci_write_config8(dev, 0x93, 0x88); pci_write_config8(dev, 0x94, 0xa4); pci_write_config8(dev, 0x95, 0xcc); pci_write_config8(dev, 0x98, 0); pci_write_config8(dev, 0x99, 0x1e); //?? /* enable SATA LED, disable CPU Frequency Change */ pci_write_config8(dev, 0xe5, 0x9); /* REQ5 as PCI request input - should be together with INTE-INTH*/ pci_write_config8(dev, 0xe4, 0x4); // Enable ACPI access (and setup like award) pci_write_config8(dev, 0x81, 0x84); outw(0xffff, 0x500); outw(0xffff, 0x520); outw(0xffff, 0x528); outl(0xffffffff, 0x530); outw(0x0, 0x524); outw(0x0, 0x52a); outw(0x0, 0x52c); outl(0x0, 0x534); outl(0x0, 0x538); //fix outb(0x0, 0x542); outw(0x000, 0x504); //fix } static void vt8237r_init(struct device *dev) { unsigned char enables, byte; printk_debug("vt8237r init\n"); byte = pci_read_config8(dev, PCI_COMMAND); byte |= PCI_COMMAND_WAIT; pci_write_config8(dev, PCI_COMMAND, byte); // enable the internal I/O decode enables = pci_read_config8(dev, 0x6C); enables |= 0x80; pci_write_config8(dev, 0x6C, enables); //FIXME Map 4MB of FLASH into the address space pci_write_config8(dev, 0x41, 0x0); // Set bit 6 of 0x40, because Award does it (IO recovery time) // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI // interrupts can be properly marked as level triggered. enables = pci_read_config8(dev, 0x40); enables |= 0x44; pci_write_config8(dev, 0x40, enables); // Set 0x42 to 0xf8 to match Award bios enables = pci_read_config8(dev, 0x42); enables |= 0xf8; pci_write_config8(dev, 0x42, enables); /* Delay Transaction Control */ pci_write_config8(dev, 0x43, 0xb); /* IO Recovery time */ pci_write_config8(dev, 0x4c, 0x44); /* ROM Memory Cycles Go To LPC */ pci_write_config8(dev, 0x59, 0x80); /* bypass Bypass APIC De-Assert Message, INTE#, INTF#, INTG#, INTH# as PCI */ pci_write_config8(dev, 0x5B, 0xb); /* set Read Pass Write Control Enable (force A2 from APIC FSB to low)*/ pci_write_config8(dev, 0x48, 0x8c); /* Set 0x58 to 0x43 APIC and RTC*/ pci_write_config8(dev, 0x58, 0x43); /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */ enables = pci_read_config8(dev, 0x4f); enables |= 0x08; pci_write_config8(dev, 0x4f, enables); /* enable serial irq */ pci_write_config8(dev, 0x52, 0x9); /* dma */ //pci_write_config8(dev, 0x53, 0x00); // Power management setup setup_pm(dev); // Start the rtc rtc_init(0); } void vt8237r_read_resources(device_t dev) { pci_dev_read_resources(dev); pic_read_resources(dev); } void vt8237r_set_resources(device_t dev) { struct resource *resource, *last; last = &dev->resource[dev->resources]; resource = find_resource(dev, 0x46); if (resource) { report_resource_stored(dev, resource, "<mmconfig>"); /* Remember this resource has been stored */ resource->flags |= IORESOURCE_STORED; /* FIXME */ } //resource = find_resource(dev,1); //resource->flags |= IORESOURCE_STORED; pci_dev_set_resources(dev); } void vt8237r_enable_resources(device_t dev) { /* vt8237r is not a pci bridge and has no resources of its own (other than standard PC i/o addresses) however it does control the isa bus and so we need to manually call enable childrens resources on that bus */ pci_dev_enable_resources(dev); enable_childrens_resources(dev); } static void keyboard_on(struct device *dev) { unsigned char regval; regval = pci_read_config8(dev, 0x51); regval |= 0x05; regval &= 0xfd; pci_write_config8(dev, 0x51, regval); init_pc_keyboard(0x60, 0x64, 0); } static void southbridge_init(struct device *dev) { unsigned int v; vt8237r_init(dev); pci_routing_fixup(dev); setup_ioapic(0xfec00000); setup_i8259(); keyboard_on(dev); //dump_south(dev); } static struct device_operations vt8237r_lpc_ops = { .read_resources = vt8237r_read_resources, .set_resources = vt8237r_set_resources, .enable_resources = vt8237r_enable_resources, .init = &southbridge_init, .scan_bus = scan_static_bus, }; static struct pci_driver lpc_driver __pci_driver = { .ops = &vt8237r_lpc_ops, .vendor = PCI_VENDOR_ID_VIA, .device = 0x3227, };
/* * This file is part of the LinuxBIOS project. * * Copyright (C) 2007 Rudolf Marek <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <console/console.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> #include <device/pci_ids.h> #include "vt8237r.h" static void sata_init(struct device *dev) { uint8_t reg; printk_debug("Configuring VIA SATA Controller\n"); /* class IDE Disk */ reg = pci_read_config8(dev, 0x45); reg &= 0x7f; /* Sub Class Write Protect off */ pci_write_config8(dev, 0x45, reg); pci_write_config8(dev, 0xa, 0x1); reg |= 0x80; /* Sub Class Write Protect on */ pci_write_config8(dev, 0x45, reg); } static struct device_operations sata_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = sata_init, .enable = 0, .ops_pci = 0, }; static struct pci_driver northbridge_driver __pci_driver = { .ops = &sata_ops, .vendor = PCI_VENDOR_ID_VIA, .device = 0x3149, };
-- linuxbios mailing list linuxbios@linuxbios.org http://www.linuxbios.org/mailman/listinfo/linuxbios