sync with openbsd; fixes observed corruption issues.

This commit is contained in:
christos 2008-04-17 19:12:26 +00:00
parent 60fafd3b9b
commit f0b645b98a
4 changed files with 114 additions and 68 deletions

View File

@ -1,8 +1,8 @@
/* $NetBSD: if_nfe.c,v 1.30 2008/03/26 14:46:21 cube Exp $ */
/* $OpenBSD: if_nfe.c,v 1.52 2006/03/02 09:04:00 jsg Exp $ */
/* $NetBSD: if_nfe.c,v 1.31 2008/04/17 19:12:26 christos Exp $ */
/* $OpenBSD: if_nfe.c,v 1.77 2008/02/05 16:52:50 brad Exp $ */
/*-
* Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2006, 2007 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2005, 2006 Jonathan Gray <jsg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@ -21,7 +21,7 @@
/* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.30 2008/03/26 14:46:21 cube Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.31 2008/04/17 19:12:26 christos Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@ -34,9 +34,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.30 2008/03/26 14:46:21 cube Exp $");
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/callout.h>
#include <sys/socket.h>
#include <sys/bus.h>
@ -112,8 +112,6 @@ void nfe_tick(void *);
CFATTACH_DECL_NEW(nfe, sizeof(struct nfe_softc), nfe_match, nfe_attach,
NULL, NULL);
/*#define NFE_NO_JUMBO*/
#ifdef NFE_DEBUG
int nfedebug = 0;
#define DPRINTF(x) do { if (nfedebug) printf x; } while (0)
@ -181,6 +179,14 @@ const struct nfe_product {
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN2 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN3 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN4 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN1 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN2 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN3 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN4 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN1 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN2 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN3 },
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN4 }
};
int
@ -214,8 +220,7 @@ nfe_attach(device_t parent, device_t self, void *aux)
sc->sc_dev = self;
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
aprint_normal(": %s (rev. 0x%02x)\n",
devinfo, PCI_REVISION(pa->pa_class));
aprint_normal(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA);
switch (memtype) {
@ -248,14 +253,6 @@ nfe_attach(device_t parent, device_t self, void *aux)
sc->sc_dmat = pa->pa_dmat;
/* Check for reversed ethernet address */
if ((NFE_READ(sc, NFE_TX_UNK) & NFE_MAC_ADDR_INORDER) != 0)
sc->sc_flags |= NFE_CORRECT_MACADDR;
nfe_get_macaddr(sc, sc->sc_enaddr);
aprint_normal_dev(self, "Ethernet address %s\n",
ether_sprintf(sc->sc_enaddr));
sc->sc_flags = 0;
switch (PCI_PRODUCT(pa->pa_id)) {
@ -267,6 +264,8 @@ nfe_attach(device_t parent, device_t self, void *aux)
break;
case PCI_PRODUCT_NVIDIA_MCP51_LAN1:
case PCI_PRODUCT_NVIDIA_MCP51_LAN2:
sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT;
break;
case PCI_PRODUCT_NVIDIA_MCP61_LAN1:
case PCI_PRODUCT_NVIDIA_MCP61_LAN2:
case PCI_PRODUCT_NVIDIA_MCP61_LAN3:
@ -279,7 +278,19 @@ nfe_attach(device_t parent, device_t self, void *aux)
case PCI_PRODUCT_NVIDIA_MCP73_LAN2:
case PCI_PRODUCT_NVIDIA_MCP73_LAN3:
case PCI_PRODUCT_NVIDIA_MCP73_LAN4:
sc->sc_flags |= NFE_40BIT_ADDR |NFE_PWR_MGMT;
sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR |
NFE_PWR_MGMT;
break;
case PCI_PRODUCT_NVIDIA_MCP77_LAN1:
case PCI_PRODUCT_NVIDIA_MCP77_LAN2:
case PCI_PRODUCT_NVIDIA_MCP77_LAN3:
case PCI_PRODUCT_NVIDIA_MCP77_LAN4:
case PCI_PRODUCT_NVIDIA_MCP79_LAN1:
case PCI_PRODUCT_NVIDIA_MCP79_LAN2:
case PCI_PRODUCT_NVIDIA_MCP79_LAN3:
case PCI_PRODUCT_NVIDIA_MCP79_LAN4:
sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM |
NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
break;
case PCI_PRODUCT_NVIDIA_CK804_LAN1:
case PCI_PRODUCT_NVIDIA_CK804_LAN2:
@ -287,19 +298,21 @@ nfe_attach(device_t parent, device_t self, void *aux)
case PCI_PRODUCT_NVIDIA_MCP04_LAN2:
sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM;
break;
case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
case PCI_PRODUCT_NVIDIA_MCP65_LAN1:
case PCI_PRODUCT_NVIDIA_MCP65_LAN2:
case PCI_PRODUCT_NVIDIA_MCP65_LAN3:
case PCI_PRODUCT_NVIDIA_MCP65_LAN4:
sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR |
NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
break;
case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
NFE_HW_VLAN | NFE_PWR_MGMT;
break;
}
if ((sc->sc_flags & NFE_PWR_MGMT) != 0) {
/* wakeup some newer chips from powerdown mode */
NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2);
NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC);
DELAY(100);
@ -310,12 +323,20 @@ nfe_attach(device_t parent, device_t self, void *aux)
NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK);
}
#ifndef NFE_NO_JUMBO
#ifdef notyet
/* enable jumbo frames for adapters that support it */
if (sc->sc_flags & NFE_JUMBO_SUP)
sc->sc_flags |= NFE_USE_JUMBO;
#endif
/* Check for reversed ethernet address */
if ((NFE_READ(sc, NFE_TX_UNK) & NFE_MAC_ADDR_INORDER) != 0)
sc->sc_flags |= NFE_CORRECT_MACADDR;
nfe_get_macaddr(sc, sc->sc_enaddr);
aprint_normal_dev(self, "Ethernet address %s\n",
ether_sprintf(sc->sc_enaddr));
/*
* Allocate Tx and Rx rings.
*/
@ -344,6 +365,11 @@ nfe_attach(device_t parent, device_t self, void *aux)
IFQ_SET_READY(&ifp->if_snd);
strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
#ifdef notyet
if (sc->sc_flags & NFE_USE_JUMBO)
ifp->if_hardmtu = NFE_JUMBO_MTU;
#endif
#if NVLAN > 0
if (sc->sc_flags & NFE_HW_VLAN)
sc->sc_ethercom.ec_capabilities |=
@ -524,18 +550,14 @@ nfe_intr(void *arg)
handled = 1;
DPRINTFN(5, ("nfe_intr: interrupt register %x\n", r));
if ((r & (NFE_IRQ_RXERR | NFE_IRQ_RX_NOBUF | NFE_IRQ_RX))
!= 0) {
if ((r & (NFE_IRQ_RXERR|NFE_IRQ_RX_NOBUF|NFE_IRQ_RX)) != 0) {
/* check Rx ring */
nfe_rxeof(sc);
}
if ((r & (NFE_IRQ_TXERR | NFE_IRQ_TXERR2 | NFE_IRQ_TX_DONE))
!= 0) {
if ((r & (NFE_IRQ_TXERR|NFE_IRQ_TXERR2|NFE_IRQ_TX_DONE)) != 0) {
/* check Tx ring */
nfe_txeof(sc);
}
if ((r & NFE_IRQ_LINK) != 0) {
NFE_READ(sc, NFE_PHY_STATUS);
NFE_WRITE(sc, NFE_PHY_STATUS, 0xf);
@ -595,9 +617,9 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd, void *data)
*/
if ((ifp->if_flags & IFF_RUNNING) &&
((ifp->if_flags ^ sc->sc_if_flags) &
(IFF_ALLMULTI | IFF_PROMISC)) != 0)
(IFF_ALLMULTI | IFF_PROMISC)) != 0) {
nfe_setmulti(sc);
else
} else
nfe_init(ifp);
} else {
if (ifp->if_flags & IFF_RUNNING)
@ -608,7 +630,7 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd, void *data)
default:
if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
break;
error = 0;
if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
@ -786,13 +808,12 @@ nfe_rxeof(struct nfe_softc *sc)
goto skip1;
}
memcpy(mtod(mnew, void *),
(void)memcpy(mtod(mnew, void *),
mtod(data->m, const void *), len);
m = mnew;
goto mbufcopied;
} else {
MEXTADD(mnew, jbuf->buf, NFE_JBYTES, 0, nfe_jfree, sc);
bus_dmamap_sync(sc->sc_dmat, sc->rxq.jmap,
mtod(data->m, char *) - (char *)sc->rxq.jpool,
NFE_JBYTES, BUS_DMASYNC_POSTREAD);
@ -869,7 +890,6 @@ mbufcopied:
device_xname(sc->sc_dev)));
}
}
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
@ -888,7 +908,7 @@ skip1:
desc32->physaddr = htole32(physaddr);
}
skip:
skip:
if (sc->sc_flags & NFE_40BIT_ADDR) {
desc64->length = htole16(sc->rxq.bufsz);
desc64->flags = htole16(NFE_RX_READY);
@ -916,6 +936,7 @@ nfe_txeof(struct nfe_softc *sc)
struct nfe_tx_data *data = NULL;
int i;
uint16_t flags;
char buf[128];
for (i = sc->txq.next;
sc->txq.queued > 0;
@ -946,7 +967,10 @@ nfe_txeof(struct nfe_softc *sc)
if ((flags & NFE_TX_ERROR_V1) != 0) {
aprint_error_dev(sc->sc_dev,
"tx v1 error 0x%04x\n", flags);
"tx v1 error %s\n",
sc->sc_dev.dv_xname,
bitmask_snprintf(flags, NFE_V1_TXERR,
buf, sizeof(buf)));
ifp->if_oerrors++;
} else
ifp->if_opackets++;
@ -956,8 +980,10 @@ nfe_txeof(struct nfe_softc *sc)
continue;
if ((flags & NFE_TX_ERROR_V2) != 0) {
aprint_error_dev(sc->sc_dev,
"tx v2 error 0x%04x\n", flags);
aprint_error_dev("tx v2 error %s\n",
sc->sc_dev,
bitmask_snprintf(flags, NFE_V2_TXERR,
buf, sizeof(buf)));
ifp->if_oerrors++;
} else
ifp->if_opackets++;
@ -1115,7 +1141,7 @@ nfe_start(struct ifnet *ifp)
int old = sc->txq.queued;
struct mbuf *m0;
if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
for (;;) {
@ -1256,7 +1282,7 @@ nfe_init(struct ifnet *ifp)
NFE_WRITE(sc, NFE_STATUS, sc->mii_phyaddr << 24 | NFE_STATUS_MAGIC);
NFE_WRITE(sc, NFE_SETUP_R4, NFE_R4_MAGIC);
NFE_WRITE(sc, NFE_WOL_CTL, NFE_WOL_MAGIC);
NFE_WRITE(sc, NFE_WOL_CTL, NFE_WOL_ENABLE);
sc->rxtxctl &= ~NFE_RXTX_BIT2;
NFE_WRITE(sc, NFE_RXTX_CTL, sc->rxtxctl);
@ -1555,8 +1581,8 @@ nfe_jfree(struct mbuf *m, void *buf, size_t size, void *arg)
/* ..and put it back in the free list */
SLIST_INSERT_HEAD(&sc->rxq.jfreelist, jbuf, jnext);
if (m != NULL)
pool_cache_put(mb_cache, m);
if (m != NULL)
pool_cache_put(mb_cache, m);
}
int
@ -1845,7 +1871,18 @@ nfe_get_macaddr(struct nfe_softc *sc, uint8_t *addr)
{
uint32_t tmp;
if ((sc->sc_flags & NFE_CORRECT_MACADDR) == 0) {
if ((sc->sc_flags & NFE_CORRECT_MACADDR) != 0) {
tmp = NFE_READ(sc, NFE_MACADDR_HI);
addr[0] = (tmp & 0xff);
addr[1] = (tmp >> 8) & 0xff;
addr[2] = (tmp >> 16) & 0xff;
addr[3] = (tmp >> 24) & 0xff;
tmp = NFE_READ(sc, NFE_MACADDR_LO);
addr[4] = (tmp & 0xff);
addr[5] = (tmp >> 8) & 0xff;
} else {
tmp = NFE_READ(sc, NFE_MACADDR_LO);
addr[0] = (tmp >> 8) & 0xff;
addr[1] = (tmp & 0xff);
@ -1855,16 +1892,6 @@ nfe_get_macaddr(struct nfe_softc *sc, uint8_t *addr)
addr[3] = (tmp >> 16) & 0xff;
addr[4] = (tmp >> 8) & 0xff;
addr[5] = (tmp & 0xff);
} else {
tmp = NFE_READ(sc, NFE_MACADDR_LO);
addr[5] = (tmp >> 8) & 0xff;
addr[4] = (tmp & 0xff);
tmp = NFE_READ(sc, NFE_MACADDR_HI);
addr[3] = (tmp >> 24) & 0xff;
addr[2] = (tmp >> 16) & 0xff;
addr[1] = (tmp >> 8) & 0xff;
addr[0] = (tmp & 0xff);
}
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: if_nfereg.h,v 1.6 2008/01/26 14:13:06 tsutsui Exp $ */
/* $OpenBSD: if_nfereg.h,v 1.16 2006/02/22 19:23:44 damien Exp $ */
/* $NetBSD: if_nfereg.h,v 1.7 2008/04/17 19:12:26 christos Exp $ */
/* $OpenBSD: if_nfereg.h,v 1.22 2007/12/05 08:30:33 jsg Exp $ */
/*-
* Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org>
@ -20,13 +20,17 @@
#define NFE_PCI_BA 0x10
#define NFE_RX_RING_COUNT 128
#define NFE_TX_RING_COUNT 64
#define NFE_TX_RING_COUNT 256
#define NFE_RX_NEXTDESC(x) (((x) + 1) & (NFE_RX_RING_COUNT - 1))
#define NFE_TX_NEXTDESC(x) (((x) + 1) & (NFE_TX_RING_COUNT - 1))
#define ETHER_ALIGN 2
#define NFE_JBYTES (ETHER_MAX_LEN_JUMBO + ETHER_ALIGN)
#define NFE_JUMBO_FRAMELEN 9018
#define NFE_JUMBO_MTU (NFE_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
#define NFE_JBYTES (NFE_JUMBO_FRAMELEN + ETHER_ALIGN)
#define NFE_JPOOL_COUNT (NFE_RX_RING_COUNT + 64)
#define NFE_JPOOL_SIZE (NFE_JPOOL_COUNT * NFE_JBYTES)
@ -94,7 +98,7 @@
#define NFE_R2_MAGIC 0x16
#define NFE_R4_MAGIC 0x08
#define NFE_R6_MAGIC 0x03
#define NFE_WOL_MAGIC 0x1111
#define NFE_WOL_ENABLE 0x1111
#define NFE_RX_START 0x01
#define NFE_TX_START 0x01
@ -163,6 +167,10 @@ struct nfe_desc32 {
#define NFE_TX_LASTFRAG_V1 (1 << 0)
} __packed;
#define NFE_V1_TXERR "\020" \
"\14TXERROR\13UNDERFLOW\12LATECOLLISION\11LOSTCARRIER\10DEFERRED" \
"\08FORCEDINT\03RETRY\00LASTPACKET"
/* V2 Rx/Tx descriptor */
struct nfe_desc64 {
volatile uint32_t physaddr[2];
@ -173,18 +181,21 @@ struct nfe_desc64 {
volatile uint16_t flags;
#define NFE_RX_FIXME_V2 0x4300
#define NFE_RX_VALID_V2 (1 << 13)
#define NFE_RX_IP_CSUMOK (1 << 12)
#define NFE_RX_UDP_CSUMOK (1 << 11)
#define NFE_RX_TCP_CSUMOK (1 << 10)
#define NFE_TX_ERROR_V2 0x5c04
#define NFE_TX_LASTFRAG_V2 (1 << 13)
#define NFE_TX_IP_CSUM (1 << 11)
#define NFE_TX_TCP_UDP_CSUM (1 << 10)
} __packed;
#define NFE_V2_TXERR "\020" \
"\14FORCEDINT\13LASTPACKET\12UNDERFLOW\10LOSTCARRIER\09DEFERRED\02RETRY"
/* flags common to V1/V2 descriptors */
#define NFE_RX_UDP_CSUMOK (1 << 10)
#define NFE_RX_TCP_CSUMOK (1 << 11)
#define NFE_RX_IP_CSUMOK (1 << 12)
#define NFE_RX_ERROR (1 << 14)
#define NFE_RX_READY (1 << 15)
#define NFE_TX_TCP_UDP_CSUM (1 << 10)
#define NFE_TX_IP_CSUM (1 << 11)
#define NFE_TX_VALID (1 << 15)
#define NFE_READ(sc, reg) \

View File

@ -1,5 +1,5 @@
/* $NetBSD: if_nfevar.h,v 1.7 2008/03/26 14:46:21 cube Exp $ */
/* $OpenBSD: if_nfevar.h,v 1.11 2006/02/19 13:57:02 damien Exp $ */
/* $NetBSD: if_nfevar.h,v 1.8 2008/04/17 19:12:26 christos Exp $ */
/* $OpenBSD: if_nfevar.h,v 1.13 2007/12/05 08:30:33 jsg Exp $ */
/*-
* Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org>
@ -38,7 +38,7 @@ struct nfe_tx_ring {
};
struct nfe_jbuf {
void * buf;
void *buf;
bus_addr_t physaddr;
SLIST_ENTRY(nfe_jbuf) jnext;
};
@ -56,7 +56,7 @@ struct nfe_rx_ring {
bus_addr_t physaddr;
struct nfe_desc32 *desc32;
struct nfe_desc64 *desc64;
void * jpool;
void *jpool;
struct nfe_rx_data data[NFE_RX_RING_COUNT];
struct nfe_jbuf jbuf[NFE_JPOOL_COUNT];
int jbufmap[NFE_RX_RING_COUNT];

View File

@ -1,4 +1,4 @@
$NetBSD: pcidevs,v 1.936 2008/04/15 21:24:07 cegger Exp $
$NetBSD: pcidevs,v 1.937 2008/04/17 19:12:26 christos Exp $
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou
@ -3167,6 +3167,10 @@ product NVIDIA MCP67_HDA_2 0x055d nForce MCP67 High Definition Audio Controller
product NVIDIA MCP67_IDE 0x0560 nForce MCP67 ATA133 IDE Controller
product NVIDIA MCP73_IDE 0x056c nForce MCP73 ATA133 IDE Controller
product NVIDIA MCP77_IDE 0x0759 nForce MCP77 ATA133 IDE Controller
product NVIDIA MCP77_LAN1 0x0760 nForce MCP77 Gigabit Ethernet Controller
product NVIDIA MCP77_LAN2 0x0761 nForce MCP77 Gigabit Ethernet Controller
product NVIDIA MCP77_LAN3 0x0762 nForce MCP77 Gigabit Ethernet Controller
product NVIDIA MCP77_LAN4 0x0763 nForce MCP77 Gigabit Ethernet Controller
product NVIDIA MCP77_HDA_1 0x0774 nForce MCP77 High Definition Audio Controller
product NVIDIA MCP77_HDA_2 0x0775 nForce MCP77 High Definition Audio Controller
product NVIDIA MCP77_HDA_3 0x0776 nForce MCP77 High Definition Audio Controller
@ -3190,6 +3194,10 @@ product NVIDIA MCP73_AHCI_11 0x07fa nForce MCP73 AHCI Controller
product NVIDIA MCP73_AHCI_12 0x07fb nForce MCP73 AHCI Controller
product NVIDIA MCP73_HDA_1 0x07fc nForce MCP73 High Definition Audio Controller
product NVIDIA MCP73_HDA_2 0x07fd nForce MCP73 High Definition Audio Controller
product NVIDIA MCP79_LAN1 0x0ab0 nForce MCP79 Gigabit Ethernet Controller
product NVIDIA MCP79_LAN2 0x0ab1 nForce MCP79 Gigabit Ethernet Controller
product NVIDIA MCP79_LAN3 0x0ab2 nForce MCP79 Gigabit Ethernet Controller
product NVIDIA MCP79_LAN4 0x0ab3 nForce MCP79 Gigabit Ethernet Controller
product NVIDIA MCP77_AHCI_1 0x0ad0 nForce MCP77 AHCI Controller
product NVIDIA MCP77_AHCI_2 0x0ad1 nForce MCP77 AHCI Controller
product NVIDIA MCP77_AHCI_3 0x0ad2 nForce MCP77 AHCI Controller