Index: stable/3/release/sysinstall/devices.c =================================================================== --- stable/3/release/sysinstall/devices.c (revision 49544) +++ stable/3/release/sysinstall/devices.c (revision 49545) @@ -1,529 +1,531 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: devices.c,v 1.88.2.4 1999/06/19 21:38:02 wpaul Exp $ + * $Id: devices.c,v 1.88.2.5 1999/07/03 05:42:38 mharo Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /* how much to bias minor number for a given /dev/s slice */ #define SLICE_DELTA (0x10000) static Device *Devices[DEV_MAX]; static int numDevs; static struct _devname { DeviceType type; char *name; char *description; int major, minor, delta, max; char dev_type; } device_names[] = { { DEVICE_TYPE_CDROM, "cd%dc", "SCSI CDROM drive", 6, 2, 8, 4, 'b' }, { DEVICE_TYPE_CDROM, "mcd%da", "Mitsumi (old model) CDROM drive", 7, 0, 8, 4, 'b' }, { DEVICE_TYPE_CDROM, "scd%da", "Sony CDROM drive - CDU31/33A type", 16, 0, 8, 4, 'b' }, { DEVICE_TYPE_CDROM, "matcd%da", "Matsushita CDROM ('sound blaster' type)", 17, 0, 8, 4, 'b' }, { DEVICE_TYPE_CDROM, "acd%dc", "ATAPI IDE CDROM", 19, 2, 8, 4, 'b' }, { DEVICE_TYPE_TAPE, "rsa%d", "SCSI tape drive", 14, 0, 16, 4, 'c' }, { DEVICE_TYPE_TAPE, "rwt%d", "Wangtek tape drive", 10, 0, 1, 4, 'c' }, { DEVICE_TYPE_DISK, "da%d", "SCSI disk device", 4, 65538, 8, 16, 'b' }, { DEVICE_TYPE_DISK, "rda%d", "SCSI disk device", 13, 65538, 8, 16, 'c' }, { DEVICE_TYPE_DISK, "wd%d", "IDE/ESDI/MFM/ST506 disk device", 0, 65538, 8, 16, 'b' }, { DEVICE_TYPE_DISK, "rwd%d", "IDE/ESDI/MFM/ST506 disk device", 3, 65538, 8, 16, 'c' }, { DEVICE_TYPE_DISK, "fla%d", "DiskOnChip2000 Flash device", 28, 65538, 8, 16, 'b' }, { DEVICE_TYPE_DISK, "rfla%d", "DiskOnChip2000 Flash devicee", 101, 65538, 8, 16, 'c' }, { DEVICE_TYPE_DISK, "wfd%d", "ATAPI floppy device", 1, 65538, 8, 4, 'b' }, { DEVICE_TYPE_DISK, "rwfd%d", "ATAPI floppy device", 87, 65538, 8, 4, 'c' }, { DEVICE_TYPE_FLOPPY, "fd%d", "floppy drive unit A", 2, 0, 64, 4, 'b' }, { DEVICE_TYPE_FLOPPY, "wfd%d", "ATAPI floppy drive unit A", 1, 0, 8, 4, 'b' }, { DEVICE_TYPE_FLOPPY, "worm%d", "SCSI optical disk / CDR", 23, 0, 1, 4, 'b' }, { DEVICE_TYPE_NETWORK, "al", "ADMtek AL981 PCI ethernet card" }, { DEVICE_TYPE_NETWORK, "ax", "ASIX AX88140A PCI ethernet card" }, { DEVICE_TYPE_NETWORK, "fpa", "DEC DEFPA PCI FDDI card" }, { DEVICE_TYPE_NETWORK, "sr", "SDL T1/E1 sync serial PCI card" }, { DEVICE_TYPE_NETWORK, "cc3i", "SDL HSSI sync serial PCI card" }, { DEVICE_TYPE_NETWORK, "en", "Efficient Networks ATM PCI card" }, { DEVICE_TYPE_NETWORK, "de", "DEC DE435 PCI NIC or other DC21040-AA based card" }, { DEVICE_TYPE_NETWORK, "fxp", "Intel EtherExpress Pro/100B PCI Fast Ethernet card" }, { DEVICE_TYPE_NETWORK, "ed", "WD/SMC 80xx; Novell NE1000/2000; 3Com 3C503 card" }, { DEVICE_TYPE_NETWORK, "ep", "3Com 3C509 ethernet card" }, { DEVICE_TYPE_NETWORK, "el", "3Com 3C501 ethernet card" }, { DEVICE_TYPE_NETWORK, "ex", "Intel EtherExpress Pro/10 ethernet card" }, { DEVICE_TYPE_NETWORK, "fe", "Fujitsu MB86960A/MB86965A ethernet card" }, { DEVICE_TYPE_NETWORK, "ie", "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210" }, { DEVICE_TYPE_NETWORK, "ix", "Intel Etherexpress ethernet card" }, { DEVICE_TYPE_NETWORK, "le", "DEC EtherWorks 2 or 3 ethernet card" }, { DEVICE_TYPE_NETWORK, "lnc", "Lance/PCnet (Isolan/Novell NE2100/NE32-VL) ethernet" }, - { DEVICE_TYPE_NETWORK, "mx", "Macronix 98713/98715/98725 PCI ethernet card" }, - { DEVICE_TYPE_NETWORK, "pn", "Lite-On 82168/82169 PNIC PCI ethernet card" }, - { DEVICE_TYPE_NETWORK, "rl", "RealTek 8129/8139 PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "mx", "Macronix 98713/98715/98725 PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "pn", "Lite-On 82168/82169 PNIC PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "rl", "RealTek 8129/8139 PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "sf", "Adaptec AIC-6915 PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "sk", "SysKonnect PCI gigabit ethernet card" }, { DEVICE_TYPE_NETWORK, "tx", "SMC 9432TX ethernet card" }, - { DEVICE_TYPE_NETWORK, "ti", "Alteon Networks PCI gigabit ethernet card" }, + { DEVICE_TYPE_NETWORK, "ti", "Alteon Networks PCI gigabit ethernet card" }, { DEVICE_TYPE_NETWORK, "tl", "Texas Instruments ThunderLAN PCI ethernet card" }, - { DEVICE_TYPE_NETWORK, "vr", "VIA VT3043/VT86C100A Rhine PCI ethernet card" }, + { DEVICE_TYPE_NETWORK, "vr", "VIA VT3043/VT86C100A Rhine PCI ethernet card" }, { DEVICE_TYPE_NETWORK, "vx", "3COM 3c590 / 3c595 ethernet card" }, { DEVICE_TYPE_NETWORK, "wb", "Winbond W89C840F PCI ethernet card" }, { DEVICE_TYPE_NETWORK, "xl", "3COM 3c90x / 3c90xB PCI ethernet card" }, { DEVICE_TYPE_NETWORK, "ze", "IBM/National Semiconductor PCMCIA ethernet card" }, { DEVICE_TYPE_NETWORK, "zp", "3Com Etherlink III PCMCIA ethernet card" }, { DEVICE_TYPE_NETWORK, "cuaa%d", "%s on device %s (COM%d)", 28, 128, 1, 16, 'c' }, { DEVICE_TYPE_NETWORK, "lp", "Parallel Port IP (PLIP) peer connection" }, { DEVICE_TYPE_NETWORK, "lo", "Loop-back (local) network interface" }, { 0 }, }; Device * new_device(char *name) { Device *dev; dev = safe_malloc(sizeof(Device)); bzero(dev, sizeof(Device)); if (name) SAFE_STRCPY(dev->name, name); return dev; } /* Stubs for unimplemented strategy routines */ Boolean dummyInit(Device *dev) { return TRUE; } FILE * dummyGet(Device *dev, char *dist, Boolean probe) { return NULL; } void dummyShutdown(Device *dev) { return; } static int deviceTry(struct _devname dev, char *try, int i) { int fd; char unit[80]; mode_t m; dev_t d; int fail; snprintf(unit, sizeof unit, dev.name, i); snprintf(try, FILENAME_MAX, "/dev/%s", unit); fd = open(try, O_RDONLY); if (fd >= 0) return fd; m = 0640; if (dev.dev_type == 'c') m |= S_IFCHR; else m |= S_IFBLK; d = makedev(dev.major, dev.minor + (i * dev.delta)); fail = mknod(try, m, d); fd = open(try, O_RDONLY); if (fd >= 0) return fd; else if (!fail) (void)unlink(try); /* Don't try a "make-under" here since we're using a fixit floppy in this case */ snprintf(try, FILENAME_MAX, "/mnt/dev/%s", unit); fd = open(try, O_RDONLY); return fd; } /* Register a new device in the devices array */ Device * deviceRegister(char *name, char *desc, char *devname, DeviceType type, Boolean enabled, Boolean (*init)(Device *), FILE * (*get)(Device *, char *, Boolean), void (*shutdown)(Device *), void *private) { Device *newdev = NULL; if (numDevs == DEV_MAX) msgFatal("Too many devices found!"); else { newdev = new_device(name); newdev->description = desc; newdev->devname = devname; newdev->type = type; newdev->enabled = enabled; newdev->init = init ? init : dummyInit; newdev->get = get ? get : dummyGet; newdev->shutdown = shutdown ? shutdown : dummyShutdown; newdev->private = private; Devices[numDevs] = newdev; Devices[++numDevs] = NULL; } return newdev; } /* Reset the registered device chain */ void deviceReset(void) { int i; for (i = 0; i < numDevs; i++) { Devices[i]->shutdown(Devices[i]); /* XXX this potentially leaks Devices[i]->private if it's being * used to point to something dynamic, but you're not supposed * to call this routine at such times that some open instance * has its private ptr pointing somewhere anyway. XXX */ free(Devices[i]); } Devices[numDevs = 0] = NULL; } /* Get all device information for devices we have attached */ void deviceGetAll(void) { int i, j, fd, s; struct ifconf ifc; struct ifreq *ifptr, *end; int ifflags; char buffer[INTERFACE_MAX * sizeof(struct ifreq)]; char **names; msgNotify("Probing devices, please wait (this can take a while)..."); /* First go for the network interfaces. Stolen shamelessly from ifconfig! */ ifc.ifc_len = sizeof(buffer); ifc.ifc_buf = buffer; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) goto skipif; /* Jump over network iface probing */ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) goto skipif; /* Jump over network iface probing */ ifflags = ifc.ifc_req->ifr_flags; end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifptr = ifc.ifc_req; ifptr < end; ifptr++) { char *descr; /* If it's not a link entry, forget it */ if (ifptr->ifr_ifru.ifru_addr.sa_family != AF_LINK) continue; /* Eliminate network devices that don't make sense */ if (!strncmp(ifptr->ifr_name, "lo", 2)) continue; /* If we have a slip device, don't register it */ if (!strncmp(ifptr->ifr_name, "sl", 2)) { continue; } /* And the same for ppp */ if (!strncmp(ifptr->ifr_name, "tun", 3) || !strncmp(ifptr->ifr_name, "ppp", 3)) { continue; } /* Try and find its description */ for (i = 0, descr = NULL; device_names[i].name; i++) { int len = strlen(device_names[i].name); if (!ifptr->ifr_name || !ifptr->ifr_name[0]) continue; else if (!strncmp(ifptr->ifr_name, device_names[i].name, len)) { descr = device_names[i].description; break; } } if (!descr) descr = ""; deviceRegister(ifptr->ifr_name, descr, strdup(ifptr->ifr_name), DEVICE_TYPE_NETWORK, TRUE, mediaInitNetwork, NULL, mediaShutdownNetwork, NULL); msgDebug("Found a network device named %s\n", ifptr->ifr_name); close(s); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) continue; if (ifptr->ifr_addr.sa_len) /* I'm not sure why this is here - it's inherited */ ifptr = (struct ifreq *)((caddr_t)ifptr + ifptr->ifr_addr.sa_len - sizeof(struct sockaddr)); } skipif: /* Next, try to find all the types of devices one might need * during the second stage of the installation. */ for (i = 0; device_names[i].name; i++) { for (j = 0; j < device_names[i].max; j++) { char try[FILENAME_MAX]; switch(device_names[i].type) { case DEVICE_TYPE_CDROM: fd = deviceTry(device_names[i], try, j); if (fd >= 0 || errno == EBUSY) { /* EBUSY if already mounted */ char n[BUFSIZ]; if (fd >= 0) close(fd); snprintf(n, sizeof n, device_names[i].name, j); deviceRegister(strdup(n), device_names[i].description, strdup(try), DEVICE_TYPE_CDROM, TRUE, mediaInitCDROM, mediaGetCDROM, mediaShutdownCDROM, NULL); msgDebug("Found a CDROM device for %s\n", try); } break; case DEVICE_TYPE_TAPE: fd = deviceTry(device_names[i], try, j); if (fd >= 0) { char n[BUFSIZ]; close(fd); snprintf(n, sizeof n, device_names[i].name, j); deviceRegister(strdup(n), device_names[i].description, strdup(try), DEVICE_TYPE_TAPE, TRUE, mediaInitTape, mediaGetTape, mediaShutdownTape, NULL); msgDebug("Found a TAPE device for %s\n", try); } break; case DEVICE_TYPE_DISK: fd = deviceTry(device_names[i], try, j); if (fd >= 0 && RunningAsInit) { dev_t d; mode_t m; int s, fail; char unit[80], slice[80]; close(fd); /* Make associated slice entries */ for (s = 1; s < 8; s++) { snprintf(unit, sizeof unit, device_names[i].name, j); snprintf(slice, sizeof slice, "/dev/%ss%d", unit, s); d = makedev(device_names[i].major, device_names[i].minor + (j * device_names[i].delta) + (s * SLICE_DELTA)); m = 0640; if (device_names[i].dev_type == 'c') m |= S_IFCHR; else m |= S_IFBLK; fail = mknod(slice, m, d); fd = open(slice, O_RDONLY); if (fd >= 0) close(fd); else if (!fail) (void)unlink(slice); } } break; case DEVICE_TYPE_FLOPPY: fd = deviceTry(device_names[i], try, j); if (fd >= 0) { char n[BUFSIZ]; close(fd); snprintf(n, sizeof n, device_names[i].name, j); deviceRegister(strdup(n), device_names[i].description, strdup(try), DEVICE_TYPE_FLOPPY, TRUE, mediaInitFloppy, mediaGetFloppy, mediaShutdownFloppy, NULL); msgDebug("Found a floppy device for %s\n", try); } break; case DEVICE_TYPE_NETWORK: fd = deviceTry(device_names[i], try, j); /* The only network devices that you can open this way are serial ones */ if (fd >= 0) { char *newdesc, *cp; close(fd); cp = device_names[i].description; /* Serial devices get a slip and ppp device each, if supported */ newdesc = safe_malloc(strlen(cp) + 40); sprintf(newdesc, cp, "SLIP interface", try, j + 1); deviceRegister("sl0", newdesc, strdup(try), DEVICE_TYPE_NETWORK, TRUE, mediaInitNetwork, NULL, mediaShutdownNetwork, NULL); msgDebug("Add mapping for %s to sl0\n", try); newdesc = safe_malloc(strlen(cp) + 50); sprintf(newdesc, cp, "PPP interface", try, j + 1); deviceRegister("ppp0", newdesc, strdup(try), DEVICE_TYPE_NETWORK, TRUE, mediaInitNetwork, NULL, mediaShutdownNetwork, NULL); msgDebug("Add mapping for %s to ppp0\n", try); } break; default: break; } } } /* Finally, go get the disks and look for DOS partitions to register */ if ((names = Disk_Names()) != NULL) { int i; for (i = 0; names[i]; i++) { Chunk *c1; Disk *d; d = Open_Disk(names[i]); if (!d) msgFatal("Unable to open disk %s", names[i]); deviceRegister(names[i], names[i], d->name, DEVICE_TYPE_DISK, FALSE, dummyInit, dummyGet, dummyShutdown, d); msgDebug("Found a disk device named %s\n", names[i]); /* Look for existing DOS partitions to register as "DOS media devices" */ for (c1 = d->chunks->part; c1; c1 = c1->next) { if (c1->type == fat || c1->type == extended) { Device *dev; char devname[80]; /* Got one! */ snprintf(devname, sizeof devname, "/dev/%s", c1->name); dev = deviceRegister(c1->name, c1->name, strdup(devname), DEVICE_TYPE_DOS, TRUE, mediaInitDOS, mediaGetDOS, mediaShutdownDOS, NULL); dev->private = c1; msgDebug("Found a DOS partition %s on drive %s\n", c1->name, d->name); } } } free(names); } } /* Rescan all devices, after closing previous set - convenience function */ void deviceRescan(void) { deviceReset(); deviceGetAll(); } /* * Find all devices that match the criteria, allowing "wildcarding" as well * by allowing NULL or ANY values to match all. The array returned is static * and may be used until the next invocation of deviceFind(). */ Device ** deviceFind(char *name, DeviceType class) { static Device *found[DEV_MAX]; int i, j; j = 0; for (i = 0; i < numDevs; i++) { if ((!name || !strcmp(Devices[i]->name, name)) && (class == DEVICE_TYPE_ANY || class == Devices[i]->type)) found[j++] = Devices[i]; } found[j] = NULL; return j ? found : NULL; } Device ** deviceFindDescr(char *name, char *desc, DeviceType class) { static Device *found[DEV_MAX]; int i, j; j = 0; for (i = 0; i < numDevs; i++) { if ((!name || !strcmp(Devices[i]->name, name)) && (!desc || !strcmp(Devices[i]->description, desc)) && (class == DEVICE_TYPE_ANY || class == Devices[i]->type)) found[j++] = Devices[i]; } found[j] = NULL; return j ? found : NULL; } int deviceCount(Device **devs) { int i; if (!devs) return 0; for (i = 0; devs[i]; i++); return i; } /* * Create a menu listing all the devices of a certain type in the system. * The passed-in menu is expected to be a "prototype" from which the new * menu is cloned. */ DMenu * deviceCreateMenu(DMenu *menu, DeviceType type, int (*hook)(dialogMenuItem *d), int (*check)(dialogMenuItem *d)) { Device **devs; int numdevs; DMenu *tmp = NULL; int i, j; devs = deviceFind(NULL, type); numdevs = deviceCount(devs); if (!numdevs) return NULL; tmp = (DMenu *)safe_malloc(sizeof(DMenu) + (sizeof(dialogMenuItem) * (numdevs + 1))); bcopy(menu, tmp, sizeof(DMenu)); for (i = 0; devs[i]; i++) { tmp->items[i].prompt = devs[i]->name; for (j = 0; j < numDevs; j++) { if (devs[i] == Devices[j]) { tmp->items[i].title = Devices[j]->description; break; } } if (j == numDevs) tmp->items[i].title = ""; tmp->items[i].fire = hook; tmp->items[i].checked = check; } tmp->items[i].title = NULL; return tmp; } Index: stable/3/release/texts/HARDWARE.TXT =================================================================== --- stable/3/release/texts/HARDWARE.TXT (revision 49544) +++ stable/3/release/texts/HARDWARE.TXT (revision 49545) @@ -1,593 +1,609 @@ Table of Contents ----------------- 0. Document Conventions 1. Default Configuration (GENERIC kernel) 2. Using UserConfig to change FreeBSD kernel settings 3. LINT - other possible configurations 4. Supported Hardware See TROUBLE.TXT for Q&A on known hardware problems. ========================================================================= 0. Document Conventions -- -------------------- We have `underlined' text which represents user input with `-' symbols throughout this document to differentiate it from the machine output. 1. Default (GENERIC) Configuration -- ------------------------------- The following table contains a list of all of the devices that are present in the GENERIC kernel. This is the essential part of the operating system that is placed in your root partition during the installation process. A compressed version of the GENERIC kernel is also used on the installation floppy diskette and DOS boot image. The table describes the various parameters used by the driver to communicate with the hardware in your system. There are four parameters in the table, though not all are used by each and every device: Port The starting I/O port used by the device, shown in hexadecimal. IOMem The lowest (or starting) memory address used by the device, also shown in hexadecimal. IRQ The interrupt the device uses to alert the driver to an event, given in decimal. DRQ The DMA (direct memory access) channel the device uses to move data to and from main memory, also given in decimal. If an entry in the table has `n/a' for a value then it means that the parameter in question does not apply to that device. A value of `dyn' means that the correct value should be determined automatically by the kernel when the system boots and that you don't need to worry about it. If an entry is marked with an *, it means that support is currently not available for it but should be back as soon as someone converts the driver to work within the new 3.0 framework. FreeBSD GENERIC kernel: Port IRQ DRQ IOMem Description ---- --- --- ----- --------------------------------- fdc0 3f0 6 2 n/a Floppy disk controller wdc0 1f0 14 n/a n/a IDE/MFM/RLL disk controller wdc1 170 15 n/a n/a IDE/MFM/RLL disk controller adv0 n/a n/a n/a n/a AdvanSys Narrow SCSI controllers adw0 n/a n/a n/a n/a AdvanSys Wide SCSI controllers ncr0 n/a n/a n/a n/a NCR PCI SCSI controller bt0 330 dyn dyn dyn Buslogic SCSI controller uha0* 330 dyn 6 dyn Ultrastore 14f aha0 330 dyn 5 dyn Adaptec 154x/1535 SCSI controller ahb0 dyn dyn dyn dyn Adaptec 174x SCSI controller ahc0 dyn dyn dyn dyn Adaptec 274x/284x/294x SCSI controller aic0* 340 11 dyn dyn Adaptec 152x/AIC-6360 SCSI controller isp0 dyn dyn dyn dyn QLogic 10X0, 2100 SCSI/FC controllers dpt n/a n/a n/a n/a DPT RAID SCSI controllers. wt0 300 5 1 dyn Wangtek and Archive QIC-02/QIC-36 psm0 60 12 n/a n/a PS/2 Mouse mcd0 300 10 n/a n/a Mitsumi CD-ROM matcd0 230 n/a n/a n/a Matsushita/Panasonic CD-ROM scd0 230 n/a n/a n/a Sony CD-ROM sio0 3f8 4 n/a n/a Serial Port 0 (COM1) sio1 2f8 3 n/a n/a Serial Port 1 (COM2) ppc0 dyn 7 n/a n/a Parallel Port Chipset al0 dyn dyn n/a dyn ADMtek AL981 PCI based cards ax0 dyn dyn n/a dyn ASIX AX88140A PCI based cards de0 n/a n/a n/a n/a DEC DC21x40 PCI based cards (including 21140 100bT cards) ed0 280 10 dyn d8000 WD & SMC 80xx; Novell NE1000 & NE2000; 3Com 3C503; HP PC Lan+ eg0 310 5 dyn dyn 3Com 3C505 ep0 300 10 dyn dyn 3Com 3C509 ex0 dyn dyn dyn n/a Intel EtherExpress Pro/10 cards fe0 300 dyn n/a n/a Allied-Telesis AT1700, RE2000 and Fujitsu FMV-180 series cards. fxp0 dyn dyn n/a dyn Intel EtherExpress Pro/100B ie0 300 10 dyn d0000 AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210; Intel EtherExpress (8/16,16[TP]) cards le0 300 5 dyn d0000 Digital Equipment EtherWorks 2 and EtherWorks 3 lnc0 280 10 n/a dyn Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL, some PCnet-PCI cards) mx0 dyn dyn n/a dyn Macronix 98713/15/25 PCI based cards pn0 dyn dyn n/a dyn Lite-On PNIC PCI based cards rl0 dyn dyn n/a dyn RealTek 8129/8139 fast ethernet +sf0 dyn dyn n/a dyn Adaptec AIC-6915 fast ethernet tl0 dyn dyn n/a dyn TI TNET100 'ThunderLAN' cards. wb0 dyn dyn n/a dyn Winbond W89C840F PCI based cards. vr0 dyn dyn n/a dyn VIA VT3043/VT86C100A PCI based cards. vx0 dyn dyn n/a dyn 3Com 3c59x ((Fast) Etherlink III) xl0 dyn dyn n/a dyn 3Com 3c900, 3c905 and 3c905B ((Fast) Etherlink XL) cs0 0x300 dyn n/a n/a Crystal Semiconductor CS89x0-based cards. ze0 300 5 n/a d8000 IBM/National Semiconductor PCMCIA Ethernet Controller zp0 300 10 n/a d8000 3Com 3c589 Etherlink III PCMCIA Ethernet Controller --- End of table --- If the hardware in your computer is not set to the same settings as those shown in the table and the item in conflict is not marked 'dyn', you will have to either reconfigure your hardware or use UserConfig to reconfigure the kernel to match the way your hardware is currently set (see the next section). If the settings do not match, the kernel may be unable to locate or reliably access the devices in your system. 2. Using UserConfig to change FreeBSD kernel settings -- -------------------------------------------------- The FreeBSD kernel on the install floppy contains drivers for every piece of hardware that could conceivably be used to install the rest of the system with. Unfortunately, PC hardware being what it is, some of these devices can be difficult to detect accurately, and for some, the process of detecting another can cause irreversible confusion. To make this process easier, FreeBSD provides UserConfig. With this UserConfig, the user can configure and disable device drivers before the kernel is loaded, avoiding potential conflicts, and eliminating the need to reconfigure hardware to suit the default driver settings. Once FreeBSD is installed, it will remember the changes made using UserConfig, so that they only need be made once. It is important to disable drivers that are not relevant to a system in order to minimize the possibility of interference, which can cause problems that are difficult to track down. UserConfig features a command line interface for users with serial consoles or a need to type commands, and a full screen 'visual' interface, which provides point-and-shoot configuration functionality. Here is a sample UserConfig screen shot in 'visual' mode: ---Active Drivers---------------------------10 Conflicts------Dev---IRQ--Port-- Storage : (Collapsed) Network : NE1000,NE2000,3C503,WD/SMC80xx Ethernet adapters CONF ed0 5 0x280 NE1000,NE2000,3C503,WD/SMC80xx Ethernet adapters CONF ed1 5 0x300 Communications : (Collapsed) Input : (Collapsed) Multimedia : ---Inactive Drivers-------------------------------------------Dev-------------- Storage : Network : (Collapsed) Communications : Input : Multimedia : PCI : ---Parameters-for-device-ed0--------------------------------------------------- Port address : 0x280 Memory address : 0xd8000 IRQ number : 5 Memory size : 0x2000 Flags : 0x0000 ------------------------------------------------------------------------------- IO Port address (Hexadecimal, 0x1-0x2000) [TAB] Change fields [Q] Save device parameters The screen is divided into four sections : - Active Drivers. Listed here are the device drivers that are currently enabled, and their basic parameters. - Inactive Drivers. These drivers are present, but are disabled. - Parameter edit field. This area is used for editing driver parameters. - Help area. Keystroke help is displayed here. One of the Active and Inactive lists is always in use, and the current entry in the list will be shown with a highlight bar. If there are more entries in a list than can be shown, it will scroll. The bar can be moved up and down using the cursor keys, and moved between lists with the TAB key. Drivers in the Active list may be marked "CONF". This indicates that one or more of their parameters conflicts with another device, and indicates a potential for problems. The total number of conflicts is displayed at the top of the screen. As a general rule, conflicts should be avoided, either by disabling conflicting devices that are not present in the system, or by altering their configuration so that they match the installed hardware. In the list areas, drivers are grouped by their basic function. Groups can be 'Collapsed' to simplify the display (this is the default state for all groups). If a group is collapsed, it will be shown with '(Collapsed)' in the list, as above. To Expand a Collapsed group, position the highlight bar over the group heading and press Enter. To Collapse it again, repeat the process. When a device driver in the Active list is highlighted, its full parameters are displayed in the Parameter edit area. Note that not all drivers use all possible parameters, and some hardware supported by drivers may not use all the parameters the driver supports. To disable a driver, go to the Active list, Expand the group it is in, highlight the driver and press Del. The driver will move to its group in the Inactive list. (If the group is collapsed or off the screen, you may not see the driver in its new location.) To enable a driver, go to the Inactive list, Expand the group it is in, highlight the driver and press Enter. The highlight will move to the Active list, and the driver you have just enabled will be highlighted, ready to be configured. To configure a driver, go to the Active list, Expand the group it is in, highlight the driver and press Enter. The cursor will move to the Parameter edit area, and the device's parameters may be edited. While editing parameters, the TAB and cursor keys can be used to move between fields. Most numeric values (except IRQ) are entered in hexadecimal, as indicated by the '0x' at the beginning of the field. The allowable values for a given field are show in the Key Help area when the field is active. To finish configuring a driver, press 'Q'. Note that PCI and EISA devices can be probed reliably, therefore they are not shown in the table above nor can their settings be changed using UserConfig. PCI drivers may be seen in the "PCI Devices" section in the Active Devices list, if you wish to check for their presence. 3. LINT - other possible configurations -- ------------------------------------ The following drivers are not in the GENERIC kernel but remain available to those who do not mind compiling a custom kernel (see section 6 of FreeBSD.FAQ). The LINT configuration file (/sys/i386/conf/LINT) also contains prototype entries for just about every device supported by FreeBSD and is a good general reference. The device names and a short description of each are listed below. The port numbers, etc, are not meaningful here since you will need to compile a custom kernel to gain access to these devices anyway and can thus adjust the addresses to match the hardware in your computer in the process. The LINT file contains prototype entries for all of the below which you can easily cut-and-paste into your own file (or simply copy LINT and edit it to taste): ctx: Cortex-I frame grabber cx: Cronyx/Sigma multiport sync/async cy: Cyclades high-speed serial driver el: 3Com 3C501 fea: DEC DEFEA EISA FDDI adapter fpa: DEC DEFPA PCI FDDI adapter gp: National Instruments AT-GPIB and AT-GPIB/TNT board gsc: Genius GS-4500 hand scanner gus: Gravis Ultrasound - Ultrasound, Ultrasound 16, Ultrasound MAX gusxvi: Gravis Ultrasound 16-bit PCM hea: Efficient ENI-155p ATM PCI adapter hfa: FORE PCA-200E ATM PCI adapter joy: Joystick labpc: National Instrument's Lab-PC and Lab-PC+ meteor: Matrox Meteor frame-grabber card bktr: Brooktree Bt848 / Bt878 based frame-grabber cards. mpu: Roland MPU-401 stand-alone card mse: Microsoft, Logitech, ATI bus mouse ports mss: Microsoft Sound System nic: Dr Neuhaus NICCY 3008, 3009 & 5000 ISDN cards opl: Yamaha OPL-2 and OPL-3 FM - SB, SB Pro, SB 16, ProAudioSpectrum pas: ProAudioSpectrum PCM and MIDI pca: PCM audio ("/dev/audio") through your PC speaker pcm: PCM audio on most modern ISA audio codecs psm: PS/2 mouse port rc: RISCom/8 multiport card rdp: RealTek RTL 8002 Pocket Ethernet adapter sb: SoundBlaster PCM - SoundBlaster, SB Pro, SB16, ProAudioSpectrum sbmidi: SoundBlaster 16 MIDI interface sbxvi: SoundBlaster 16 si: Specialix SI/XIO/SX (old and enhanced ISA, PCI, EISA) serial spigot: Creative Labs Video Spigot video-acquisition board uart: Stand-alone 6850 UART for MIDI wds: Western Digital WD7000 IDE --- end of list --- 4. Supported Hardware -- ------------------ FreeBSD currently runs on a wide variety of ISA, VLB, EISA and PCI bus based PC's, ranging from 386sx to Pentium class machines (though the 386sx is not recommended). Support for generic IDE or ESDI drive configurations, various SCSI controller, network and serial cards is also provided. What follows is a list of all peripherals currently known to work with FreeBSD. Other configurations may also work, we have simply not as yet received confirmation of this. 4.1. Disk Controllers ---- ---------------- WD1003 (any generic MFM/RLL) WD1007 (any generic IDE/ESDI) IDE ATA Adaptec 1535 ISA SCSI controllers Adaptec 154x series ISA SCSI controllers Adaptec 174x series EISA SCSI controller in standard and enhanced mode. Adaptec 274X/284X/2920C/2930U2/294x/2950/3940/3950 (Narrow/Wide/Twin) series EISA/VLB/PCI SCSI controllers. Adaptec AIC7850, AIC7860, AIC7880, AIC789x, on-board SCSI controllers. AdvanSys SCSI controllers (all models). BusLogic MultiMaster controllers: [ Please note that BusLogic/Mylex "Flashpoint" adapters are NOT yet supported ] BusLogic MultiMaster "W" Series Host Adapters: BT-948, BT-958, BT-958D BusLogic MultiMaster "C" Series Host Adapters: BT-946C, BT-956C, BT-956CD, BT-445C, BT-747C, BT-757C, BT-757CD, BT-545C, BT-540CF BusLogic MultiMaster "S" Series Host Adapters: BT-445S, BT-747S, BT-747D, BT-757S, BT-757D, BT-545S, BT-542D, BT-742A, BT-542B BusLogic MultiMaster "A" Series Host Adapters: BT-742A, BT-542B AMI FastDisk controllers that are true BusLogic MultiMaster clones are also supported. DPT SmartCACHE Plus, SmartCACHE III, SmartRAID III, SmartCACHE IV and SmartRAID IV SCSI/RAID controllers are supported. The DPT SmartRAID/CACHE V is not yet supported. SymBios (formerly NCR) 53C810, 53C810a, 53C815, 53C820, 53C825a, 53C860, 53C875, 53C875j, 53C885, 53C895 and 53C896 PCI SCSI controllers: ASUS SC-200 Data Technology DTC3130 (all variants) Diamond FirePort (all) NCR cards (all) Symbios cards (all) Tekram DC390W, 390U and 390F Tyan S1365 QLogic 1020, 1040, 1040B and 2100 SCSI and Fibre Channel Adapters DTC 3290 EISA SCSI controller in 1542 emulation mode. With all supported SCSI controllers, full support is provided for SCSI-I & SCSI-II peripherals, including hard disks, optical disks, tape drives (including DAT and 8mm Exabyte), medium changers, processor target devices and CDROM drives. WORM devices that support CDROM commands are supported for read-only access by the CDROM driver. WORM/CD-R/CD-RW writing support is provided by cdrecord, which is in the ports tree. The following CD-ROM type systems are supported at this time: (cd) SCSI interface (also includes ProAudio Spectrum and SoundBlaster SCSI) (matcd) Matsushita/Panasonic (Creative SoundBlaster) proprietary interface (562/563 models) (scd) Sony proprietary interface (all models) (wcd) ATAPI IDE interface The following drivers were supported under the old SCSI subsystem, but are NOT YET supported under the new CAM SCSI subsystem: Tekram DC390 and DC390T controllers (maybe other cards based on the AMD 53c974 as well). NCR5380/NCR53400 ("ProAudio Spectrum") SCSI controller. UltraStor 14F, 24F and 34F SCSI controllers. Seagate ST01/02 SCSI controllers. Future Domain 8xx/950 series SCSI controllers. WD7000 SCSI controller. Adaptec 1510 series ISA SCSI controllers (not for bootable devices) Adaptec 152x series ISA SCSI controllers Adaptec AIC-6260 and AIC-6360 based boards, which includes the AHA-152x and SoundBlaster SCSI cards. [ Note: There is work-in-progress to port the AIC-6260/6360 and UltraStor drivers to the new CAM SCSI framework, but no estimates on when or if they will be completed. ] Unmaintained drivers, they might or might not work for your hardware: Floppy tape interface (Colorado/Mountain/Insight) (mcd) Mitsumi proprietary CD-ROM interface (all models) 4.2. Network cards ---- ------------- +Adaptec Duralink PCI fast ethernet adapters based on the Adaptec +AIC-6915 fast ethernet controller chip, including the following: + ANA-62011 64-bit single port 10/100baseTX adapter + ANA-62022 64-bit dual port 10/100baseTX adapter + ANA-62044 64-bit quad port 10/100baseTX adapter + ANA-69011 32-bit single port 10/100baseTX adapter + ANA-62020 64-bit single port 100baseFX adapter + Allied-Telesis AT1700 and RE2000 cards Alteon Networks PCI gigabit ethernet NICs based on the Tigon 1 and Tigon 2 chipsets, including the following: Alteon AceNIC (Tigon 1 and 2) 3Com 3c985-SX (Tigon 1 and 2) Netgear GA620 (Tigon 2) Silicon Graphics Gigabit Ethernet DEC/Compaq EtherWORKS 1000 NEC Gigabit Ethernet AMD PCnet/PCI (79c970 & 53c974 or 79c974) SMC Elite 16 WD8013 ethernet interface, and most other WD8003E, WD8003EBT, WD8003W, WD8013W, WD8003S, WD8003SBT and WD8013EBT based clones. SMC Elite Ultra is also supported. RealTek 8129/8139 fast ethernet NICs including the following: Allied Telesyn AT2550 Allied Telesyn AT2500TX Genius GF100TXR (RTL8139) NDC Communications NE100TX-E OvisLink LEF-8129TX OvisLink LEF-8139TX Netronix Inc. EA-1210 NetEther 10/100 KTX-9130TX 10/100 Fast Ethernet Accton "Cheetah" EN1027D (MPX 5030/5038; RealTek 8139 clone?) SMC EZ Card 10/100 PCI 1211-TX Lite-On 82c168/82c169 PNIC fast ethernet NICs including the following: LinkSys EtherFast LNE100TX NetGear FA310-TX Rev. D1 Matrox FastNIC 10/100 - + Kingston KNE110TX + Macronix 98713, 98713A, 98715, 98715A and 98725 fast ethernet NICs NDC Communications SFA100A (98713A) CNet Pro120A (98713 or 98713A) CNet Pro120B (98715) SVEC PN102TX (98713) Macronix/Lite-On PNIC II LC82C115 fast ethernet NICs including the following: LinkSys EtherFast LNE100TX Version 2 Winbond W89C840F fast ethernet NICs including the following: Trendware TE100-PCIE VIA Technologies VT3043 "Rhine I" and VT86C100A "Rhine II" fast ethernet NICs including the following: Hawking Technologies PN102TX D-Link DFE530TX + +SysKonnect SK-984x PCI gigabit ethernet cards including the following: + SK-9841 1000baseLX single mode fiber, single port + SK-9842 1000baseSX multimode fiber, single port + SK-9843 1000baseLX single mode fiber, dual port + SK-9844 1000baseSX multimode fiber, dual port Texas Instruments ThunderLAN PCI NICs, including the following: Compaq Netelligent 10, 10/100, 10/100 Proliant, 10/100 Dual-Port Compaq Netelligent 10/100 TX Embedded UTP, 10 T PCI UTP/Coax, 10/100 TX UTP Compaq NetFlex 3P, 3P Integrated, 3P w/ BNC Olicom OC-2135/2138, OC-2325, OC-2326 10/100 TX UTP Racore 8165 10/100baseTX Racore 8148 10baseT/100baseTX/100baseFX multi-personality ADMtek AL981-based PCI fast ethernet NICs ASIX Electronics AX88140A PCI NICs, including the following: Alfa Inc. GFC2204 CNet Pro110B DEC EtherWORKS III NICs (DE203, DE204, and DE205) DEC EtherWORKS II NICs (DE200, DE201, DE202, and DE422) DEC DC21040, DC21041, or DC21140 based NICs (SMC Etherpower 8432T, DE245, etc) DEC FDDI (DEFPA/DEFEA) NICs Efficient ENI-155p ATM PCI FORE PCA-200E ATM PCI Fujitsu MB86960A/MB86965A HP PC Lan+ cards (model numbers: 27247B and 27252A). Intel EtherExpress (not recommended due to driver instability) Intel EtherExpress Pro/10 Intel EtherExpress Pro/100B PCI Fast Ethernet Isolan AT 4141-0 (16 bit) Isolink 4110 (8 bit) Novell NE1000, NE2000, and NE2100 ethernet interface. PCI network cards emulating the NE2000: RealTek 8029, NetVin 5000, Winbond W89C940, Surecom NE-34, VIA VT86C926. 3Com 3C501 cards 3Com 3C503 Etherlink II 3Com 3c505 Etherlink/+ 3Com 3C507 Etherlink 16/TP 3Com 3C509, 3C579, 3C589 (PCMCIA), 3C590/592/595/900/905/905B PCI and EISA (Fast) Etherlink III / (Fast) Etherlink XL 3Com 3c980 Fast Etherlink XL server adapter Toshiba ethernet cards PCMCIA ethernet cards from IBM and National Semiconductor are also supported. Note that NO token ring cards are supported at this time as we're still waiting for someone to donate a driver for one of them. Any takers? 4.3. Misc ---- ---- AST 4 port serial card using shared IRQ. ARNET 8 port serial card using shared IRQ. ARNET (now Digiboard) Sync 570/i high-speed serial. Boca BB1004 4-Port serial card (Modems NOT supported) Boca IOAT66 6-Port serial card (Modems supported) Boca BB1008 8-Port serial card (Modems NOT supported) Boca BB2016 16-Port serial card (Modems supported) Cyclades Cyclom-y Serial Board. STB 4 port card using shared IRQ. SDL Communications Riscom/8 Serial Board. SDL Communications RISCom/N2 and N2pci high-speed sync serial boards. Specialix SI/XIO/SX multiport serial cards, with both the older SIHOST2.x and the new "enhanced" (transputer based, aka JET) host cards. ISA, EISA and PCI are supported. Stallion multiport serial boards: EasyIO, EasyConnection 8/32 & 8/64, ONboard 4/16 and Brumby. Adlib, SoundBlaster, SoundBlaster Pro, ProAudioSpectrum, Gravis UltraSound and Roland MPU-401 sound cards. Connectix QuickCam Matrox Meteor Video frame grabber Creative Labs Video Spigot frame grabber Cortex1 frame grabber Various Frame grabbers based on Brooktree Bt848 and Bt878 chip. HP4020, HP6020, Philips CDD2000/CDD2660 and Plasmon CD-R drives. Bus mice PS/2 mice Standard PC Joystick X-10 power controllers GPIB and Transputer drivers. Genius and Mustek hand scanners. Floppy tape drives (some rather old models only, driver rather stale) Lucent Technologies WaveLAN/IEEE 802.11 PCMCIA and ISA standard speed (2Mbps) and turbo speed (6Mbps) wireless network adapters and workalikes (NCR WaveLAN/IEEE 802.11, Cabletron RoamAbout 802.11 DS). Note: the ISA versions of these adapters are actually PCMCIA cards combined with an ISA to PCMCIA bridge card, so both kinds of devices work with the same driver. FreeBSD currently does NOT support IBM's microchannel (MCA) bus. Index: stable/3/release/texts/RELNOTES.TXT =================================================================== --- stable/3/release/texts/RELNOTES.TXT (revision 49544) +++ stable/3/release/texts/RELNOTES.TXT (revision 49545) @@ -1,599 +1,620 @@ RELEASE NOTES FreeBSD Release 3.2-STABLE Welcome to this 3.2-STABLE snapshot, a follow-on to 3.2-RELEASE released June 1999. In the months since 3.2 was released, many bug fixes and general enhancements have been made to the system. Please see relevant details below. Any installation failures or crashes should be reported by using the send-pr command (those preferring a WEB based interface can also see http://www.freebsd.org/send-pr.html). For information about FreeBSD and the layout of the 3.3-RELEASE directory (especially if you're installing from floppies!), see ABOUT.TXT. For installation instructions, see the INSTALL.TXT and HARDWARE.TXT files. Table of contents: ------------------ 1. What's new since 3.2-RELEASE 1.1 KERNEL CHANGES 1.2 SECURITY FIXES 1.3 USERLAND CHANGES 2. Supported Configurations 2.1 Disk Controllers 2.2 Ethernet cards 2.3 ATM 2.4 Misc 3. Obtaining FreeBSD 3.1 FTP/Mail 3.2 CDROM 4. Upgrading from previous releases of FreeBSD 5. Reporting problems, making suggestions, submitting code 6. Acknowledgements 1. What's new since 3.2-RELEASE --------------------------------- 1.1. KERNEL CHANGES ------------------- Alpha timecounter code has been improved. The al and rl drivers have been ported to the Alpha. The i386 bootstrap has been enhanced for some problematic systems. Driver support has been added for IEEE 802.11 PCMCIA wireless network adapters based on the Lucent Hermes chipset, including the Lucent WaveLAN/IEEE 802.11 and the Cabletron RoamAbout. Both 2Mbps and 6Mbps Turbo adapters are supported. [MERGED] Driver support has been added for PCI fast ethernet cards based on the ADMtek Inc. AL981 Comet chipset. Driver support has been added for PCI fast ethernet cards based on the LC82C115 'PNIC II' chipset. Driver support has been added for the Compaq Smart Raid family of RAID controllers. USB support has been improved. Major updates to the Vinum volume manager have been incorporated. Driver support for a number of Realtek and Avance Asound audio cards has been added. A number of NFS problems have been fixed. +Driver support has been added for SysKonnect SK-984x PCI gigabit +ethernet adapters. +Driver support has been added for Adaptec Duralink PCI ethernet adapters +based on the Adaptec AIC-6915 fast ethernet controller. + 1.2. SECURITY FIXES ------------------- (none yet logged) 1.3. USERLAND CHANGES --------------------- TCP Wrapper support in inetd(8) is now controlled with command-line options and dgram services may be wrapped in addition to previously wrapped service types. Please see the manpage for details, since inetd run without command-line options will do no wrapping. 2. Supported Configurations --------------------------- FreeBSD currently runs on a wide variety of ISA, VLB, EISA and PCI bus based PC's, ranging from 386sx to Pentium class machines (though the 386sx is not recommended). Support for generic IDE or ESDI drive configurations, various SCSI controller, network and serial cards is also provided. What follows is a list of all peripherals currently known to work with FreeBSD. Other configurations may also work, we have simply not as yet received confirmation of this. 2.1. Disk Controllers --------------------- WD1003 (any generic MFM/RLL) WD1007 (any generic IDE/ESDI) IDE ATA Adaptec 1535 ISA SCSI controllers Adaptec 154x series ISA SCSI controllers Adaptec 174x series EISA SCSI controller in standard and enhanced mode. Adaptec 274X/284X/2920C/2930U2/294x/2950/3940/3950 (Narrow/Wide/Twin) series EISA/VLB/PCI SCSI controllers. Adaptec AIC7850, AIC7860, AIC7880, AIC789x, on-board SCSI controllers. AdvanSys SCSI controllers (all models). BusLogic MultiMaster controllers: [ Please note that BusLogic/Mylex "Flashpoint" adapters are NOT yet supported ] BusLogic MultiMaster "W" Series Host Adapters: BT-948, BT-958, BT-958D BusLogic MultiMaster "C" Series Host Adapters: BT-946C, BT-956C, BT-956CD, BT-445C, BT-747C, BT-757C, BT-757CD, BT-545C, BT-540CF BusLogic MultiMaster "S" Series Host Adapters: BT-445S, BT-747S, BT-747D, BT-757S, BT-757D, BT-545S, BT-542D, BT-742A, BT-542B BusLogic MultiMaster "A" Series Host Adapters: BT-742A, BT-542B AMI FastDisk controllers that are true BusLogic MultiMaster clones are also supported. DPT SmartCACHE Plus, SmartCACHE III, SmartRAID III, SmartCACHE IV and SmartRAID IV SCSI/RAID controllers are supported. The DPT SmartRAID/CACHE V is not yet supported. SymBios (formerly NCR) 53C810, 53C810a, 53C815, 53C820, 53C825a, 53C860, 53C875, 53C875j, 53C885, 53C895 and 53C896 PCI SCSI controllers: ASUS SC-200 Data Technology DTC3130 (all variants) Diamond FirePort (all) NCR cards (all) Symbios cards (all) Tekram DC390W, 390U and 390F Tyan S1365 QLogic 1020, 1040, 1040B, 1080 and 1240 SCSI Host Adapters. QLogic 2100 Fibre Channel Adapters (private loop only). DTC 3290 EISA SCSI controller in 1542 emulation mode. With all supported SCSI controllers, full support is provided for SCSI-I & SCSI-II peripherals, including hard disks, optical disks, tape drives (including DAT and 8mm Exabyte), medium changers, processor target devices and CDROM drives. WORM devices that support CDROM commands are supported for read-only access by the CDROM driver. WORM/CD-R/CD-RW writing support is provided by cdrecord, which is in the ports tree. The following CD-ROM type systems are supported at this time: (cd) SCSI interface (also includes ProAudio Spectrum and SoundBlaster SCSI) (matcd) Matsushita/Panasonic (Creative SoundBlaster) proprietary interface (562/563 models) (scd) Sony proprietary interface (all models) (wcd) ATAPI IDE interface The following drivers were supported under the old SCSI subsystem, but are NOT YET supported under the new CAM SCSI subsystem: Tekram DC390 and DC390T controllers (maybe other cards based on the AMD 53c974 as well). NCR5380/NCR53400 ("ProAudio Spectrum") SCSI controller. UltraStor 14F, 24F and 34F SCSI controllers. Seagate ST01/02 SCSI controllers. Future Domain 8xx/950 series SCSI controllers. WD7000 SCSI controller. Adaptec 1510 series ISA SCSI controllers (not for bootable devices) Adaptec 152x series ISA SCSI controllers Adaptec AIC-6260 and AIC-6360 based boards, which includes the AHA-152x and SoundBlaster SCSI cards. [ Note: There is work-in-progress to port the AIC-6260/6360 and UltraStor drivers to the new CAM SCSI framework, but no estimates on when or if they will be completed. ] Unmaintained drivers, they might or might not work for your hardware: Floppy tape interface (Colorado/Mountain/Insight) (mcd) Mitsumi proprietary CD-ROM interface (all models) 2.2. Ethernet cards ------------------- + +Adaptec Duralink PCI fast ethernet adapters based on the Adaptec +AIC-6915 fast ethernet controller chip, including the following: + ANA-62011 64-bit single port 10/100baseTX adapter + ANA-62022 64-bit dual port 10/100baseTX adapter + ANA-62044 64-bit quad port 10/100baseTX adapter + ANA-69011 32-bit single port 10/100baseTX adapter + ANA-62020 64-bit single port 100baseFX adapter + Allied-Telesis AT1700 and RE2000 cards Alteon Networks PCI gigabit ethernet NICs based on the Tigon 1 and Tigon 2 chipsets, including the following: Alteon AceNIC (Tigon 1 and 2) 3Com 3c985-SX (Tigon 1 and 2) Netgear GA620 (Tigon 2) Silicon Graphics Gigabit Ethernet DEC/Compaq EtherWORKS 1000 NEC Gigabit Ethernet AMD PCnet/PCI (79c970 & 53c974 or 79c974) SMC Elite 16 WD8013 ethernet interface, and most other WD8003E, WD8003EBT, WD8003W, WD8013W, WD8003S, WD8003SBT and WD8013EBT based clones. SMC Elite Ultra. SMC Etherpower II. RealTek 8129/8139 fast ethernet NICs including the following: Allied Telesyn AT2550 Allied Telesyn AT2500TX Genius GF100TXR (RTL8139) NDC Communications NE100TX-E OvisLink LEF-8129TX OvisLink LEF-8139TX Netronix Inc. EA-1210 NetEther 10/100 KTX-9130TX 10/100 Fast Ethernet Accton "Cheetah" EN1027D (MPX 5030/5038; RealTek 8139 clone?) SMC EZ Card 10/100 PCI 1211-TX Lite-On 82c168/82c169 PNIC fast ethernet NICs including the following: LinkSys EtherFast LNE100TX NetGear FA310-TX Rev. D1 Matrox FastNIC 10/100 + Kingston KNE110TX Macronix 98713, 98713A, 98715, 98715A and 98725 fast ethernet NICs NDC Communications SFA100A (98713A) CNet Pro120A (98713 or 98713A) CNet Pro120B (98715) SVEC PN102TX (98713) Macronix/Lite-On PNIC II LC82C115 fast ethernet NICs including the following: LinkSys EtherFast LNE100TX Version 2 Winbond W89C840F fast ethernet NICs including the following: Trendware TE100-PCIE VIA Technologies VT3043 "Rhine I" and VT86C100A "Rhine II" fast ethernet NICs including the following: Hawking Technologies PN102TX D-Link DFE530TX +SysKonnect SK-984x PCI gigabit ethernet cards including the following: + SK-9841 1000baseLX single mode fiber, single port + SK-9842 1000baseSX multimode fiber, single port + SK-9843 1000baseLX single mode fiber, dual port + SK-9844 1000baseSX multimode fiber, dual port + Texas Instruments ThunderLAN PCI NICs, including the following: Compaq Netelligent 10, 10/100, 10/100 Proliant, 10/100 Dual-Port Compaq Netelligent 10/100 TX Embedded UTP, 10 T PCI UTP/Coax, 10/100 TX UTP Compaq NetFlex 3P, 3P Integrated, 3P w/ BNC Olicom OC-2135/2138, OC-2325, OC-2326 10/100 TX UTP Racore 8165 10/100baseTX Racore 8148 10baseT/100baseTX/100baseFX multi-personality ADMtek Inc. AL981-based PCI fast ethernet NICs ASIX Electronics AX88140A PCI NICs, including the following: Alfa Inc. GFC2204 CNet Pro110B DEC EtherWORKS III NICs (DE203, DE204, and DE205) DEC EtherWORKS II NICs (DE200, DE201, DE202, and DE422) DEC DC21040, DC21041, or DC21140 based NICs (SMC Etherpower 8432T, DE245, etc) DEC FDDI (DEFPA/DEFEA) NICs Fujitsu MB86960A/MB86965A HP PC Lan+ cards (model numbers: 27247B and 27252A). Intel EtherExpress 16 Intel EtherExpress Pro/10 Intel EtherExpress Pro/100B PCI Fast Ethernet Isolan AT 4141-0 (16 bit) Isolink 4110 (8 bit) Novell NE1000, NE2000, and NE2100 ethernet interface. PCI network cards emulating the NE2000: RealTek 8029, NetVin 5000, Winbond W89C940, Surecom NE-34, VIA VT86C926. 3Com 3C501 cards 3Com 3C503 Etherlink II 3Com 3c505 Etherlink/+ 3Com 3C507 Etherlink 16/TP 3Com 3C509, 3C579, 3C589 (PCMCIA), 3C590/592/595/900/905/905B PCI and EISA (Fast) Etherlink III / (Fast) Etherlink XL 3Com 3c980 Fast Etherlink XL server adapter Toshiba ethernet cards Crystal Semiconductor CS89x0-based NICs, including: IBM Etherjet ISA PCMCIA ethernet cards from IBM and National Semiconductor are also supported. Note that NO token ring cards are supported at this time as we're still waiting for someone to donate a driver for one of them. Any takers? 2.3 ATM ------- o ATM Host Interfaces - FORE Systems, Inc. PCA-200E ATM PCI Adapters - Efficient Networks, Inc. ENI-155p ATM PCI Adapters o ATM Signalling Protocols - The ATM Forum UNI 3.1 signalling protocol - The ATM Forum UNI 3.0 signalling protocol - The ATM Forum ILMI address registration - FORE Systems's proprietary SPANS signalling protocol - Permanent Virtual Channels (PVCs) o IETF "Classical IP and ARP over ATM" model - RFC 1483, "Multiprotocol Encapsulation over ATM Adaptation Layer 5" - RFC 1577, "Classical IP and ARP over ATM" - RFC 1626, "Default IP MTU for use over ATM AAL5" - RFC 1755, "ATM Signaling Support for IP over ATM" - RFC 2225, "Classical IP and ARP over ATM" - RFC 2334, "Server Cache Synchronization Protocol (SCSP)" - Internet Draft draft-ietf-ion-scsp-atmarp-00.txt, "A Distributed ATMARP Service Using SCSP" o ATM Sockets interface 2.4. Misc --------- AST 4 port serial card using shared IRQ. ARNET 8 port serial card using shared IRQ. ARNET (now Digiboard) Sync 570/i high-speed serial. Boca BB1004 4-Port serial card (Modems NOT supported) Boca IOAT66 6-Port serial card (Modems supported) Boca BB1008 8-Port serial card (Modems NOT supported) Boca BB2016 16-Port serial card (Modems supported) Comtrol Rocketport card. Cyclades Cyclom-y Serial Board. STB 4 port card using shared IRQ. SDL Communications Riscom/8 Serial Board. SDL Communications RISCom/N2 and N2pci high-speed sync serial boards. Stallion multiport serial boards: EasyIO, EasyConnection 8/32 & 8/64, ONboard 4/16 and Brumby. Specialix SI/XIO/SX ISA, EISA and PCI serial expansion cards/modules. Adlib, SoundBlaster, SoundBlaster Pro, ProAudioSpectrum, Gravis UltraSound and Roland MPU-401 sound cards. (snd driver) Most ISA audio codecs manufactured by Crystal Semiconductors, OPTi, Creative Labs, Avance, Yamaha and ENSONIQ. (pcm driver) Connectix QuickCam Matrox Meteor Video frame grabber Creative Labs Video Spigot frame grabber Cortex1 frame grabber Hauppauge Wincast/TV boards (PCI) STB TV PCI Intel Smart Video Recorder III Various Frame grabbers based on Brooktree Bt848 and Bt878 chip. HP4020, HP6020, Philips CDD2000/CDD2660 and Plasmon CD-R drives. PS/2 mice Standard PC Joystick X-10 power controllers GPIB and Transputer drivers. Genius and Mustek hand scanners. Xilinx XC6200 based reconfigurable hardware cards compatible with the HOT1 from Virtual Computers (www.vcc.com) Support for Dave Mills experimental Loran-C receiver. Lucent Technologies WaveLAN/IEEE 802.11 PCMCIA and ISA standard speed (2Mbps) and turbo speed (6Mbps) wireless network adapters and workalikes (NCR WaveLAN/IEEE 802.11, Cabletron RoamAbout 802.11 DS). Note: the ISA versions of these adapters are actually PCMCIA cards combined with an ISA to PCMCIA bridge card, so both kinds of devices work with the same driver. FreeBSD currently does NOT support IBM's microchannel (MCA) bus. 3. Obtaining FreeBSD -------------------- You may obtain FreeBSD in a variety of ways: 3.1. FTP/Mail ------------- You can ftp FreeBSD and any or all of its optional packages from `ftp.freebsd.org' - the official FreeBSD release site. For other locations that mirror the FreeBSD software see the file MIRROR.SITES. Please ftp the distribution from the site closest (in networking terms) to you. Additional mirror sites are always welcome! Contact freebsd-admin@FreeBSD.org for more details if you'd like to become an official mirror site. If you do not have access to the Internet and electronic mail is your only recourse, then you may still fetch the files by sending mail to `ftpmail@ftpmail.vix.com' - putting the keyword "help" in your message to get more information on how to fetch files using this mechanism. Please do note, however, that this will end up sending many *tens of megabytes* through the mail and should only be employed as an absolute LAST resort! 3.2. CDROM ---------- FreeBSD 3.2-RELEASE CDs may be ordered on CDROM from: Walnut Creek CDROM 4041 Pike Lane, Suite F Concord CA 94520 1-800-786-9907, +1-925-674-0783, +1-925-674-0821 (FAX) Or via the Internet from orders@cdrom.com or http://www.cdrom.com. Their current catalog can be obtained via ftp from: ftp://ftp.cdrom.com/cdrom/catalog Cost per -RELEASE CD is $39.95 or $24.95 with a FreeBSD subscription. FreeBSD SNAPshot CDs, when available, are $39.95 or $14.95 with a FreeBSD-SNAP subscription (-RELEASE and -SNAP subscriptions are entirely separate). With a subscription, you will automatically receive updates as they are released. Your credit card will be billed when each disk is shipped and you may cancel your subscription at any time without further obligation. Shipping (per order not per disc) is $5 in the US, Canada or Mexico and $9.00 overseas. They accept Visa, Mastercard, Discover, American Express or checks in U.S. Dollars and ship COD within the United States. California residents please add 8.25% sales tax. Should you be dissatisfied for any reason, the CD comes with an unconditional return policy. 4. Upgrading from previous releases of FreeBSD ---------------------------------------------- If you're upgrading from a previous release of FreeBSD, most likely it's 2.2.x or 2.1.x (in some lesser number of cases) and some of the following issues may affect you, depending of course on your chosen method of upgrading. There are two popular ways of upgrading FreeBSD distributions: o Using sources, via /usr/src o Using sysinstall's (binary) upgrade option. In the case of using sources, there are simply two targets you need to be aware of: The standard ``upgrade'' target, which will upgrade a 2.x or 3.0 system to 3.2 and the ``world'' target, which will take an already upgraded system and keep it in sync with whatever changes have happened since the initial upgrade. In the case of using the binary upgrade option, the system will go straight to 3.2/ELF but also populate the //lib/aout directories for backwards compatibility with older binaries. In either case, going to ELF will mean that you'll have somewhat smaller binaries and access to a lot more compiler goodies which have been already been ported to other ELF environments (our older and somewhat crufty a.out format being largely unsupported by most other software projects). Those who wish to retain access to the older a.out dynamic executables should be sure and install the compat22 distribution. Notice that the a.out libraries won't be accessible until the system is rebooted, which may cause trouble with certain a.out packages. Also, do not use install disks or sysinstall from previous versions, as version 3.1 introduced a new bootstrapping procedure, requiring new boot blocks to be installed (because of elf kernels), and version 3.2 has further modifications to the bootstrapping procedure. [ other important upgrading notes should go here] 5. Reporting problems, making suggestions, submitting code. ----------------------------------------------------------- Your suggestions, bug reports and contributions of code are always valued - please do not hesitate to report any problems you may find (preferably with a fix attached, if you can!). The preferred method to submit bug reports from a machine with Internet mail connectivity is to use the send-pr command or use the CGI script at http://www.freebsd.org/send-pr.html. Bug reports will be dutifully filed by our faithful bugfiler program and you can be sure that we'll do our best to respond to all reported bugs as soon as possible. Bugs filed in this way are also visible on our WEB site in the support section and are therefore valuable both as bug reports and as "signposts" for other users concerning potential problems to watch out for. If, for some reason, you are unable to use the send-pr command to submit a bug report, you can try to send it to: freebsd-bugs@FreeBSD.org Note that send-pr itself is a shell script that should be easy to move even onto a totally different system. We much prefer if you could use this interface, since it make it easier to keep track of the problem reports. However, before submitting, please try to make sure whether the problem might have already been fixed since. Otherwise, for any questions or tech support issues, please send mail to: freebsd-questions@FreeBSD.org Additionally, being a volunteer effort, we are always happy to have extra hands willing to help - there are already far more desired enhancements than we'll ever be able to manage by ourselves! To contact us on technical matters, or with offers of help, please send mail to: freebsd-hackers@FreeBSD.org Please note that these mailing lists can experience *significant* amounts of traffic and if you have slow or expensive mail access and are only interested in keeping up with significant FreeBSD events, you may find it preferable to subscribe instead to: freebsd-announce@FreeBSD.org All of the mailing lists can be freely joined by anyone wishing to do so. Send mail to MajorDomo@FreeBSD.org and include the keyword `help' on a line by itself somewhere in the body of the message. This will give you more information on joining the various lists, accessing archives, etc. There are a number of mailing lists targeted at special interest groups not mentioned here, so send mail to majordomo and ask about them! 6. Acknowledgements ------------------- FreeBSD represents the cumulative work of many dozens, if not hundreds, of individuals from around the world who have worked very hard to bring you this release. For a complete list of FreeBSD project staffers, please see: http://www.freebsd.org/handbook/staff.html or, if you've loaded the doc distribution: file:/usr/share/doc/handbook/staff.html Special mention to: The donors listed at http://www.freebsd.org/handbook/donors.html Justin M. Seger for almost single-handedly converting the ports collection to ELF. Doug Rabson and John Birrell for making FreeBSD/alpha happen and to the NetBSD project for substantial indirect aid. Peter Wemm for the new kernel module system (with substantial aid from Doug Rabson). And to the many thousands of FreeBSD users and testers all over the world, without whom this release simply would not have been possible. We sincerely hope you enjoy this release of FreeBSD! The FreeBSD Project Index: stable/3/share/man/man4/man4.i386/Makefile =================================================================== --- stable/3/share/man/man4/man4.i386/Makefile (revision 49544) +++ stable/3/share/man/man4/man4.i386/Makefile (revision 49545) @@ -1,99 +1,101 @@ -# $Id: Makefile,v 1.95.2.4 1999/04/30 19:35:08 wpaul Exp $ +# $Id: Makefile,v 1.95.2.5 1999/05/22 21:08:42 wpaul Exp $ MAN4= adv.4 adw.4 aha.4 ahb.4 ahc.4 aic.4 apm.4 ar.4 asc.4 atkbd.4 \ atkbdc.4 ax.4 bktr.4 bt.4 cs.4 cx.4 cy.4 de.4 \ dgb.4 dpt.4 ed.4 el.4 en.4 ep.4 ex.4 fdc.4 fe.4 fxp.4 gsc.4 ie.4 \ io.4 joy.4 keyboard.4 labpc.4 le.4 lnc.4 lpt.4 matcd.4 mcd.4 \ mem.4 meteor.4 mouse.4 mse.4 mtio.4 mx.4 ncr.4 npx.4 \ pcf.4 pcm.4 pcvt.4 perfmon.4 pn.4 pnp.4 ppc.4 psm.4 \ - rdp.4 rl.4 sb.4 scd.4 screen.4 si.4 sio.4 \ + rdp.4 rl.4 sb.4 scd.4 screen.4 sf.4 si.4 sio.4 sk.4 \ spkr.4 splash.4 sr.4 syscons.4 sysmouse.4 ti.4 tl.4 tw.4 tx.4 \ vga.4 vr.4 vx.4 wb.4 wd.4 wfd.4 wi.4 wl.4 wt.4 xl.4 ze.4 zp.4 MLINKS= adv.4 ../adv.4 MLINKS+= adw.4 ../adw.4 MLINKS+= aha.4 ../aha.4 MLINKS+= ahb.4 ../ahb.4 MLINKS+= ahc.4 ../ahc.4 MLINKS+= aic.4 ../aic.4 MLINKS+= apm.4 ../apm.4 MLINKS+= ar.4 ../ar.4 MLINKS+= asc.4 ../asc.4 MLINKS+= atkbd.4 ../atkbd.4 MLINKS+= atkbdc.4 ../atkbdc.4 MLINKS+= ax.4 ../ax.4 MLINKS+= bktr.4 ../bktr.4 MLINKS+= bt.4 ../bt.4 MLINKS+= cs.4 ../cs.4 MLINKS+= cx.4 ../cx.4 MLINKS+= cy.4 ../cy.4 MLINKS+= de.4 ../de.4 MLINKS+= dgb.4 ../dgb.4 MLINKS+= dpt.4 ../dpt.4 MLINKS+= ed.4 ../ed.4 MLINKS+= el.4 ../el.4 MLINKS+= en.4 ../en.4 MLINKS+= ep.4 ../ep.4 MLINKS+= ex.4 ../ex.4 MLINKS+= fdc.4 ../fdc.4 MLINKS+= fe.4 ../fe.4 MLINKS+= fxp.4 ../fxp.4 MLINKS+= gsc.4 ../gsc.4 MLINKS+= ie.4 ../ie.4 MLINKS+= io.4 ../io.4 MLINKS+= joy.4 ../joy.4 MLINKS+= keyboard.4 ../keyboard.4 MLINKS+= labpc.4 ../labpc.4 MLINKS+= le.4 ../le.4 MLINKS+= lnc.4 ../lnc.4 MLINKS+= lpt.4 ../lpt.4 MLINKS+= matcd.4 ../matcd.4 MLINKS+= mcd.4 ../mcd.4 MLINKS+= mem.4 kmem.4 mem.4 ../mem.4 mem.4 ../kmem.4 MLINKS+= meteor.4 ../meteor.4 MLINKS+= mouse.4 ../mouse.4 MLINKS+= mse.4 ../mse.4 MLINKS+= mtio.4 ../mtio.4 MLINKS+= mx.4 ../mx.4 MLINKS+= ncr.4 ../ncr.4 MLINKS+= npx.4 ../npx.4 MLINKS+= pcf.4 ../pcf.4 MLINKS+= pcm.4 ../pcm.4 MLINKS+= pcvt.4 vt.4 pcvt.4 ../pcvt.4 pcvt.4 ../vt.4 MLINKS+= perfmon.4 ../perfmon.4 MLINKS+= pn.4 ../pn.4 MLINKS+= pnp.4 ../pnp.4 MLINKS+= ppc.4 ../ppc.4 MLINKS+= psm.4 ../psm.4 MLINKS+= rdp.4 ../rdp.4 MLINKS+= rl.4 ../rl.4 MLINKS+= sb.4 ../sb.4 MLINKS+= scd.4 ../scd.4 MLINKS+= screen.4 ../screen.4 +MLINKS+= sf.4 ../sf.4 MLINKS+= si.4 ../si.4 MLINKS+= sio.4 ../sio.4 +MLINKS+= sk.4 ../sk.4 MLINKS+= spkr.4 ../spkr.4 spkr.4 speaker.4 spkr.4 ../speaker.4 MLINKS+= splash.4 ../splash.4 splash.4 screensaver.4 splash.4 ../screensaver.4 MLINKS+= sr.4 ../sr.4 MLINKS+= syscons.4 ../syscons.4 MLINKS+= sysmouse.4 ../sysmouse.4 MLINKS+= ti.4 ../ti.4 MLINKS+= tl.4 ../tl.4 MLINKS+= tw.4 ../tw.4 MLINKS+= tx.4 ../tx.4 MLINKS+= vga.4 ../vga.4 MLINKS+= vr.4 ../vr.4 MLINKS+= vx.4 ../vx.4 MLINKS+= wb.4 ../wb.4 MLINKS+= wd.4 ../wd.4 MLINKS+= wfd.4 ../wfd.4 MLINKS+= wi.4 ../wi.4 MLINKS+= wl.4 ../wl.4 MLINKS+= wt.4 ../wt.4 MLINKS+= xl.4 ../xl.4 MLINKS+= ze.4 ../ze.4 MLINKS+= zp.4 ../zp.4 MANSUBDIR=/i386 .include Index: stable/3/sys/alpha/conf/GENERIC =================================================================== --- stable/3/sys/alpha/conf/GENERIC (revision 49544) +++ stable/3/sys/alpha/conf/GENERIC (revision 49545) @@ -1,126 +1,127 @@ # # GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks # # For more information read the handbook part System Administration -> # Configuring the FreeBSD Kernel -> The Configuration File. # The handbook is available in /usr/share/doc/handbook or online as # latest version from the FreeBSD World Wide Web server # # # An exhaustive list of options and more detailed explanations of the # device lines is present in the ./LINT configuration file. If you are # in doubt as to the purpose or necessity of a line, check first in LINT. # -# $Id: GENERIC,v 1.14.2.10 1999/07/05 08:55:22 msmith Exp $ +# $Id: GENERIC,v 1.14.2.11 1999/07/11 14:55:23 wpaul Exp $ machine "alpha" cpu "EV4" cpu "EV5" ident GENERIC maxusers 32 # Platforms supported options "DEC_AXPPCI_33" # UDB, Multia, AXPpci33, Noname options "DEC_EB164" # EB164, PC164, PC164LX, PC164SX options "DEC_EB64PLUS" # EB64+, Aspen Alpine, etc options "DEC_2100_A50" # AlphaStation 200, 250, 255, 400 options "DEC_KN20AA" # AlphaStation 500, 600 options "DEC_ST550" # Personal Workstation 433, 500, 600 options "DEC_3000_300" # DEC3000/300* Pelic* family options "DEC_3000_500" # DEC3000/[4-9]00 Flamingo/Sandpiper family options INET #InterNETworking options FFS #Berkeley Fast Filesystem options NFS #Network Filesystem options MFS #Memory Filesystem options MFS_ROOT #Memory Filesystem as rootfs options MSDOSFS #MSDOS Filesystem options "CD9660" #ISO 9660 Filesystem options "CD9660_ROOT" #CD-ROM usable as root device options FFS_ROOT #FFS usable as root device [keep this!] options NFS_ROOT #NFS usable as root device options PROCFS #Process filesystem options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device options UCONSOLE #Allow users to grab the console options FAILSAFE #Be conservative config kernel root on da0 # Platform chipsets controller cia0 controller apecs0 controller lca0 # Standard busses controller pci0 controller isa0 # TurboChannel host bus support controller tcasic0 controller tc0 #controller tcds0 controller ioasic0 # A single entry for any of these controllers (ncr, ahb, ahc, amd) is # sufficient for any number of installed devices. controller ncr0 controller isp0 #controller esp0 controller scbus0 device da0 device sa0 device pass0 device cd0 # real time clock device mcclock0 at isa0 port 0x70 controller atkbdc0 at isa? port IO_KBD device atkbd0 at atkbdc? irq 1 device psm0 at atkbdc? irq 12 device vga0 at isa? port ? conflicts # splash screen/screen saver pseudo-device splash # syscons is the default console driver, resembling an SCO console device sc0 at isa? device sio0 at isa0 port "IO_COM1" irq 4 device sio1 at isa0 port "IO_COM2" irq 3 flags 0x50 # Order is important here due to intrusive probes, do *not* alphabetize # this list of network interfaces until the probes have been fixed. # Right now it appears that the ie0 must be probed before ep0. See # revision 1.20 of this file. device al0 device ax0 device de0 device fxp0 device le0 device mx0 device pn0 device rl0 +device sf0 device tl0 device wb0 device xl0 pseudo-device loop pseudo-device ether pseudo-device sl 1 pseudo-device ppp 1 pseudo-device tun 1 pseudo-device pty 16 # KTRACE enables the system-call tracing facility ktrace(2). # This adds 4 KB bloat to your kernel, and slightly increases # the costs of each syscall. options KTRACE #kernel tracing # This provides support for System V shared memory. # options SYSVSHM Index: stable/3/sys/i386/conf/GENERIC =================================================================== --- stable/3/sys/i386/conf/GENERIC (revision 49544) +++ stable/3/sys/i386/conf/GENERIC (revision 49545) @@ -1,218 +1,219 @@ # # GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks # # For more information on this file, please read the handbook section on # Kernel Configuration Files: # # http://www.freebsd.org/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.ORG/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ./LINT configuration file. If you are # in doubt as to the purpose or necessity of a line, check first in LINT. # -# $Id: GENERIC,v 1.143.2.15 1999/06/19 21:37:44 wpaul Exp $ +# $Id: GENERIC,v 1.143.2.16 1999/07/02 04:04:53 jkh Exp $ machine "i386" cpu "I386_CPU" cpu "I486_CPU" cpu "I586_CPU" cpu "I686_CPU" ident GENERIC maxusers 32 options MATH_EMULATE #Support for x87 emulation options INET #InterNETworking options FFS #Berkeley Fast Filesystem options FFS_ROOT #FFS usable as root device [keep this!] options MFS #Memory Filesystem options MFS_ROOT #MFS usable as root device, "MFS" req'ed options NFS #Network Filesystem options NFS_ROOT #NFS usable as root device, "NFS" req'ed options MSDOSFS #MSDOS Filesystem options "CD9660" #ISO 9660 Filesystem options "CD9660_ROOT" #CD-ROM usable as root. "CD9660" req'ed options PROCFS #Process filesystem options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device options UCONSOLE #Allow users to grab the console options FAILSAFE #Be conservative options USERCONFIG #boot -c editor options VISUAL_USERCONFIG #visual boot -c editor config kernel root on wd0 # To make an SMP kernel, the next two are needed #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O # Optionally these may need tweaked, (defaults shown): #options NCPU=2 # number of CPUs #options NBUS=4 # number of busses #options NAPIC=1 # number of IO APICs #options NINTR=24 # number of INTs controller isa0 controller pnp0 controller eisa0 controller pci0 controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 disk fd0 at fdc0 drive 0 disk fd1 at fdc0 drive 1 options "CMD640" # work around CMD640 chip deficiency controller wdc0 at isa? port "IO_WD1" bio irq 14 disk wd0 at wdc0 drive 0 disk wd1 at wdc0 drive 1 controller wdc1 at isa? port "IO_WD2" bio irq 15 disk wd2 at wdc1 drive 0 disk wd3 at wdc1 drive 1 options ATAPI #Enable ATAPI support for IDE bus options ATAPI_STATIC #Don't do it as an LKM device acd0 #IDE CD-ROM device wfd0 #IDE Floppy (e.g. LS-120) # A single entry for any of these controllers (ncr, ahb, ahc) is # sufficient for any number of installed devices. controller ncr0 controller ahb0 controller ahc0 controller isp0 # This controller offers a number of configuration options, too many to # document here - see the LINT file in this directory and look up the # dpt0 entry there for much fuller documentation on this. controller dpt0 controller adv0 at isa? port ? cam irq ? controller adw0 controller bt0 at isa? port ? cam irq ? controller aha0 at isa? port ? cam irq ? controller scbus0 device da0 device sa0 device pass0 device cd0 #Only need one of these, the code dynamically grows device wt0 at isa? port 0x300 bio irq 5 drq 1 device mcd0 at isa? port 0x300 bio irq 10 controller matcd0 at isa? port 0x230 bio device scd0 at isa? port 0x230 bio # atkbdc0 controlls both the keyboard and the PS/2 mouse controller atkbdc0 at isa? port IO_KBD tty device atkbd0 at isa? tty irq 1 device psm0 at isa? tty irq 12 device vga0 at isa? port ? conflicts # splash screen/screen saver pseudo-device splash # syscons is the default console driver, resembling an SCO console device sc0 at isa? tty # Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver #device vt0 at isa? tty #options XSERVER # support for X server #options FAT_CURSOR # start with block cursor # If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines #options PCVT_SCANSET=2 # IBM keyboards are non-std device npx0 at isa? port IO_NPX irq 13 # # Laptop support (see LINT for more options) # device apm0 at isa? disable flags 0x31 # Advanced Power Management # PCCARD (PCMCIA) support #controller card0 #device pcic0 at card? #device pcic1 at card? device sio0 at isa? port "IO_COM1" flags 0x10 tty irq 4 device sio1 at isa? port "IO_COM2" tty irq 3 device sio2 at isa? disable port "IO_COM3" tty irq 5 device sio3 at isa? disable port "IO_COM4" tty irq 9 # Parallel port device ppc0 at isa? port? flags 0x40 net irq 7 controller ppbus0 device lpt0 at ppbus? device plip0 at ppbus? device ppi0 at ppbus? #controller vpo0 at ppbus? # # The following Ethernet NICs are all PCI devices. # device al0 # ADMtek AL981 (``Comet'') device ax0 # ASIX AX88140A device de0 # DEC/Intel DC21x4x (``Tulip'') device fxp0 # Intel EtherExpress PRO/100B (82557, 82558) device mx0 # Macronix 98713/98715/98725 (``PMAC'') device pn0 # Lite-On 82c168/82c169 (``PNIC'') device rl0 # RealTek 8129/8139 +device sf0 # Adaptec AIC-6915 DuraLAN (``Starfire'') device tl0 # Texas Instruments ThunderLAN device tx0 # SMC 9432TX (83c170 ``EPIC'') device vr0 # VIA Rhine, Rhine II device vx0 # 3Com 3c590, 3c595 (``Vortex'') device wb0 # Winbond W89C840F device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'') # Order is important here due to intrusive probes, do *not* alphabetize # this list of network interfaces until the probes have been fixed. # Right now it appears that the ie0 must be probed before ep0. See # revision 1.20 of this file. device ed0 at isa? port 0x280 net irq 10 iomem 0xd8000 device ie0 at isa? port 0x300 net irq 10 iomem 0xd0000 device ep0 at isa? port 0x300 net irq 10 device ex0 at isa? port? net irq? device fe0 at isa? port 0x300 net irq ? device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 device lnc0 at isa? port 0x280 net irq 10 drq 0 #device xe0 at isa? port? net irq ? device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000 device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 device cs0 at isa? port 0x300 net irq ? pseudo-device loop pseudo-device ether pseudo-device sl 1 pseudo-device ppp 1 pseudo-device tun 1 pseudo-device pty 16 pseudo-device gzip # Exec gzipped a.out's # KTRACE enables the system-call tracing facility ktrace(2). # This adds 4 KB bloat to your kernel, and slightly increases # the costs of each syscall. options KTRACE #kernel tracing # This provides support for System V shared memory and message queues. # options SYSVSHM options SYSVMSG options SYSVSEM # The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. The number of devices determines the maximum number of # simultaneous BPF clients programs runnable. #pseudo-device bpfilter 4 #Berkeley packet filter Index: stable/3/sys/i386/conf/LINT =================================================================== --- stable/3/sys/i386/conf/LINT (revision 49544) +++ stable/3/sys/i386/conf/LINT (revision 49545) @@ -1,2129 +1,2144 @@ # # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.539.2.29 1999/06/29 19:10:21 mph Exp $ +# $Id: LINT,v 1.539.2.30 1999/07/03 21:46:18 jdp Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from # this file as required. # # # This directive is mandatory; it defines the architecture to be # configured for; in this case, the 386 family based IBM-PC and # compatibles. # machine "i386" # # This is the ``identification'' of the kernel. Usually this should # be the same as the name of your kernel. # ident LINT # # The `maxusers' parameter controls the static sizing of a number of # internal system tables by a complicated formula defined in param.c. # maxusers 10 # # The `makeoptions' parameter allows variables to be passed to the # generated Makefile in the build area. The following is equivalent # to `config -g KERNELNAME'. # #makeoptions DEBUG="-g" #Build kernel with debug symbols. # # Certain applications can grow to be larger than the 128M limit # that FreeBSD initially imposes. Below are some options to # allow that limit to grow to 256MB, and can be increased further # with changing the parameters. MAXDSIZ is the maximum that the # limit can be set to, and the DFLDSIZ is the default value for # the limit. You might want to set the default lower than the # max, and explicitly set the maximum with a shell command for processes # that regularly exceed the limit like INND. # options "MAXDSIZ=(256*1024*1024)" options "DFLDSIZ=(256*1024*1024)" # When this is set, be extra conservative in various parts of the kernel # and choose functionality over speed (on the widest variety of systems). options FAILSAFE # Options for the VM subsystem #options PQ_NOOPT # No coloring options PQ_LARGECACHE # color for 512k/16k cache #options PQ_HUGECACHE # color for 1024k/16k cache # This allows you to actually store this configuration file into # the kernel binary itself, where it may be later read by saying: # strings -aout -n 3 /kernel | grep ^___ | sed -e 's/^___//' > MYKERNEL # options INCLUDE_CONFIG_FILE # Include this file in kernel # # This directive defines a number of things: # - The compiled kernel is to be called `kernel' # - The root filesystem might be on partition wd0a # - Crash dumps will be written to wd0b, if possible. Specifying the # dump device here is not recommended. Use dumpon(8). # config kernel root on wd0 dumps on wd0 ##################################################################### # SMP OPTIONS: # # SMP enables building of a Symmetric MultiProcessor Kernel. # APIC_IO enables the use of the IO APIC for Symmetric I/O. # NCPU sets the number of CPUs, defaults to 2. # NBUS sets the number of busses, defaults to 4. # NAPIC sets the number of IO APICs on the motherboard, defaults to 1. # NINTR sets the total number of INTs provided by the motherboard. # # Notes: # # An SMP kernel will ONLY run on an Intel MP spec. qualified motherboard. # # Be sure to disable 'cpu "I386_CPU"' && 'cpu "I486_CPU"' for SMP kernels. # # Check the 'Rogue SMP hardware' section to see if additional options # are required by your hardware. # # Mandatory: options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O # Optional, these are the defaults plus 1: options NCPU=5 # number of CPUs options NBUS=5 # number of busses options NAPIC=2 # number of IO APICs options NINTR=25 # number of INTs # # Rogue SMP hardware: # # Bridged PCI cards: # # The MP tables of most of the current generation MP motherboards # do NOT properly support bridged PCI cards. To use one of these # cards you should refer to ??? ##################################################################### # CPU OPTIONS # # You must specify at least one CPU (the one you intend to run on); # deleting the specification for CPUs you don't need to use may make # parts of the system run faster. This is especially true removing # I386_CPU. # cpu "I386_CPU" cpu "I486_CPU" cpu "I586_CPU" # aka Pentium(tm) cpu "I686_CPU" # aka Pentium Pro(tm) # # Options for CPU features. # # CPU_BLUELIGHTNING_FPU_OP_CACHE enables FPU operand cache on IBM # BlueLightning CPU. It works only with Cyrix FPU, and this option # should not be used with Intel FPU. # # CPU_BLUELIGHTNING_3X enables triple-clock mode on IBM Blue Lightning # CPU if CPU supports it. The default is double-clock mode on # BlueLightning CPU box. # # CPU_BTB_EN enables branch target buffer on Cyrix 5x86 (NOTE 1). # # CPU_DIRECT_MAPPED_CACHE sets L1 cache of Cyrix 486DLC CPU in direct # mapped mode. Default is 2-way set associative mode. # # CPU_CYRIX_NO_LOCK enables weak locking for the entire address space # of Cyrix 6x86 and 6x86MX CPUs. If this option is not set and # FAILESAFE is defined, NO_LOCK bit of CCR1 is cleared. (NOTE 3) # # CPU_DISABLE_5X86_LSSER disables load store serialize (i.e. enables # reorder). This option should not be used if you use memory mapped # I/O device(s). # # CPU_FASTER_5X86_FPU enables faster FPU exception handler. # # CPU_I486_ON_386 enables CPU cache on i486 based CPU upgrade products # for i386 machines. # # CPU_IORT defines I/O clock delay time (NOTE 1). Default vaules of # I/O clock delay time on Cyrix 5x86 and 6x86 are 0 and 7,respectively # (no clock delay). # # CPU_LOOP_EN prevents flushing the prefetch buffer if the destination # of a jump is already present in the prefetch buffer on Cyrix 5x86(NOTE # 1). # # CPU_RSTK_EN enables return stack on Cyrix 5x86 (NOTE 1). # # CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU # enters suspend mode following execution of HALT instruction. # # CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD # K5/K6/K6-2 cpus. # # CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache # flush at hold state. # # CYRIX_CACHE_REALLY_WORKS enables (1) CPU cache on Cyrix 486 CPUs # without cache flush at hold state, and (2) write-back CPU cache on # Cyrix 6x86 whose revision < 2.7 (NOTE 2). # # NO_F00F_HACK disables the hack that prevents Pentiums (and ONLY # Pentiums) from locking up when a LOCK CMPXCHG8B instruction is # executed. This should be included for ALL kernels that won't run # on a Pentium. # # NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors # which indicates that the 15-16MB range is *definitely* not being # occupied by an ISA memory hole. # # NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT, # CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs. # These options may crash your system. # # NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled # in write-through mode when revision < 2.7. If revision of Cyrix # 6x86 >= 2.7, CPU cache is always enabled in write-back mode. # # NOTE 3: This option may cause failures for software that requires # locked cycles in order to operate correctly. # options "CPU_BLUELIGHTNING_FPU_OP_CACHE" options "CPU_BLUELIGHTNING_3X" options "CPU_BTB_EN" options "CPU_DIRECT_MAPPED_CACHE" options "CPU_DISABLE_5X86_LSSER" options "CPU_FASTER_5X86_FPU" options "CPU_I486_ON_386" options "CPU_IORT" options "CPU_LOOP_EN" options "CPU_RSTK_EN" options "CPU_SUSP_HLT" options "CPU_WT_ALLOC" options "CYRIX_CACHE_WORKS" options "CYRIX_CACHE_REALLY_WORKS" #options "NO_F00F_HACK" # # A math emulator is mandatory if you wish to run on hardware which # does not have a floating-point processor. Pick either the original, # bogus (but freely-distributable) math emulator, or a much more # fully-featured but GPL-licensed emulator taken from Linux. # options MATH_EMULATE #Support for x87 emulation # Don't enable both of these in a real config. options GPL_MATH_EMULATE #Support for x87 emulation via #new math emulator ##################################################################### # COMPATIBILITY OPTIONS # # Implement system calls compatible with 4.3BSD and older versions of # FreeBSD. You probably do NOT want to remove this as much current code # still relies on the 4.3 emulation. # options "COMPAT_43" # # Statically compile in the i386 a.out LKM compatability support. # Also available as an KLD module. # options LKM # # Allow user-mode programs to manipulate their local descriptor tables. # This option is required for the WINE Windows(tm) emulator, and is # not used by anything else (that we know of). # options USER_LDT #allow user-level control of i386 ldt # # These three options provide support for System V Interface # Definition-style interprocess communication, in the form of shared # memory, semaphores, and message queues, respectively. # options SYSVSHM options SYSVSEM options SYSVMSG # # This option includes a MD5 routine in the kernel, this is used for # various authentication and privacy uses. # options "MD5" # # Allow processes to switch to vm86 mode, as well as enabling direct # user-mode access to the I/O port space. This option is necessary for # the doscmd emulator to run and the VESA modes in syscons to be available. # options "VM86" ##################################################################### # DEBUGGING OPTIONS # # Enable the kernel debugger. # options DDB # # Don't drop into DDB for a panic. Intended for unattended operation # where you may want to drop to DDB from the console, but still want # the machine to recover from a panic # options DDB_UNATTENDED # # If using GDB remote mode to debug the kernel, there's a non-standard # extension to the remote protocol that can be used to use the serial # port as both the debugging port and the system console. It's non- # standard and you're on your own if you enable it. See also the # "remotechat" variables in the FreeBSD specific version of gdb. # options GDB_REMOTE_CHAT # # KTRACE enables the system-call tracing facility ktrace(2). # options KTRACE #kernel tracing # # The INVARIANTS option is used in a number of source files to enable # extra sanity checking of internal structures. This support is not # enabled by default because of the extra time it would take to check # for these conditions, which can only occur as a result of # programming errors. # options INVARIANTS # # The INVARIANT_SUPPORT option makes us compile in support for # verifying some of the internal structures. It is a prerequisite for # 'INVARIANTS', as enabling 'INVARIANTS' will make these functions be # called. The intent is that you can set 'INVARIANTS' for single # source files (by changing the source file or specifying it on the # command line) if you have 'INVARIANT_SUPPORT' enabled. # options INVARIANT_SUPPORT # # The DIAGNOSTIC option is used to enable extra debugging information # from some parts of the kernel. As this makes everything more noisy, # it is disabled by default. # options DIAGNOSTIC # # PERFMON causes the driver for Pentium/Pentium Pro performance counters # to be compiled. See perfmon(4) for more information. # options PERFMON # # This option let some drivers co-exist that can't co-exist in a running # system. This is used to be able to compile all kernel code in one go for # quality assurance purposes (like this file, which the option takes it name # from.) # options COMPILING_LINT # XXX - this doesn't belong here. # Allow ordinary users to take the console - this is useful for X. options UCONSOLE # XXX - this doesn't belong here either options USERCONFIG #boot -c editor options INTRO_USERCONFIG #imply -c and show intro screen options VISUAL_USERCONFIG #visual boot -c editor ##################################################################### # NETWORKING OPTIONS # # Protocol families: # Only the INET (Internet) family is officially supported in FreeBSD. # Source code for the NS (Xerox Network Service) is provided for amusement # value. # options INET #Internet communications protocols options IPX #IPX/SPX communications protocols options IPXIP #IPX in IP encapsulation (not available) options IPTUNNEL #IP in IPX encapsulation (not available) options NETATALK #Appletalk communications protocols # These are currently broken but are shipped due to interest. #options NS #Xerox NS protocols # These are currently broken and are no longer shipped due to lack # of interest. #options CCITT #X.25 network layer #options ISO #options TPIP #ISO TP class 4 over IP #options TPCONS #ISO TP class 0 over X.25 #options LLC #X.25 link layer for Ethernets #options HDLC #X.25 link layer for serial lines #options EON #ISO CLNP over IP #options NSIP #XNS over IP # # Network interfaces: # The `loop' pseudo-device is MANDATORY when networking is enabled. # The `ether' pseudo-device provides generic code to handle # Ethernets; it is MANDATORY when a Ethernet device driver or a # Token-ring device driver is configured. # The 'fddi' pseudo-device provides generic code to support FDDI. # The `sppp' pseudo-device serves a similar role for certain types # of synchronous PPP links (like `cx', `ar'). # The `sl' pseudo-device implements the Serial Line IP (SLIP) service. # The `ppp' pseudo-device implements the Point-to-Point Protocol. # The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. The number of devices determines the maximum number of # simultaneous BPF clients programs runnable. # The `disc' pseudo-device implements a minimal network interface, # which throws away all packets sent and never receives any. It is # included for testing purposes. # The `tun' pseudo-device implements the User Process PPP (iijppp) # # The PPP_BSDCOMP option enables support for compress(1) style entire # packet compression, the PPP_DEFLATE is for zlib/gzip style compression. # PPP_FILTER enables code for filtering the ppp data stream and selecting # events for resetting the demand dial activity timer - requires bpfilter. # See pppd(8) for more details. # pseudo-device ether #Generic Ethernet pseudo-device token #Generic TokenRing pseudo-device fddi #Generic FDDI pseudo-device sppp #Generic Synchronous PPP pseudo-device loop #Network loopback device pseudo-device bpfilter 4 #Berkeley packet filter pseudo-device disc #Discard device pseudo-device tun 1 #Tunnel driver (user process ppp(8)) pseudo-device sl 2 #Serial Line IP pseudo-device ppp 2 #Point-to-point protocol options PPP_BSDCOMP #PPP BSD-compress support options PPP_DEFLATE #PPP zlib/deflate/gzip support options PPP_FILTER #enable bpf filtering (needs bpfilter) # # Internet family options: # # TCP_COMPAT_42 causes the TCP code to emulate certain bugs present in # 4.2BSD. This option should not be used unless you have a 4.2BSD # machine and TCP connections fail. # # MROUTING enables the kernel multicast packet forwarder, which works # with mrouted(8). # # IPFIREWALL enables support for IP firewall construction, in # conjunction with the `ipfw' program. IPFIREWALL_VERBOSE sends # logged packets to the system logger. IPFIREWALL_VERBOSE_LIMIT # limits the number of times a matching entry can be logged. # # WARNING: IPFIREWALL defaults to a policy of "deny ip from any to any" # and if you do not add other rules during startup to allow access, # YOU WILL LOCK YOURSELF OUT. It is suggested that you set firewall=open # in /etc/rc.conf when first enabling this feature, then refining the # firewall rules in /etc/rc.firewall after you've tested that the new kernel # feature works properly. # # IPFIREWALL_DEFAULT_TO_ACCEPT causes the default rule (at boot) to # allow everything. Use with care, if a cracker can crash your # firewall machine, they can get to your protected machines. However, # if you are using it as an as-needed filter for specific problems as # they arise, then this may be for you. Changing the default to 'allow' # means that you won't get stuck if the kernel and /sbin/ipfw binary get # out of sync. # # IPDIVERT enables the divert IP sockets, used by ``ipfw divert'' # # IPFILTER enables Darren Reed's ipfilter package. # IPFILTER_LOG enables ipfilter's logging. # IPFILTER_LKM enables LKM support for an ipfilter module (untested). # # TCPDEBUG is undocumented. # options "TCP_COMPAT_42" #emulate 4.2BSD TCP bugs options MROUTING # Multicast routing options IPFIREWALL #firewall options IPFIREWALL_VERBOSE #print information about # dropped packets options IPFIREWALL_FORWARD #enable transparent proxy support options "IPFIREWALL_VERBOSE_LIMIT=100" #limit verbosity options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default options IPDIVERT #divert sockets options IPFILTER #kernel ipfilter support options IPFILTER_LOG #ipfilter logging #options IPFILTER_LKM #kernel support for ip_fil.o LKM options TCPDEBUG # ICMP_BANDLIM enables icmp error response bandwidth limiting. You # typically want this option as it will help protect the machine from # D.O.S. packet attacks. # options "ICMP_BANDLIM" # DUMMYNET enables the "dummynet" bandwidth limiter. You need # IPFIREWALL as well. See the dummynet(4) manpage for more info. # BRIDGE enables bridging between ethernet cards -- see bridge(4). # You can use IPFIREWALL and dummynet together with bridging. options DUMMYNET options BRIDGE # # ATM (HARP version) options # # ATM_CORE includes the base ATM functionality code. This must be included # for ATM support. # # ATM_IP includes support for running IP over ATM. # # At least one (and usually only one) of the following signalling managers # must be included (note that all signalling managers include PVC support): # ATM_SIGPVC includes support for the PVC-only signalling manager `sigpvc'. # ATM_SPANS includes support for the `spans' signalling manager, which runs # the FORE Systems's proprietary SPANS signalling protocol. # ATM_UNI includes support for the `uni30' and `uni31' signalling managers, # which run the ATM Forum UNI 3.x signalling protocols. # # The `hea' driver provides support for the Efficient Networks, Inc. # ENI-155p ATM PCI Adapter. # # The `hfa' driver provides support for the FORE Systems, Inc. # PCA-200E ATM PCI Adapter. # options ATM_CORE #core ATM protocol family options ATM_IP #IP over ATM support options ATM_SIGPVC #SIGPVC signalling manager options ATM_SPANS #SPANS signalling manager options ATM_UNI #UNI signalling manager device hea0 #Efficient ENI-155p ATM PCI device hfa0 #FORE PCA-200E ATM PCI ##################################################################### # FILESYSTEM OPTIONS # # Only the root, /usr, and /tmp filesystems need be statically # compiled; everything else will be automatically loaded at mount # time. (Exception: the UFS family---FFS, and MFS --- cannot # currently be demand-loaded.) Some people still prefer to statically # compile other filesystems as well. # # NB: The NULL, PORTAL, UMAP and UNION filesystems are known to be # buggy, and WILL panic your system if you attempt to do anything with # them. They are included here as an incentive for some enterprising # soul to sit down and fix them. # # One of these is mandatory: options FFS #Fast filesystem options MFS #Memory File System options NFS #Network File System # The rest are optional: # options NFS_NOSERVER #Disable the NFS-server code. options "CD9660" #ISO 9660 filesystem options FDESC #File descriptor filesystem options KERNFS #Kernel filesystem options MSDOSFS #MS DOS File System options NTFS #NT File System options NULLFS #NULL filesystem options PORTAL #Portal filesystem options PROCFS #Process filesystem options UMAPFS #UID map filesystem options UNION #Union filesystem # The xFS_ROOT options REQUIRE the associated ``options xFS'' options "CD9660_ROOT" #CD-ROM usable as root device options FFS_ROOT #FFS usable as root device options MFS_ROOT #MFS usable as root device options NFS_ROOT #NFS usable as root device # This code is still experimental (e.g. doesn't handle disk slices well). # Also, 'options MFS' is currently incompatible with DEVFS. options DEVFS #devices filesystem # Soft updates is technique for improving file system speed and # making abrupt shutdown less risky. It is not enabled by default due # to copyright restraints on the code that implement it. # # Read ../../ufs/ffs/README.softupdates to learn what you need to # do to enable this. ../../contrib/softupdates/README gives # more details on how they actually work. # #options SOFTUPDATES # Make space in the kernel for a MFS root filesystem. Define to the number # of kilobytes to reserve for the filesystem. options MFS_ROOT_SIZE=10 # Allows MFS filesystems to be exported via nfs options EXPORTMFS # Allow this many swap-devices. options NSWAPDEV=20 # Disk quotas are supported when this option is enabled. If you # change the value of this option, you must do a `make clean' in your # kernel compile directory in order to get a working kernel. # options QUOTA #enable disk quotas # Add more checking code to various filesystems #options NULLFS_DIAGNOSTIC #options KERNFS_DIAGNOSTIC #options UMAPFS_DIAGNOSTIC #options UNION_DIAGNOSTIC # In particular multi-session CD-Rs might require a huge amount of # time in order to "settle". If we are about mounting them as the # root f/s, we gotta wait a little. # # The number is supposed to be in seconds. options "CD9660_ROOTDELAY=20" # If you are running a machine just as a fileserver for PC and MAC # users, using SAMBA or Netatalk, you may consider setting this option # and keeping all those users' directories on a filesystem that is # mounted with the suiddir option. This gives new files the same # ownership as the directory (similiar to group). It's a security hole # if you let these users run programs, so confine it to file-servers # (but it'll save you lots of headaches in those cases). Root owned # directories are exempt and X bits are cleared. The suid bit must be # set on the directory as well; see chmod(1) PC owners can't see/set # ownerships so they keep getting their toes trodden on. This saves # you all the support calls as the filesystem it's used on will act as # they expect: "It's my dir so it must be my file". # options SUIDDIR # Add some error checking code to the null_bypass routine # in the NULL filesystem #options SAFETY # NFS options: options "NFS_MINATTRTIMO=3" # VREG attrib cache timeout in sec options "NFS_MAXATTRTIMO=60" options "NFS_MINDIRATTRTIMO=30" # VDIR attrib cache timeout in sec options "NFS_MAXDIRATTRTIMO=60" options "NFS_GATHERDELAY=10" # Default write gather delay (msec) options "NFS_UIDHASHSIZ=29" # Tune the size of nfssvc_sock with this options "NFS_WDELAYHASHSIZ=16" # and with this options "NFS_MUIDHASHSIZ=63" # Tune the size of nfsmount with this options NFS_DEBUG # Enable NFS Debugging # Coda stuff: options CODA #CODA filesystem. pseudo-device vcoda 4 #coda minicache <-> venus comm. ##################################################################### # POSIX P1003.1B # Real time extensions added int the 1993 Posix # P1003_1B: Infrastructure # _KPOSIX_PRIORITY_SCHEDULING: Build in _POSIX_PRIORITY_SCHEDULING # _KPOSIX_VERSION: Version kernel is built for options "P1003_1B" options "_KPOSIX_PRIORITY_SCHEDULING" options "_KPOSIX_VERSION=199309L" ##################################################################### # SCSI DEVICES # SCSI DEVICE CONFIGURATION # The SCSI subsystem consists of the `base' SCSI code, a number of # high-level SCSI device `type' drivers, and the low-level host-adapter # device drivers. The host adapters are listed in the ISA and PCI # device configuration sections below. # # Beginning with FreeBSD 2.0.5 you can wire down your SCSI devices so # that a given bus, target, and LUN always come on line as the same # device unit. In earlier versions the unit numbers were assigned # in the order that the devices were probed on the SCSI bus. This # means that if you removed a disk drive, you may have had to rewrite # your /etc/fstab file, and also that you had to be careful when adding # a new disk as it may have been probed earlier and moved your device # configuration around. # This old behavior is maintained as the default behavior. The unit # assignment begins with the first non-wired down unit for a device # type. For example, if you wire a disk as "da3" then the first # non-wired disk will be assigned da4. # The syntax for wiring down devices is: # controller scbus0 at ahc0 # Single bus device # controller scbus1 at ahc1 bus 0 # Single bus device # controller scbus3 at ahc2 bus 0 # Twin bus device # controller scbus2 at ahc2 bus 1 # Twin bus device # disk da0 at scbus0 target 0 unit 0 # disk da1 at scbus3 target 1 # disk da2 at scbus2 target 3 # tape sa1 at scbus1 target 6 # device cd0 at scbus? # "units" (SCSI logical unit number) that are not specified are # treated as if specified as LUN 0. # All SCSI devices allocate as many units as are required. # The "unknown" device (uk? in pre-2.0.5) is now part of the base SCSI # configuration and doesn't have to be explicitly configured. controller scbus0 #base SCSI code device ch0 #SCSI media changers device da0 #SCSI direct access devices (aka disks) device sa0 #SCSI tapes device cd0 #SCSI CD-ROMs #device od0 #SCSI optical disk device pass0 #CAM passthrough driver # The previous devices (ch, da, st, cd) are recognized by config. # config doesn't (and shouldn't) know about these newer ones, # so we have to specify that they are on a SCSI bus with the "at scbus?" # clause. device pt0 at scbus? # SCSI processor type device sctarg0 at scbus? # SCSI target # CAM OPTIONS: # debugging options: # -- NOTE -- If you specify one of the bus/target/lun options, you must # specify them all! # CAMDEBUG: When defined enables debugging macros # CAM_DEBUG_BUS: Debug the given bus. Use -1 to debug all busses. # CAM_DEBUG_TARGET: Debug the given target. Use -1 to debug all targets. # CAM_DEBUG_LUN: Debug the given lun. Use -1 to debug all luns. # CAM_DEBUG_FLAGS: OR together CAM_DEBUG_INFO, CAM_DEBUG_TRACE, # CAM_DEBUG_SUBTRACE, and CAM_DEBUG_CDB # # CAM_MAX_HIGHPOWER: Maximum number of concurrent high power (start unit) cmds # SCSI_NO_SENSE_STRINGS: When defined disables sense descriptions # SCSI_NO_OP_STRINGS: When defined disables opcode descriptions # SCSI_REPORT_GEOMETRY: Always report disk geometry at boot up instead # of only when booting verbosely. # SCSI_DELAY: The number of MILLISECONDS to freeze the SIM (scsi adapter) # queue after a bus reset, and the number of milliseconds to # freeze the device queue after a bus device reset. options CAMDEBUG options "CAM_DEBUG_BUS=-1" options "CAM_DEBUG_TARGET=-1" options "CAM_DEBUG_LUN=-1" options "CAM_DEBUG_FLAGS=CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB" options "CAM_MAX_HIGHPOWER=4" options SCSI_NO_SENSE_STRINGS options SCSI_NO_OP_STRINGS options SCSI_REPORT_GEOMETRY options SCSI_DELAY=8000 # Be pessimistic about Joe SCSI device # Options for the CAM CDROM driver: # CHANGER_MIN_BUSY_SECONDS: Guaranteed minimum time quantum for a changer LUN # CHANGER_MAX_BUSY_SECONDS: Maximum time quantum per changer LUN, only # enforced if there is I/O waiting for another LUN # The compiled in defaults for these variables are 2 and 10 seconds, # respectively. # # These can also be changed on the fly with the following sysctl variables: # kern.cam.cd.changer.min_busy_seconds # kern.cam.cd.changer.max_busy_seconds # options "CHANGER_MIN_BUSY_SECONDS=2" options "CHANGER_MAX_BUSY_SECONDS=10" # Options for the CAM sequential access driver: # SA_SPACE_TIMEOUT: Timeout for space operations, in minutes # SA_REWIND_TIMEOUT: Timeout for rewind operations, in minutes # SA_ERASE_TIMEOUT: Timeout for erase operations, in minutes options "SA_SPACE_TIMEOUT=(60)" options "SA_REWIND_TIMEOUT=(2*60)" options "SA_ERASE_TIMEOUT=(4*60)" ##################################################################### # MISCELLANEOUS DEVICES AND OPTIONS # The `pty' device usually turns out to be ``effectively mandatory'', # as it is required for `telnetd', `rlogind', `screen', `emacs', and # `xterm', among others. pseudo-device pty 16 #Pseudo ttys - can go as high as 256 pseudo-device speaker #Play IBM BASIC-style noises out your speaker pseudo-device gzip #Exec gzipped a.out's pseudo-device vn #Vnode driver (turns a file into a device) pseudo-device snp 3 #Snoop device - to look at pty/vty/etc.. pseudo-device ccd 4 #Concatenated disk driver pseudo-device vinum #Vinum concat/mirror/raid driver options VINUMDEBUG #enable Vinum debugging hooks # These are only for watching for bitrot in old tty code. # broken #pseudo-device tb # Size of the kernel message buffer. Should be N * pagesize. options "MSGBUF_SIZE=40960" ##################################################################### # HARDWARE DEVICE CONFIGURATION # ISA and EISA devices: # EISA support is available for some device, so they can be auto-probed. # Micro Channel is not supported at all. # # Mandatory ISA devices: isa, npx # controller isa0 # # Options for `isa': # # AUTO_EOI_1 enables the `automatic EOI' feature for the master 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # This option breaks suspend/resume on some portables. # # AUTO_EOI_2 enables the `automatic EOI' feature for the slave 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # Automatic EOI is documented not to work for for the slave with the # original i8259A, but it works for some clones and some integrated # versions. # # MAXMEM specifies the amount of RAM on the machine; if this is not # specified, FreeBSD will first read the amount of memory from the CMOS # RAM, so the amount of memory will initially be limited to 64MB or 16MB # depending on the BIOS. If the BIOS reports 64MB, a memory probe will # then attempt to detect the installed amount of RAM. If this probe # fails to detect >64MB RAM you will have to use the MAXMEM option. # The amount is in kilobytes, so for a machine with 128MB of RAM, it would # be 131072 (128 * 1024). # # TUNE_1542 enables the automatic ISA bus speed selection for the # Adaptec 1542 boards. Does not work for all boards, use it with caution. # # BROKEN_KEYBOARD_RESET disables the use of the keyboard controller to # reset the CPU for reboot. This is needed on some systems with broken # keyboard controllers. # # PAS_JOYSTICK_ENABLE enables the gameport on the ProAudio Spectrum options "AUTO_EOI_1" #options "AUTO_EOI_2" options "MAXMEM=(128*1024)" options "TUNE_1542" #options BROKEN_KEYBOARD_RESET #options PAS_JOYSTICK_ENABLE # Enable support for the kernel PLL to use an external PPS signal, # under supervision of [x]ntpd(8) # More info in ftp://ftp.udel.edu/pub/ntp/kernel.tar.Z options PPS_SYNC # If you see the "calcru: negative time of %ld usec for pid %d (%s)\n" # message you probably have some broken sw/hw which disables interrupts # for too long. You can make the system more resistant to this by # choosing a high value for NTIMECOUNTER. The default is 5, there # is no upper limit but more than a couple of hundred are not productive. options "NTIMECOUNTER=20" # Enable PnP support in the kernel. This allows you to automaticly # attach to PnP cards for drivers that support it and allows you to # configure cards from USERCONFIG. See pnp(4) for more info. controller pnp0 # The keyboard controller; it controlls the keyboard and the PS/2 mouse. controller atkbdc0 at isa? port IO_KBD tty # The AT keyboard device atkbd0 at isa? tty irq 1 # Options for atkbd: options ATKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions ATKBD_DFLT_KEYMAP="jp.106" # These options are valid for other keyboard drivers as well. options KBD_DISABLE_KEYMAP_LOAD # refuse to load a keymap options KBD_INSTALL_CDEV # install a CDEV entry in /dev # `flags' for atkbd: # 0x01 Force detection of keyboard, else we always assume a keyboard # 0x02 Don't reset keyboard, useful for some newer ThinkPads # 0x04 Old-style (XT) keyboard support, useful for older ThinkPads # PS/2 mouse device psm0 at isa? tty irq 12 # Options for psm: options PSM_HOOKAPM #hook the APM resume event, useful #for some laptops options PSM_RESETAFTERSUSPEND #reset the device at the resume event # The video card driver. device vga0 at isa? port ? conflicts # Options for vga: # Try the following option if the mouse pointer is not drawn correctly # or font does not seem to be loaded properly. May cause flicker on # some systems. options VGA_ALT_SEQACCESS # If you can dispense with some vga driver features, you may want to # use the following options to save some memory. options VGA_NO_FONT_LOADING # don't save/load font options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs # To include support for VESA video modes options VESA # needs VM86 defined too!! # Splash screen at start up! Screen savers require this too. pseudo-device splash # The pcvt console driver (vt220 compatible). device vt0 at isa? tty options XSERVER # support for running an X server. options FAT_CURSOR # start with block cursor # This PCVT option is for keyboards such as those used on IBM ThinkPad laptops options PCVT_SCANSET=2 # IBM keyboards are non-std # The syscons console driver (sco color console compatible). device sc0 at isa? tty options MAXCONS=16 # number of virtual consoles options "STD8X16FONT" # Compile font in makeoptions "STD8X16FONT"="cp850" options SC_HISTORY_SIZE=200 # number of history buffer lines options SC_DISABLE_REBOOT # disable reboot key sequence # # `flags' for sc0: # 0x01 Use a 'visual' bell # 0x02 Use a 'blink' cursor # 0x04 Use a 'underline' cursor # 0x06 Use a 'blinking underline' (destructive) cursor # 0x40 Make the bell quiet if it is rung in the backgroud vty. # # The Numeric Processing eXtension driver. This should be configured if # your machine has a math co-processor, unless the coprocessor is very # buggy. If it is not configured then you *must* configure math emulation # (see above). If both npx0 and emulation are configured, then only npx0 # is used (provided it works). device npx0 at isa? port IO_NPX iosiz 0x0 flags 0x0 irq 13 # # `flags' for npx0: # 0x01 don't use the npx registers to optimize bcopy # 0x02 don't use the npx registers to optimize bzero # 0x04 don't use the npx registers to optimize copyin or copyout. # The npx registers are normally used to optimize copying and zeroing when # all of the following conditions are satisfied: # "I586_CPU" is an option # the cpu is an i586 (perhaps not a Pentium) # the probe for npx0 succeeds # INT 16 exception handling works. # Then copying and zeroing using the npx registers is normally 30-100% faster. # The flags can be used to control cases where it doesn't work or is slower. # Setting them at boot time using userconfig works right (the optimizations # are not used until later in the bootstrap when npx0 is attached). # # # `iosiz' for npx0: # This can be used instead of the MAXMEM option to set the memory size. If # it is nonzero, then it overrides both the MAXMEM option and the memory # size reported by the BIOS. Setting it at boot time using userconfig takes # effect on the next reboot after the change has been recorded in the kernel # binary (the size is used early in the boot before userconfig has a chance # to change it). # # # Optional ISA and EISA devices: # # # SCSI host adapters: `aha', `bt' # # adv: All Narrow SCSI bus AdvanSys controllers. # adw: Second Generation AdvanSys controllers including the ADV940UW. # aha: Adaptec 154x # ahc: Adaptec 274x/284x/294x # bt: Most Buslogic controllers # # Note that the order is important in order for Buslogic cards to be # probed correctly. # controller bt0 at isa? port "IO_BT0" cam irq ? controller adv0 at isa? port ? cam irq ? controller adw0 controller aha0 at isa? port ? cam irq ? # # ST-506, ESDI, and IDE hard disks: `wdc' and `wd' # # The flags fields are used to enable the multi-sector I/O and # the 32BIT I/O modes. The flags may be used in either the controller # definition or in the individual disk definitions. The controller # definition is supported for the boot configuration stuff. # # Each drive has a 16 bit flags value defined: # The low 8 bits are the maximum value for the multi-sector I/O, # where 0xff defaults to the maximum that the drive can handle. # The high bit of the 16 bit flags (0x8000) allows probing for # 32 bit transfers. Bit 14 (0x4000) enables a hack to wake # up powered-down laptop drives. Bit 13 (0x2000) allows # probing for PCI IDE DMA controllers, such as Intel's PIIX # south bridges. Bit 12 (0x1000) sets LBA mode instead of the # default CHS mode for accessing the drive. See the wd.4 man page. # # The flags field for the drives can be specified in the controller # specification with the low 16 bits for drive 0, and the high 16 bits # for drive 1. # e.g.: #controller wdc0 at isa? port "IO_WD1" bio irq 14 flags 0x00ff8004 # # specifies that drive 0 will be allowed to probe for 32 bit transfers and # a maximum multi-sector transfer of 4 sectors, and drive 1 will not be # allowed to probe for 32 bit transfers, but will allow multi-sector # transfers up to the maximum that the drive supports. # # If you are using a PCI controller that is not running in compatibility # mode (for example, it is a 2nd IDE PCI interface), then use config line(s) # such as: # #controller wdc2 at isa? port "0" bio irq ? flags 0xa0ffa0ff #disk wd4 at wdc2 drive 0 #disk wd5 at wdc2 drive 1 # #controller wdc3 at isa? port "0" bio irq ? flags 0xa0ffa0ff #disk wd6 at wdc3 drive 0 #disk wd7 at wdc3 drive 1 # # Note that the above config would be useful for a Promise card, when used # on a MB that already has a PIIX controller. Note the bogus irq and port # entries. These are automatically filled in by the IDE/PCI support. # controller wdc0 at isa? port "IO_WD1" bio irq 14 disk wd0 at wdc0 drive 0 disk wd1 at wdc0 drive 1 controller wdc1 at isa? port "IO_WD2" bio irq 15 disk wd2 at wdc1 drive 0 disk wd3 at wdc1 drive 1 # # Options for `wdc': # # CMD640 enables serializing access to primary and secondary channel # of the CMD640B IDE Chip. The serializing will only take place # if this option is set *and* the chip is probed by the pci-system. # options "CMD640" #Enable work around for CMD640 h/w bug # # ATAPI enables the support for ATAPI-compatible IDE devices # options ATAPI #Enable ATAPI support for IDE bus options ATAPI_STATIC #Don't do it as an LKM # # This option allow you to override the default probe time for IDE # devices, to get a faster probe. Setting this below 10000 violate # the IDE specs, but may still work for you (it will work for most # people). # options IDE_DELAY=8000 # Be optimistic about Joe IDE device # IDE CD-ROM & CD-R/RW driver - requires wdc controller and ATAPI option device acd0 # IDE floppy driver - requires wdc controller and ATAPI option device wfd0 # IDE tape driver - requires wdc controller and ATAPI option device wst0 # # Compaq Intelligent Disk Array Controller # controller ida0 at isa? bio irq ? vector idaintr disk id0 at ida0 drive 0 disk id1 at ida0 drive 1 disk id2 at ida0 drive 2 disk id3 at ida0 drive 3 # Warning: # This driver can be configured to steal the ide devsw[] entries # so the IDE driver must also be present. If this behaviour is used, # the system will be unable to get to IDE drives. This is to allow # systems to boot off the IDA array, while thinking they are booting off # an IDE drive. (The boot blocks only know about IDE and SCSI). # # To disable this behaviour, the following line should be used. # Do this is you wish to boot of a different device. #options IDA_CUCKOO_MODE=0 # # Standard floppy disk controllers and floppy tapes: `fdc', `fd', and `ft' # controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 # # FDC_DEBUG enables floppy debugging. Since the debug output is huge, you # gotta turn it actually on by setting the variable fd_debug with DDB, # however. options FDC_DEBUG # FDC_YE enables support for the floppies used on the Libretto. This is a # pcmcia floppy. You will also need to add #card "Y-E DATA" "External FDD" # config 0x4 "fdc0" 10 # to your pccard.conf file. options FDC_YE # This option is undocumented on purpose. options FDC_PRINT_BOGUS_CHIPTYPE # # Activate this line instead of the fdc0 line above if you happen to # have an Insight floppy tape. Probing them proved to be dangerous # for people with floppy disks only, so it's "hidden" behind a flag: #controller fdc0 at isa? port "IO_FD1" bio flags 1 irq 6 drq 2 disk fd0 at fdc0 drive 0 disk fd1 at fdc0 drive 1 # # Other standard PC hardware: `olpt', `mse', `sio', etc. # # olpt: printer port (deprecated, use ppbus instead) # olpt specials: # The port may be specified as ?. This will cause the # driver to scan the BIOS port list. # The irq clause may be omitted. This will force the port # into polling mode. # mse: Logitech and ATI InPort bus mouse ports # sio: serial ports (see sio(4)) device olpt0 at isa? port? tty irq 7 device olpt1 at isa? port "IO_LPT3" tty irq 5 device mse0 at isa? port 0x23c tty irq 5 device sio0 at isa? port "IO_COM1" tty flags 0x10 irq 4 # # `flags' for serial drivers that support consoles (only for sio now): # 0x10 enable console support for this unit. The other console flags # are ignored unless this is set. Enabling console support does # not make the unit the preferred console - boot with -h or set # the 0x20 flag for that. Currently, at most one unit can have # console support; the first one (in config file order) with # this flag set is preferred. Setting this flag for sio0 gives # the old behaviour. # 0x20 force this unit to be the console (unless there is another # higher priority console). This replaces the COMCONSOLE option. # 0x40 reserve this unit for low level console operations. Do not # access the device in any normal way. # # PnP `flags' (set via userconfig using pnp x flags y) # 0x1 disable probing of this device. Used to prevent your modem # from being attached as a PnP modem. # # Options for serial drivers that support consoles (only for sio now): options BREAK_TO_DEBUGGER #a BREAK on a comconsole goes to #DDB, if available. options CONSPEED=9600 #default speed for serial console (default 9600) # Options for sio: options COM_ESP #code for Hayes ESP options COM_MULTIPORT #code for some cards with shared IRQs options "EXTRA_SIO=2" #number of extra sio ports to allocate # Other flags for sio that aren't documented in the man page. # 0x20000 enable hardware RTS/CTS and larger FIFOs. Only works for # ST16650A-compatible UARTs. # # Network interfaces: `cx', `ed', `el', `ep', `ie', `is', `le', `lnc' # # ar: Arnet SYNC/570i hdlc sync 2/4 port V.35/X.21 serial driver (requires sppp) # cs: IBM Etherjet and other Crystal Semi CS89x0-based adapters # cx: Cronyx/Sigma multiport sync/async (with Cisco or PPP framing) # ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503 # el: 3Com 3C501 (slow!) # ep: 3Com 3C509 (buggy) # ex: Intel EtherExpress Pro/10 and other i82595-based adapters # fe: Fujitsu MB86960A/MB86965A Ethernet # ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210; Intel EtherExpress # le: Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100, # DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422) # lnc: Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL, AMD Am7990 & Am79C960) # rdp: RealTek RTL 8002-based pocket ethernet adapters # sr: RISCom/N2 hdlc sync 1/2 port V.35/X.21 serial driver (requires sppp) # wi: Lucent WaveLAN/IEEE 802.11 PCMCIA adapters. Note: this supports both # the PCMCIA and ISA cards: the ISA card is really a PCMCIA to ISA # bridge with a PCMCIA adapter plugged into it. # wl: Lucent Wavelan (ISA card only). # ze: IBM/National Semiconductor PCMCIA ethernet controller. # zp: 3Com PCMCIA Etherlink III (It does not require shared memory for # send/receive operation, but it needs 'iomem' to read/write the # attribute memory) # oltr: Olicom ISA token-ring adapters OC-3115, OC-3117, OC-3118 and OC-3133 # (no options needed) # device ar0 at isa? port 0x300 net irq 10 iomem 0xd0000 device cs0 at isa? port 0x300 net irq ? device cx0 at isa? port 0x240 net irq 15 drq 7 device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 device el0 at isa? port 0x300 net irq 9 device ep0 at isa? port 0x300 net irq 10 device ex0 at isa? port? net irq? device fe0 at isa? port 0x300 net irq ? device ie0 at isa? port 0x300 net irq 5 iomem 0xd0000 device ie1 at isa? port 0x360 net irq 7 iomem 0xd0000 device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 device lnc0 at isa? port 0x280 net irq 10 drq 0 device rdp0 at isa? port 0x378 net irq 7 flags 2 device sr0 at isa? port 0x300 net irq 5 iomem 0xd0000 device wi0 at isa? port? net irq ? options WLCACHE # enables the signal-strength cache options WLDEBUG # enables verbose debugging output device wl0 at isa? port 0x300 net irq ? device xe0 at isa? port? irq ? # We can (bogusly) include both the dedicated PCCARD drivers and the generic # support when COMPILING_LINT. device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 device oltr0 at isa? # # ATM related options # # The `en' device provides support for Efficient Networks (ENI) # ENI-155 PCI midway cards, and the Adaptec 155Mbps PCI ATM cards (ANA-59x0). # # atm pseudo-device provides generic atm functions and is required for # atm devices. # NATM enables the netnatm protocol family that can be used to # bypass TCP/IP. # # the current driver supports only PVC operations (no atm-arp, no multicast). # for more details, please read the original documents at # http://www.ccrc.wustl.edu/pub/chuck/bsdatm/wucs.html # pseudo-device atm device en0 device en1 options NATM #native ATM # # Audio drivers: `snd', `sb', `pas', `gus', `pca' # # snd: Voxware sound support code # sb: SoundBlaster PCM - SoundBlaster, SB Pro, SB16, ProAudioSpectrum # sbxvi: SoundBlaster 16 # sbmidi: SoundBlaster 16 MIDI interface # pas: ProAudioSpectrum PCM and MIDI # gus: Gravis Ultrasound - Ultrasound, Ultrasound 16, Ultrasound MAX # gusxvi: Gravis Ultrasound 16-bit PCM (do not use) # mss: Microsoft Sound System # css: Crystal Sound System (CSS 423x PnP) # sscape: Ensoniq Soundscape MIDI interface # sscape_mss: Ensoniq Soundscape PCM (requires sscape) # opl: Yamaha OPL-2 and OPL-3 FM - SB, SB Pro, SB 16, ProAudioSpectrum # uart: stand-alone 6850 UART for MIDI # mpu: Roland MPU-401 stand-alone card # # Beware! The addresses specified below are also hard-coded in # i386/isa/sound/sound_config.h. If you change the values here, you # must also change the values in the include file. # # pcm: PCM audio through various sound cards. # # This has support for a large number of new audio cards, based on # CS423x, OPTi931, Yamaha OPL-SAx, and also for SB16, GusPnP. # For more information about this driver and supported cards, # see the pcm.4 man page and /sys/i386/isa/snd/CARDS. # # The flags of the device tells the device a bit more info about the # device that normally is obtained through the PnP interface. # bit 2..0 secondary DMA channel; # bit 4 set if the board uses two dma channels; # bit 15..8 board type, overrides autodetection; leave it # zero if don't know what to put in (and you don't, # since this is unsupported at the moment...). # # This driver will use the new PnP code if it's available. # # pca: PCM audio through your PC speaker # # If you have a GUS-MAX card and want to use the CS4231 codec on the # card the drqs for the gus max must be 8 bit (1, 2, or 3). # # If you would like to use the full duplex option on the gus, then define # flags to be the ``read dma channel''. # # options BROKEN_BUS_CLOCK #PAS-16 isn't working and OPTI chipset # options SYMPHONY_PAS #PAS-16 isn't working and SYMPHONY chipset # options EXCLUDE_SBPRO #PAS-16 # options SBC_IRQ=5 #PAS-16. Must match irq on sb0 line. # PAS16: The order of the pas0/sb0/opl0 is important since the # sb emulation is enabled in the pas-16 attach. # # To overide the GUS defaults use: # options GUS_DMA2 # options GUS_DMA # options GUS_IRQ # # The i386/isa/sound/sound.doc has more information. # Controls all "VOXWARE" driver sound devices. See Luigi's driver # below for an alternate which may work better for some cards. # controller snd0 device pas0 at isa? port 0x388 irq 10 drq 6 device sb0 at isa? port 0x220 irq 5 drq 1 device sbxvi0 at isa? drq 5 device sbmidi0 at isa? port 0x330 device awe0 at isa? port 0x620 device gus0 at isa? port 0x220 irq 12 drq 1 #device gus0 at isa? port 0x220 irq 12 drq 1 flags 0x3 device mss0 at isa? port 0x530 irq 10 drq 1 device css0 at isa? port 0x534 irq 5 drq 1 flags 0x08 device sscape0 at isa? port 0x330 irq 9 drq 0 device trix0 at isa? port 0x330 irq 6 drq 0 device sscape_mss0 at isa? port 0x534 irq 5 drq 1 device opl0 at isa? port 0x388 device mpu0 at isa? port 0x330 irq 6 drq 0 device uart0 at isa? port 0x330 irq 5 # Luigi's snd code (use INSTEAD of snd0 and all VOXWARE drivers!). # You may also wish to enable the pnp controller with this, for pnp # sound cards. # #device pcm0 at isa? port ? tty irq 10 drq 1 flags 0x0 # Not controlled by `snd' device pca0 at isa? port "IO_TIMER1" tty # # Miscellaneous hardware: # # mcd: Mitsumi CD-ROM # scd: Sony CD-ROM # matcd: Matsushita/Panasonic CD-ROM # wt: Wangtek and Archive QIC-02/QIC-36 tape drives # ctx: Cortex-I frame grabber # apm: Laptop Advanced Power Management (experimental) # spigot: The Creative Labs Video Spigot video-acquisition board # meteor: Matrox Meteor video capture board # bktr: Brooktree bt848/848a/849/878/879 family video capture and TV Tuner board # cy: Cyclades serial driver # dgb: Digiboard PC/Xi and PC/Xe series driver (ALPHA QUALITY!) # dgm: Digiboard PC/Xem driver # gp: National Instruments AT-GPIB and AT-GPIB/TNT board # asc: GI1904-based hand scanners, e.g. the Trust Amiscan Grey # gsc: Genius GS-4500 hand scanner. # joy: joystick # labpc: National Instrument's Lab-PC and Lab-PC+ # rc: RISCom/8 multiport card # rp: Comtrol Rocketport(ISA) - single card # tw: TW-523 power line interface for use with X-10 home control products # si: Specialix SI/XIO 4-32 port terminal multiplexor # stl: Stallion EasyIO and EasyConnection 8/32 (cd1400 based) # stli: Stallion EasyConnection 8/64, ONboard, Brumby (intelligent) # # Notes on APM # The flags takes the following meaning for apm0: # 0x0020 Statclock is broken. # 0x0011 Limit APM protocol to 1.1 or 1.0 # 0x0010 Limit APM protocol to 1.0 # # # Notes on the spigot: # The video spigot is at 0xad6. This port address can not be changed. # The irq values may only be 10, 11, or 15 # I/O memory is an 8kb region. Possible values are: # 0a0000, 0a2000, ..., 0fffff, f00000, f02000, ..., ffffff # The start address must be on an even boundary. # Add the following option if you want to allow non-root users to be able # to access the spigot. This option is not secure because it allows users # direct access to the I/O page. # options SPIGOT_UNSECURE # # Notes on the Comtrol Rocketport driver: # # The exact values used for rp0 depend on how many boards you have # in the system. The manufacturer's sample configs are listed as: # # Comtrol Rocketport ISA single card # device rp0 at isa? port 0x280 tty # # If instead you have two ISA cards, one installed at 0x100 and the # second installed at 0x180, then you should add the following to # your kernel configuration file: # # device rp0 at isa? port 0x100 tty # device rp1 at isa? port 0x180 tty # # For 4 ISA cards, it might be something like this: # # device rp0 at isa? port 0x180 tty # device rp1 at isa? port 0x100 tty # device rp2 at isa? port 0x340 tty # device rp3 at isa? port 0x240 tty # # And for PCI cards, you only need say: # # device rp0 # device rp1 # ... # Note: Make sure that any Rocketport PCI devices are specified BEFORE the # ISA Rocketport devices. # Notes on the Digiboard driver: # # The following flag values have special meanings: # 0x01 - alternate layout of pins (dgb & dgm) # 0x02 - use the windowed PC/Xe in 64K mode (dgb only) # Notes on the Specialix SI/XIO driver: # **This is NOT a Specialix supported Driver!** # The host card is memory, not IO mapped. # The Rev 1 host cards use a 64K chunk, on a 32K boundary. # The Rev 2 host cards use a 32K chunk, on a 32K boundary. # The cards can use an IRQ of 11, 12 or 15. # Notes on the Stallion stl and stli drivers: # See src/i386/isa/README.stl for complete instructions. # This is version 0.0.5alpha, unsupported by Stallion. # The stl driver has a secondary IO port hard coded at 0x280. You need # to change src/i386/isa/stallion.c if you reconfigure this on the boards. # The "flags" and "iosiz" settings on the stli driver depend on the board: # EasyConnection 8/64 ISA: flags 23 iosiz 0x1000 # EasyConnection 8/64 EISA: flags 24 iosiz 0x10000 # EasyConnection 8/64 MCA: flags 25 iosiz 0x1000 # ONboard ISA: flags 4 iosiz 0x10000 # ONboard EISA: flags 7 iosiz 0x10000 # ONboard MCA: flags 3 iosiz 0x10000 # Brumby: flags 2 iosiz 0x4000 # Stallion: flags 1 iosiz 0x10000 device mcd0 at isa? port 0x300 bio irq 10 # for the Sony CDU31/33A CDROM device scd0 at isa? port 0x230 bio # for the SoundBlaster 16 multicd - up to 4 devices controller matcd0 at isa? port 0x230 bio device wt0 at isa? port 0x300 bio irq 5 drq 1 device ctx0 at isa? port 0x230 iomem 0xd0000 device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000 device apm0 at isa? device gp0 at isa? port 0x2c0 tty device gsc0 at isa? port "IO_GSC1" tty drq 3 device joy0 at isa? port IO_GAME device cy0 at isa? tty irq 10 iomem 0xd4000 iosiz 0x2000 options CY_PCI_FASTINTR # Use with cy_pci unless irq is shared device dgb0 at isa? port 0x220 iomem 0xfc000 iosiz ? tty options "NDGBPORTS=16" # Defaults to 16*NDGB device dgm0 at isa? port 0x104 iomem 0xd0000 iosiz ? tty device labpc0 at isa? port 0x260 tty irq 5 device rc0 at isa? port 0x220 tty irq 12 device rp0 at isa? port 0x280 tty # the port and irq for tw0 are fictitious device tw0 at isa? port 0x380 tty irq 11 device si0 at isa? iomem 0xd0000 tty irq 12 device asc0 at isa? port "IO_ASC1" tty drq 3 irq 10 device stl0 at isa? port 0x2a0 tty irq 10 device stli0 at isa? port 0x2a0 tty iomem 0xcc000 flags 23 iosiz 0x1000 # You are unlikely to have the hardware for loran0 device loran0 at isa? port ? tty irq 5 # HOT1 Xilinx 6200 card (www.vcc.com) device xrpu0 # # EISA devices: # # The EISA bus device is eisa0. It provides auto-detection and # configuration support for all devices on the EISA bus. # # The `ahb' device provides support for the Adaptec 174X adapter. # # The `ahc' device provides support for the Adaptec 274X and 284X # adapters. The 284X, although a VLB card responds to EISA probes. # # fea: DEC DEFEA EISA FDDI adapter # controller eisa0 controller ahb0 controller ahc0 device fea0 # The aic7xxx driver will attempt to use memory mapped I/O for all PCI # controllers that have it configured only if this option is set. Unfortunately, # this doesn't work on some motherboards, which prevents it from being the # default. options AHC_ALLOW_MEMIO # By default, only 10 EISA slots are probed, since the slot numbers # above clash with the configuration address space of the PCI subsystem, # and the EISA probe is not very smart about this. This is sufficient # for most machines, but in particular the HP NetServer LC series comes # with an onboard AIC7770 dual-channel SCSI controller on EISA slot #11, # thus you need to bump this figure to 12 for them. options "EISA_SLOTS=12" # # PCI devices & PCI options: # # The main PCI bus device is `pci'. It provides auto-detection and # configuration support for all devices on the PCI bus, using either # configuration mode defined in the PCI specification. # # The `ahc' device provides support for the Adaptec 29/3940(U)(W) # and motherboard based AIC7870/AIC7880 adapters. # # The `ncr' device provides support for the NCR 53C810 and 53C825 # self-contained SCSI host adapters. # # The `isp' device provides support for the Qlogic ISP 1020, 1040 # nd 1040B PCI SCSI host adapters, as well as the Qlogic ISP 2100 # FC/AL Host Adapter. # # The `al' device provides support for PCI fast ethernet adapters # based on the ADMtek Inc. AL981 "Comet" chip.. # # The `ax' device provides support for PCI fast ethernet adapters # based on the ASIX Electronics AX88140A chip, including the Alfa # Inc. GFC2204. # # The `de' device provides support for the Digital Equipment DC21040 # self-contained Ethernet adapter. # # The `fxp' device provides support for the Intel EtherExpress Pro/100B # PCI Fast Ethernet adapters. # # The `mx' device provides support for various fast ethernet adapters # based on the Macronix 98713, 987615 ans 98725 series chips. # # The `pn' device provides support for various fast ethernet adapters # based on the Lite-On 82c168 and 82c169 PNIC chips, including the # LinkSys LNE100TX, the NetGear FA310TX rev. D1 and the Matrox # FastNIC 10/100. # # The 'rl' device provides support for PCI fast ethernet adapters based # on the RealTek 8129/8139 chipset. Note that the RealTek driver defaults # to useing programmed I/O to do register accesses because memory mapped # mode seems to cause severe lockups on SMP hardware. This driver also # supports the Accton EN1207D `Cheetah' adapter, which uses a chip called # the MPX 5030/5038, which is either a RealTek in disguise or a RealTek # workalike. # +# The 'sf' device provides support for Adaptec Duralink PCI fast +# ethernet adapters based on the Adaptec AIC-6915 "starfire" controller. +# This includes dual and quad port cards, as well as one 100baseFX card. +# Most of these are 64-bit PCI devices, except for one single port +# card which is 32-bit. +# +# The 'sk' device provides support for the SysKonnect SK-984x series +# PCI gigabit ethernet NICs. This includes the SK-9841 and SK-9842 +# single port cards (single mode and multimode fiber) and the +# SK-9843 and SK-9844 dual port cards (also single mode and multimode). +# The driver will autodetect the number of ports on the card and +# attach each one as a separate network interface. +# # The 'ti' device provides support for PCI gigabit ethernet NICs based # on the Alteon Networks Tigon 1 and Tigon 2 chipsets. This includes the # Alteon AceNIC, the 3Com 3c985, the Netgear GA620 and various others. # Note that you will probably want to bump up NMBCLUSTERS a lot to use # this driver. # # The 'tl' device provides support for the Texas Instruments TNETE100 # series 'ThunderLAN' cards and integrated ethernet controllers. This # includes several Compaq Netelligent 10/100 cards and the built-in # ethernet controllers in several Compaq Prosignia, Proliant and # Deskpro systems. It also supports several Olicom 10Mbps and 10/100 # boards. # # The `tx' device provides support for the SMC 9432TX cards. # # The `vr' device provides support for various fast ethernet adapters # based on the VIA Technologies VT3043 `Rhine I' and VT86C100A `Rhine II' # chips, including the D-Link DFE530TX. # # The `vx' device provides support for the 3Com 3C590 and 3C595 # early support # # The `wb' device provides support for various fast ethernet adapters # based on the Winbond W89C840F chip. Note: this is not the same as # the Winbond W89C940F, which is an NE2000 clone. # # The `xl' device provides support for the 3Com 3c900, 3c905 and # 3c905B (Fast) Etherlink XL cards and integrated controllers. This # includes the integrated 3c905B-TX chips in certain Dell Optiplex and # Dell Precision desktop machines and the integrated 3c905-TX chips # in Dell Latitude laptop docking stations. # # The `fpa' device provides support for the Digital DEFPA PCI FDDI # adapter. pseudo-device fddi is also needed. # # The `meteor' device is a PCI video capture board. It can also have the # following options: # options METEOR_ALLOC_PAGES=xxx preallocate kernel pages for data entry # figure (ROWS*COLUMN*BYTES_PER_PIXEL*FRAME+PAGE_SIZE-1)/PAGE_SIZE # options METEOR_DEALLOC_PAGES remove all allocated pages on close(2) # options METEOR_DEALLOC_ABOVE=xxx remove all allocated pages above the # specified amount. If this value is below the allocated amount no action # taken # option METEOR_SYSTEM_DEFAULT={METEOR_PAL|METEOR_NTSC|METEOR_SECAM}, used # for initialization of fps routine when a signal is not present. # # The 'bktr' device is a PCI video capture device using the Brooktree # bt848/bt848a/bt849/bt878/bt879 chipset. When used with a TV Tuner it forms a # TV card, eg Miro PC/TV,Hauppauge WinCast/TV WinTV, VideoLogic Captivator, # Intel Smart Video III, AverMedia, IMS Turbo. # The following options can be used to override the auto detection # options OVERRIDE_CARD=xxx # options OVERRIDE_TUNER=xxx # options OVERRIDE_MSP=1 # options OVERRIDE_DBX=1 # The current values are found in /usr/src/sys/pci/brooktree848.c # # option BROOKTREE_SYSTEM_DEFAULT=BROOKTREE_PAL # This is required for Dual Crystal (28&35Mhz) boards where PAL is used # to prevent hangs during initialisation. eg VideoLogic Captivator PCI. # # PAL or SECAM users who have a 28Mhz crystal (and no 35Mhz crystal) # must enable PLL mode with this option. eg some new Hauppauge cards. # option BKTR_USE_PLL # # Using sysctl(8) run-time overrides on a per-card basis can be made # # The oltr driver supports the following Olicom PCI token-ring adapters # OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250 # controller pci0 controller ahc1 controller ncr0 controller isp0 # # Options for ISP # # SCSI_ISP_NO_FWLOAD_MASK - mask of isp unit numbers (obviously # a max of 32) that you wish to disable # to disable the loading of firmware on. # SCSI_ISP_NO_NVRAM_MASK - mask of isp unit numbers (obviously # a max of 32) that you wish to disable # them picking up information from NVRAM # (for broken cards you can't fix the NVRAM # on- very rare, or for systems you can't # change NVRAM on (e.g. alpha) and you don't # like what's in there) # SCSI_ISP_PREFER_MEM_MAP - control preference for using memory mappings # instead of I/O space mappings. It defaults # to 1 for i386, 0 for alpha. Set to 1 to # unconditionally prefer mapping memory, # else it will use I/O space mappings. Of # course, this can fail if the PCI implement- # ation doesn't support what you want. # # SCSI_ISP_FCDUPLEX - mask of isp unit numbers (obviously # a max of 32) that you wish to set fibre # channel full duplex mode on. # to disable the loading of firmware on. # SCSI_ISP_FABRIC enable loading of Fabric f/w flavor (2100). # SCSI_ISP_SCCLUN enable loading of expanded lun f/w (2100). # # ISP_DISABLE_1020_SUPPORT Disable support for 1020/1040 cards # ISP_DISABLE_1080_SUPPORT Disable support for 1080/1240 cards # ISP_DISABLE_2100_SUPPORT Disable support for 2100 cards # (these really just to save code space) # (use of all three will cause the driver to not compile) options "SCSI_ISP_NO_FWLOAD_MASK=0x12" # disable FW load for isp1 and isp4 options "SCSI_ISP_NO_NVRAM_MASK=0x1" # disable NVRAM for isp0 options "SCSI_ISP_PREFER_MEM_MAP=0" # prefer I/O mapping options "ISP_DISABLE_1080_SUPPORT=1" # Disable support for Qlogic 1080 options "SCSI_ISP_FCDUPLEX=0x4" # isp2 is a Fibre Channel card # we want in full duplex mode. device al0 device ax0 device de0 device fxp0 device mx0 device pn0 device rl0 +device sf0 +device sk0 device ti0 device tl0 device tx0 device vr0 device vx0 device wb0 device xl0 device fpa0 device meteor0 #The oltr driver in the ISA section will also find PCI cards. #device oltr0 # Brooktree driver has been ported to the new I2C framework. Thus, # you'll need to have the following 3 lines in the kernel config. # controller smbus0 # controller iicbus0 # controller iicbb0 # The iic and smb devices are only needed if you want to control other # I2C slaves connected to the external connector of some cards. # device bktr0 # # PCI options # #options PCI_QUIET #quiets PCI code on chipset settings # # PCCARD/PCMCIA # # card: slot controller # pcic: slots controller card0 device pcic0 at card? device pcic1 at card? # You may need to reset all pccards after resuming options PCIC_RESUME_RESET # reset after resume # # Laptop/Notebook options: # # See also: # apm under `Miscellaneous hardware' # above. # For older notebooks that signal a powerfail condition (external # power supply dropped, or battery state low) by issuing an NMI: options POWERFAIL_NMI # make it beep instead of panicing # # SMB bus # # System Management Bus support provided by the 'smbus' device. # # Supported devices: # smb standard io # # Supported interfaces: # iicsmb I2C to SMB bridge with any iicbus interface # bktr brooktree848 I2C hardware interface # controller smbus0 device smb0 at smbus? # # I2C Bus # # Philips i2c bus support is provided by the `iicbus' device. # # Supported devices: # ic i2c network interface # iic i2c standard io # iicsmb i2c to smb bridge. Allow i2c i/o with smb commands. # # Supported interfaces: # pcf Philips PCF8584 ISA-bus controller # bktr brooktree848 I2C software interface # # Other: # iicbb generic I2C bit-banging code (needed by lpbb, bktr) # controller iicbus0 controller iicbb0 device ic0 at iicbus? device iic0 at iicbus? device iicsmb0 at iicbus? controller pcf0 at isa? port 0x320 net irq 5 # ISDN4BSD section # i4b passive ISDN cards support (isic - I4b Siemens Isdn Chipset driver) # note that the ``options'' and ``device'' lines must BOTH be defined ! # # Non-PnP Cards: # -------------- # # Teles S0/8 or Niccy 1008 options "TEL_S0_8" #device isic0 at isa? iomem 0xd0000 net irq 5 flags 1 # # Teles S0/16 or Creatix ISDN-S0 or Niccy 1016 options "TEL_S0_16" #device isic0 at isa? port 0xd80 iomem 0xd0000 net irq 5 flags 2 # # Teles S0/16.3 options "TEL_S0_16_3" #device isic0 at isa? port 0xd80 net irq 5 flags 3 # # AVM A1 or AVM Fritz!Card options "AVM_A1" #device isic0 at isa? port 0x340 net irq 5 flags 4 # # USRobotics Sportster ISDN TA intern options "USR_STI" #device isic0 at isa? port 0x268 net irq 5 flags 7 # # ITK ix1 Micro options "ITKIX1" #device isic0 at isa? port 0x398 net irq 10 flags 18 # # PnP-Cards: # ---------- # # Teles S0/16.3 PnP options "TEL_S0_16_3_P" #device isic0 at isa? port ? net irq ? # # Creatix ISDN-S0 P&P options "CRTX_S0_P" #device isic0 at isa? port ? net irq ? # # Dr. Neuhaus Niccy Go@ options "DRN_NGO" #device isic0 at isa? port ? net irq ? # # Sedlbauer Win Speed options "SEDLBAUER" #device isic0 at isa? port ? net irq ? # # Dynalink IS64PH options "DYNALINK" #device isic0 at isa? port ? net irq ? # # ELSA QuickStep 1000pro ISA options "ELSA_QS1ISA" #device isic0 at isa? port ? net irq ? # # PCI-Cards: # ---------- # # ELSA QuickStep 1000pro PCI options "ELSA_QS1PCI" #device isic0 # # PCMCIA-Cards: # ------------- # # AVM PCMCIA Fritz!Card options "AVM_A1_PCMCIA" device isic0 at isa? port 0x340 net irq 5 flags 10 # # Active Cards: # ------------- # # Stollmann Tina-dd control device device tina0 at isa? port 0x260 net irq 10 # # ISDN Protocol Stack # ------------------- # # Q.921 / layer 2 - i4b passive cards D channel handling pseudo-device "i4bq921" # # Q.931 / layer 3 - i4b passive cards D channel handling pseudo-device "i4bq931" # # layer 4 - i4b common passive and active card handling pseudo-device "i4b" # # ISDN devices # ------------ # # userland driver to do ISDN tracing (for passive cards only) pseudo-device "i4btrc" 4 # # userland driver to control the whole thing pseudo-device "i4bctl" # # userland driver for access to raw B channel pseudo-device "i4brbch" 4 # # userland driver for telephony pseudo-device "i4btel" 2 # # network driver for IP over raw HDLC ISDN pseudo-device "i4bipr" 4 # enable VJ header compression detection for ipr i/f options IPR_VJ # # network driver for sync PPP over ISDN pseudo-device "i4bisppp" 4 # Parallel-Port Bus # # Parallel port bus support is provided by the `ppbus' device. # Multiple devices may be attached to the parallel port, devices # are automatically probed and attached when found. # # Supported devices: # vpo Iomega Zip Drive # Requires SCSI disk support ('scbus' and 'da'), best # performance is achieved with ports in EPP 1.9 mode. # lpt Parallel Printer, use _instead_ of olpt0 # plip Parallel network interface # ppi General-purpose I/O ("Geek Port") # pps Pulse per second Timing Interface # lpbb Philips official parallel port I2C bit-banging interface # # Supported interfaces: # ppc ISA-bus parallel port interfaces. # controller ppbus0 controller vpo0 at ppbus? device lpt0 at ppbus? device plip0 at ppbus? device ppi0 at ppbus? device pps0 at ppbus? device lpbb0 at ppbus? device ppc0 at isa? disable port? tty irq 7 # Kernel BOOTP support options BOOTP # Use BOOTP to obtain IP address/hostname options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options "BOOTP_NFSV3" # Use NFS v3 to NFS mount root options BOOTP_COMPAT # Workaround for broken bootp daemons. options "BOOTP_WIRED_TO=fxp0" # Use interface fxp0 for BOOTP # If you want to disable loadable kernel modules (LKM), you # might want to use this option. #options NO_LKM # # Add tie-ins for a hardware watchdog. This only enable the hooks; # the user must still supply the actual driver. # options HW_WDOG # # Set the number of PV entries per process. Increasing this can # stop panics related to heavy use of shared memory. However, that can # (combined with large amounts of physical memory) cause panics at # boot time due the kernel running out of VM space. # # If you're tweaking this, you might also want to increase the sysctls # "vm.v_free_min", "vm.v_free_reserved", and "vm.v_free_target". # # The value below is the one more than the default. # options "PMAP_SHPGPERPROC=201" # # Disable swapping. This option removes all code which actually performs # swapping, so it's not possible to turn it back on at run-time. # # This is sometimes usable for systems which don't have any swap space # (see also sysctls "vm.defer_swapspace_pageouts" and # "vm.disable_swapspace_pageouts") # #options NO_SWAPPING # Set the number of sf_bufs to allocate. sf_bufs are virtual buffers # for sendfile(2) that are used to map file VM pages, and normally # default to a quantity that is roughly 16*MAXUSERS+512. You would # typically want about 4 of these for each simultaneous file send. # options "NSFBUFS=1024" # # Enable extra debugging code for locks. This include storing the # filename and line of whatever aquired the lock in the lock itself, # and changing a number of function calls to pass around the relevant # data. This is not at all useful unless you are debugging lock code. # options DEBUG_LOCKS # More undocumented options for linting. options CLK_CALIBRATION_LOOP options "CLK_USE_I8254_CALIBRATION" options CLK_USE_TSC_CALIBRATION options CLUSTERDEBUG options COMPAT_LINUX options CPU_UPGRADE_HW_CACHE options DEBUG options DEBUG_VFS_LOCKS options "DEBUG_1284" #options DISABLE_PSE options "EXT2FS" options "I586_PMC_GUPROF=0x70000" options "IBCS2" options KEY options KEY_DEBUG options LOCKF_DEBUG options LOUTB options KBD_MAXRETRY=4 options KBD_MAXWAIT=6 options KBD_RESETDELAY=201 options KBDIO_DEBUG=2 options MSGMNB=2049 options MSGMNI=41 options MSGSEG=2049 options MSGSSZ=16 options MSGTQL=41 options NBUF=512 options NETATALKDEBUG options NMBCLUSTERS=1024 options NPX_DEBUG options PANIC_REBOOT_WAIT_TIME=16 options "PCVT_24LINESDEF" options PCVT_CTRL_ALT_DEL options PCVT_EMU_MOUSE options PCVT_FREEBSD=211 options PCVT_META_ESC options PCVT_NSCREENS=9 options PCVT_PRETTYSCRNS options PCVT_SCREENSAVER options PCVT_USEKBDSEC options "PCVT_VT220KEYB" options PSM_DEBUG=1 options SCSI_NCR_DEBUG options SCSI_NCR_DFLT_TAGS=4 options SCSI_NCR_MAX_SYNC=10000 options SCSI_NCR_MAX_WIDE=1 options SCSI_NCR_MYADDR=7 options SEMMAP=31 options SEMMNI=11 options SEMMNS=61 options SEMMNU=31 options SEMMSL=61 options SEMOPM=101 options SEMUME=11 options SHOW_BUSYBUFS # List buffers that prevent root unmount options SHMALL=1025 options "SHMMAX=(SHMMAXPGS*PAGE_SIZE+1)" options SHMMAXPGS=1025 options SHMMIN=2 options SHMMNI=33 options SHMSEG=9 options SI_DEBUG options SIMPLELOCK_DEBUG options SPX_HACK options VFS_BIO_DEBUG # The 'dpt' driver provides support for DPT controllers (http://www.dpt.com/). # These have hardware RAID-{0,1,5} support, and do multi-initiator I/O. # The DPT controllers are commonly re-licensed under other brand-names - # some controllers by Olivetti, Dec, HP, AT&T, SNI, AST, Alphatronic, NEC and # Compaq are actually DPT controllers. # # See sys/dev/dpt for debugging and other subtle options. # DPT_VERIFY_HINTR Performs some strict hardware interrupts testing. # Only use if you suspect PCI bus corruption problems # DPT_RESTRICTED_FREELIST Normally, the freelisat used by the DPT for queue # will grow to accomodate increased use. This growth # will NOT shrink. To restrict the number of queue # slots to exactly what the DPT can hold at one time, # enable this option. # DPT_MEASURE_PERFORMANCE Enables a set of (semi)invasive metrics. Various # instruments are enabled. The tools in # /usr/sbin/dpt_* assume these to be enabled. # DPT_FREELIST_IS_STACK For optimal L{1,2} CPU cache utilization, enable # this option. Otherwise, the transaction queue is # a LIFO. I cannot measure the performance gain. # DPT_HANDLE_TIMEOUTS Normally device timeouts are handled by the DPT. # If you ant the driver to handle timeouts, enable # this option. If your system is very busy, this # option will create more trouble than solve. # DPT_TIMEOUT_FACTOR Used to compute the excessive amount of time to # wait when timing out with the above option. # DPT_DEBUG_xxxx These are controllable from sys/dev/dpt/dpt.h # DPT_LOST_IRQ When enabled, will try, once per second, to catch # any interrupt that got lost. Seems to help in some # DPT-firmware/Motherboard combinations. Minimal # cost, great benefit. # DPT_RESET_HBA Make "reset" actually reset the controller # instead of fudging it. Only enable this if you # are 100% certain you need it. # DPT_SHUTDOWN_SLEEP Reset controller if a request take more than # this number of seconds. Do NOT enable this # unless you are really, really, really certain # you need it. You are advised to call Simon (the # driver author) before setting it, and NEVER, # EVER set it to less than 300s (5 minutes). controller dpt0 # DPT options options DPT_VERIFY_HINTR options DPT_RESTRICTED_FREELIST #!CAM# options DPT_MEASURE_PERFORMANCE options DPT_FREELIST_IS_STACK #!CAM# options DPT_HANDLE_TIMEOUTS options DPT_TIMEOUT_FACTOR=4 options DPT_INTR_DELAY=200 # Some motherboards need that options DPT_LOST_IRQ options DPT_RESET_HBA # Don't EVER set this without having talked to Simon Shapiro on the phone # first. options DPT_SHUTDOWN_SLEEP=500 # # Embedded system options: # # An embedded system might want to run something other than init. options INIT_PATH="/sbin/init:/stand/sysinstall" # USB support # UHCI controller controller uhci0 # OHCI controller controller ohci0 # General USB code (mandatory for USB) controller usb0 # # Generic USB device driver device ugen0 # Human Interface Device (anything with buttons and dials) device uhid0 # USB keyboard device ukbd0 # USB printer device ulpt0 # USB mouse device ums0 # # debugging options for the USB subsystem # options UHCI_DEBUG options OHCI_DEBUG options USB_DEBUG options UGEN_DEBUG options UHID_DEBUG options UHUB_DEBUG options UKBD_DEBUG options ULPT_DEBUG options UMS_DEBUG Index: stable/3/sys/i386/i386/userconfig.c =================================================================== --- stable/3/sys/i386/i386/userconfig.c (revision 49544) +++ stable/3/sys/i386/i386/userconfig.c (revision 49545) @@ -1,3552 +1,3555 @@ /** ** Copyright (c) 1995 ** Michael Smith, msmith@freebsd.org. All rights reserved. ** ** This code contains a module marked : * Copyright (c) 1991 Regents of the University of California. * All rights reserved. * Copyright (c) 1994 Jordan K. Hubbard * All rights reserved. * Copyright (c) 1994 David Greenman * All rights reserved. * * Many additional changes by Bruce Evans * * This code is derived from software contributed by the * University of California Berkeley, Jordan K. Hubbard, * David Greenman and Bruce Evans. ** As such, it contains code subject to the above copyrights. ** The module and its copyright can be found below. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer as ** the first lines of this file unmodified. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. All advertising materials mentioning features or use of this software ** must display the following acknowledgment: ** This product includes software developed by Michael Smith. ** 4. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY MICHAEL SMITH ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL MICHAEL SMITH BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** - ** $Id: userconfig.c,v 1.126.2.5 1999/05/15 18:19:37 obrien Exp $ + ** $Id: userconfig.c,v 1.126.2.6 1999/06/19 21:37:40 wpaul Exp $ **/ /** ** USERCONFIG ** ** Kernel boot-time configuration manipulation tool for FreeBSD. ** ** Two modes of operation are supported : the default is the line-editor mode, ** the command "visual" invokes the fullscreen mode. ** ** The line-editor mode is the old favorite from FreeBSD 2.0/20.05 &c., the ** fullscreen mode requires syscons or a minimal-ansi serial console. **/ /** ** USERCONFIG, visual mode. ** ** msmith@freebsd.org ** ** Look for "EDIT THIS LIST" to add to the list of known devices ** ** ** There are a number of assumptions made in this code. ** ** - That the console supports a minimal set of ANSI escape sequences ** (See the screen manipulation section for a summary) ** and has at least 24 rows. ** - That values less than or equal to zero for any of the device ** parameters indicate that the driver does not use the parameter. ** - That the only tunable parameter for PCI devices are their flags. ** - That flags are _always_ editable. ** ** Devices marked as disabled are imported as such. PCI devices are ** listed under a seperate heading for informational purposes only. ** To date, there is no means for changing the behaviour of PCI drivers ** from UserConfig. ** ** Note that some EISA devices probably fall into this category as well, ** and in fact the actual bus supported by some drivers is less than clear. ** A longer-term goal might be to list drivers by instance rather than ** per bus-presence. ** ** For this tool to be useful, the list of devices below _MUST_ be updated ** when a new driver is brought into the kernel. It is not possible to ** extract this information from the drivers in the kernel. ** ** XXX - TODO: ** ** - Display _what_ a device conflicts with. ** - Implement page up/down (as what?) ** - Wizard mode (no restrictions) ** - Find out how to put syscons back into low-intensity mode so that the ** !b escape is useful on the console. (It seems to be that it actually ** gets low/high intensity backwards. That looks OK.) ** ** - Only display headings with devices under them. (difficult) **/ #include "opt_userconfig.h" #include "pci.h" #include #include #include #include #include #include #include #include #include #include #include #include "pnp.h" #if NPNP > 0 #include #endif #include static MALLOC_DEFINE(M_DEVL, "isa_devlist", "isa_device lists in userconfig()"); static struct isa_device *isa_devlist; /* list read by kget to extract changes */ static int userconfig_boot_parsing; /* set if we are reading from the boot instructions */ #define putchar(x) cnputc(x) static int sysctl_machdep_uc_devlist SYSCTL_HANDLER_ARGS { struct isa_device *id; int error=0; char name[8]; if(!req->oldptr) { /* Only sizing */ id=isa_devlist; while(id) { error+=sizeof(struct isa_device)+8; id=id->id_next; } return(SYSCTL_OUT(req,0,error)); } else { /* Output the data. The buffer is filled with consecutive * struct isa_device and char buf[8], containing the name * (not guaranteed to end with '\0'). */ id=isa_devlist; while(id) { error=sysctl_handle_opaque(oidp,id, sizeof(struct isa_device),req); if(error) return(error); strncpy(name,id->id_driver->name,8); error=sysctl_handle_opaque(oidp,name, 8,req); if(error) return(error); id=id->id_next; } return(0); } } SYSCTL_PROC( _machdep, OID_AUTO, uc_devlist, CTLFLAG_RD, 0, 0, sysctl_machdep_uc_devlist, "A", "List of ISA devices changed in UserConfig"); /* ** Obtain command input. ** ** Initially, input is read from a possibly-loaded script. ** At the end of the script, or if no script is supplied, ** behaviour is determined by the RB_CONFIG (-c) flag. If ** the flag is set, user input is read from the console; if ** unset, the 'quit' command is invoked and userconfig ** will exit. ** ** Note that quit commands encountered in the script will be ** ignored if the RB_CONFIG flag is supplied. */ static const char *config_script; static int config_script_size; /* use of int for -ve magic value */ #define has_config_script() (config_script_size > 0) static int init_config_script(void) { caddr_t autoentry, autoattr; /* Look for loaded userconfig script */ autoentry = preload_search_by_type("userconfig_script"); if (autoentry != NULL) { /* We have one, get size and data */ config_script_size = 0; if ((autoattr = preload_search_info(autoentry, MODINFO_SIZE)) != NULL) config_script_size = (size_t)*(u_int32_t *)autoattr; config_script = NULL; if ((autoattr = preload_search_info(autoentry, MODINFO_ADDR)) != NULL) config_script = *(const char **)autoattr; /* sanity check */ if ((config_script_size == 0) || (config_script == NULL)) { config_script_size = 0; config_script = NULL; } } return has_config_script(); } static int getchar(void) { int c = -1; #ifdef INTRO_USERCONFIG static int intro = 0; #endif if (has_config_script()) { /* Consume character from loaded userconfig script, display */ userconfig_boot_parsing = 1; c = *config_script; config_script++; config_script_size--; } else { #ifdef INTRO_USERCONFIG if (userconfig_boot_parsing) { if (!(boothowto & RB_CONFIG)) { /* userconfig_script, !RB_CONFIG -> quit */ if (intro == 0) { c = 'q'; config_script = "uit\n"; config_script_size = strlen(config_script); /* userconfig_script will be 1 on the next pass */ } } else { /* userconfig_script, RB_CONFIG -> cngetc() */ } } else { if (!(boothowto & RB_CONFIG)) { /* no userconfig_script, !RB_CONFIG -> show intro */ if (intro == 0) { intro = 1; c = 'i'; config_script = "ntro\n"; config_script_size = strlen(config_script); /* userconfig_script will be 1 on the next pass */ } } else { /* no userconfig_script, RB_CONFIG -> cngetc() */ } } #else /* !INTRO_USERCONFIG */ /* assert(boothowto & RB_CONFIG) */ #endif /* INTRO_USERCONFIG */ userconfig_boot_parsing = 0; if (c <= 0) c = cngetc(); } return(c); } #ifndef FALSE #define FALSE (0) #define TRUE (!FALSE) #endif #ifdef VISUAL_USERCONFIG static struct isa_device *devtabs[] = { isa_devtab_bio, isa_devtab_tty, isa_devtab_net, isa_devtab_cam, isa_devtab_null, NULL }; typedef struct { char dev[16]; /* device basename */ char name[60]; /* long name */ int attrib; /* things to do with the device */ int class; /* device classification */ } DEV_INFO; #define FLG_INVISIBLE (1<<0) /* device should not be shown */ #define FLG_MANDATORY (1<<1) /* device can be edited but not disabled */ #define FLG_FIXIRQ (1<<2) /* device IRQ cannot be changed */ #define FLG_FIXIOBASE (1<<3) /* device iobase cannot be changed */ #define FLG_FIXMADDR (1<<4) /* device maddr cannot be changed */ #define FLG_FIXMSIZE (1<<5) /* device msize cannot be changed */ #define FLG_FIXDRQ (1<<6) /* device DRQ cannot be changed */ #define FLG_FIXED (FLG_FIXIRQ|FLG_FIXIOBASE|FLG_FIXMADDR|FLG_FIXMSIZE|FLG_FIXDRQ) #define FLG_IMMUTABLE (FLG_FIXED|FLG_MANDATORY) #define CLS_STORAGE 1 /* storage devices */ #define CLS_NETWORK 2 /* network interfaces */ #define CLS_COMMS 3 /* serial, parallel ports */ #define CLS_INPUT 4 /* user input : mice, keyboards, joysticks etc */ #define CLS_MMEDIA 5 /* "multimedia" devices (sound, video, etc) */ #define CLS_PCI 254 /* PCI devices */ #define CLS_MISC 255 /* none of the above */ typedef struct { char name[60]; int number; } DEVCLASS_INFO; static DEVCLASS_INFO devclass_names[] = { { "Storage : ", CLS_STORAGE}, { "Network : ", CLS_NETWORK}, { "Communications : ", CLS_COMMS}, { "Input : ", CLS_INPUT}, { "Multimedia : ", CLS_MMEDIA}, { "PCI : ", CLS_PCI}, { "Miscellaneous : ", CLS_MISC}, { "",0}}; /********************* EDIT THIS LIST **********************/ /** Notes : ** ** - PCI devices should be marked FLG_IMMUTABLE. They should not be movable ** or editable, and have no attributes. This is handled in getdevs() and ** devinfo(), so drivers that have a presence on busses other than PCI ** should have appropriate flags set below. ** - Devices that shouldn't be seen or removed should be marked FLG_INVISIBLE. ** - XXX The list below should be reviewed by the driver authors to verify ** that the correct flags have been set for each driver, and that the ** descriptions are accurate. **/ static DEV_INFO device_info[] = { /*---Name----- ---Description---------------------------------------------- */ {"isp", "QLogic ISP SCSI Controller", FLG_IMMUTABLE, CLS_STORAGE}, {"dpt", "DPT SCSI RAID Controller", FLG_IMMUTABLE, CLS_STORAGE}, {"adv", "AdvanSys SCSI narrow controller", 0, CLS_STORAGE}, {"adw", "AdvanSys SCSI WIDE controller", 0, CLS_STORAGE}, {"bt", "Buslogic SCSI controller", 0, CLS_STORAGE}, {"ahc", "Adaptec 274x/284x/294x SCSI controller", 0, CLS_STORAGE}, {"ahb", "Adaptec 174x SCSI controller", 0, CLS_STORAGE}, {"aha", "Adaptec 154x SCSI controller", 0, CLS_STORAGE}, {"uha", "Ultrastor 14F/24F/34F SCSI controller",0, CLS_STORAGE}, {"aic", "Adaptec 152x SCSI and compatible sound cards", 0, CLS_STORAGE}, {"nca", "ProAudio Spectrum SCSI and compatibles", 0, CLS_STORAGE}, {"sea", "Seagate ST01/ST02 SCSI and compatibles", 0, CLS_STORAGE}, {"wds", "Western Digitial WD7000 SCSI controller", 0, CLS_STORAGE}, {"ncr", "NCR/Symbios 53C810/15/25/60/75 SCSI controller",FLG_FIXED,CLS_STORAGE}, {"wdc", "IDE/ESDI/MFM disk controller", 0, CLS_STORAGE}, {"fdc", "Floppy disk controller", FLG_FIXED, CLS_STORAGE}, {"mcd", "Mitsumi CD-ROM", 0, CLS_STORAGE}, {"scd", "Sony CD-ROM", 0, CLS_STORAGE}, {"matcdc", "Matsushita/Panasonic/Creative CDROM", 0, CLS_STORAGE}, {"wt", "Wangtek/Archive QIC-02 Tape drive", 0, CLS_STORAGE}, {"amd", "Tekram DC-390(T) / AMD 53c974 based PCI SCSI", FLG_FIXED, CLS_STORAGE}, {"cs", "IBM EtherJet, CS89x0-based Ethernet adapters",0, CLS_NETWORK}, {"ed", "NE1000,NE2000,3C503,WD/SMC80xx Ethernet adapters",0, CLS_NETWORK}, {"el", "3C501 Ethernet adapter", 0, CLS_NETWORK}, {"ep", "3C509 Ethernet adapter", 0, CLS_NETWORK}, {"ex", "Intel EtherExpress Pro/10 Ethernet adapter", 0, CLS_NETWORK}, {"fe", "Fujitsu MD86960A/MB869685A Ethernet adapters", 0, CLS_NETWORK}, {"fea", "DEC DEFEA EISA FDDI adapter", 0, CLS_NETWORK}, {"fxp", "Intel EtherExpress Pro/100B Ethernet adapter", 0, CLS_NETWORK}, {"ie", "AT&T Starlan 10 and EN100, 3C507, NI5210 Ethernet adapters",0,CLS_NETWORK}, {"ix", "Intel EtherExpress Ethernet adapter", 0, CLS_NETWORK}, {"le", "DEC Etherworks 2 and 3 Ethernet adapters", 0, CLS_NETWORK}, {"lnc", "Isolan, Novell NE2100/NE32-VL Ethernet adapters", 0,CLS_NETWORK}, +{"sf", "Adaptec AIC-6915 PCI Ethernet adapters ", 0,CLS_NETWORK}, +{"sk", "SysKonnect SK-984x gigabit Ethernet adapters ", 0,CLS_NETWORK}, +{"ti", "Alteon Networks Tigon gigabit Ethernet adapters ", 0,CLS_NETWORK}, {"tl", "Texas Instruments ThunderLAN Ethernet adapters", 0,CLS_NETWORK}, {"tx", "SMC 9432TX Ethernet adapters", 0, CLS_NETWORK}, {"vx", "3COM 3C590/3C595 Ethernet adapters", 0, CLS_NETWORK}, {"xe", "Xircom PC Card Ethernet adapter", 0, CLS_NETWORK}, {"ze", "IBM/National Semiconductor PCMCIA Ethernet adapter",0, CLS_NETWORK}, {"zp", "3COM PCMCIA Etherlink III Ethernet adapter", 0, CLS_NETWORK}, {"al", "ADMtek AL981 ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"ax", "ASIX AX88140A ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"de", "DEC DC21040 Ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"fpa", "DEC DEFPA PCI FDDI adapter", FLG_FIXED, CLS_NETWORK}, {"rl", "RealTek 8129/8139 ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"mx", "Macronix PMAC ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"pn", "Lite-On 82c168/82c169 PNIC adapter", FLG_FIXED, CLS_NETWORK}, {"tl", "Texas Instruments ThunderLAN ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"vr", "VIA Rhine/Rhine II ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"wb", "Winbond W89C840F ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"xl", "3COM 3C90x PCI ethernet adapter", FLG_FIXED, CLS_NETWORK}, {"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS}, {"cx", "Cronyx/Sigma multiport sync/async adapter",0, CLS_COMMS}, {"rc", "RISCom/8 multiport async adapter", 0, CLS_COMMS}, {"cy", "Cyclades multiport async adapter", 0, CLS_COMMS}, {"cyy", "Cyclades Ye/PCI multiport async adapter",FLG_INVISIBLE,CLS_COMMS}, {"dgb", "Digiboard PC/Xe, PC/Xi async adapter", 0, CLS_COMMS}, {"si", "Specialix SI/XIO async adapter", 0, CLS_COMMS}, {"stl", "Stallion EasyIO/Easy Connection 8/32 async adapter",0, CLS_COMMS}, {"stli", "Stallion intelligent async adapter" ,0, CLS_COMMS}, {"lpt", "Parallel printer port", 0, CLS_COMMS}, {"ppc", "Parallel Port chipset", 0, CLS_COMMS}, {"gp", "National Instruments AT-GPIB/TNT driver", 0, CLS_COMMS}, {"atkbdc", "Keyboard controller", FLG_INVISIBLE, CLS_INPUT}, {"atkbd", "Keyboard", FLG_FIXED, CLS_INPUT}, {"mse", "Microsoft Bus Mouse", 0, CLS_INPUT}, {"psm", "PS/2 Mouse", FLG_FIXED, CLS_INPUT}, {"joy", "Joystick", FLG_FIXED, CLS_INPUT}, {"vt", "PCVT console driver", FLG_IMMUTABLE, CLS_INPUT}, {"sc", "Syscons console driver", FLG_IMMUTABLE, CLS_INPUT}, {"bktr", "Brooktree BT848 based frame grabber/tuner card", 0,CLS_MMEDIA}, {"pcm", "New Luigi audio driver for all supported sound cards", 0,CLS_MMEDIA}, {"sb", "Soundblaster PCM (SB, SBPro, SB16, ProAudio Spectrum)",0,CLS_MMEDIA}, {"sbxvi", "Soundblaster 16", 0, CLS_MMEDIA}, {"sbmidi", "Soundblaster MIDI interface", 0, CLS_MMEDIA}, {"awe", "AWE32 MIDI", 0, CLS_MMEDIA}, {"pas", "ProAudio Spectrum PCM and MIDI", 0, CLS_MMEDIA}, {"gus", "Gravis Ultrasound, Ultrasound 16 and Ultrasound MAX",0,CLS_MMEDIA}, {"gusxvi", "Gravis Ultrasound 16-bit PCM", 0, CLS_MMEDIA}, {"gusmax", "Gravis Ultrasound MAX", 0, CLS_MMEDIA}, {"mss", "Microsoft Sound System", 0, CLS_MMEDIA}, {"opl", "OPL-2/3 FM, Soundblaster, SBPro, SB16, ProAudio Spectrum",0,CLS_MMEDIA}, {"mpu", "Roland MPU401 MIDI", 0, CLS_MMEDIA}, {"sscape", "Ensoniq Soundscape MIDI interface", 0, CLS_MMEDIA}, {"sscape_mss", "Ensoniq Soundscape PCM", 0, CLS_MMEDIA}, {"uart", "6850 MIDI UART", 0, CLS_MMEDIA}, {"pca", "PC speaker PCM audio driver", FLG_FIXED, CLS_MMEDIA}, {"ctx", "Coretex-I frame grabber", 0, CLS_MMEDIA}, {"spigot", "Creative Labs Video Spigot video capture", 0, CLS_MMEDIA}, {"scc", "IBM Smart Capture Card", 0, CLS_MMEDIA}, {"gsc", "Genius GS-4500 hand scanner", 0, CLS_MMEDIA}, {"asc", "AmiScan scanner", 0, CLS_MMEDIA}, {"qcam", "QuickCam parallel port camera", 0, CLS_MMEDIA}, {"apm", "Advanced Power Management", FLG_FIXED, CLS_MISC}, {"labpc", "National Instruments Lab-PC/Lab-PC+", 0, CLS_MISC}, {"npx", "Math coprocessor", FLG_INVISIBLE, CLS_MISC}, {"lkm", "Loadable PCI driver support", FLG_INVISIBLE, CLS_MISC}, {"vga", "Catchall PCI VGA driver", FLG_INVISIBLE, CLS_MISC}, {"chip", "PCI chipset support", FLG_INVISIBLE, CLS_MISC}, {"piix", "Intel 82371 Bus-master IDE controller", FLG_INVISIBLE, CLS_MISC}, {"ide_pci", "PCI IDE controller", FLG_INVISIBLE, CLS_MISC}, {"","",0,0}}; typedef struct _devlist_struct { char name[80]; int attrib; /* flag values as per the FLG_* defines above */ int class; /* disk, etc as per the CLS_* defines above */ char dev[16]; int iobase,irq,drq,maddr,msize,unit,flags,conflict_ok,id; int comment; /* 0 = device, 1 = comment, 2 = collapsed comment */ int conflicts; /* set/reset by findconflict, count of conflicts */ int changed; /* nonzero if the device has been edited */ struct isa_device *device; struct _devlist_struct *prev,*next; } DEV_LIST; #define DEV_DEVICE 0 #define DEV_COMMENT 1 #define DEV_ZOOMED 2 #define LIST_CURRENT (1<<0) #define LIST_SELECTED (1<<1) #define KEY_EXIT 0 /* return codes from dolist() and friends */ #define KEY_DO 1 #define KEY_DEL 2 #define KEY_TAB 3 #define KEY_REDRAW 4 #define KEY_UP 5 /* these only returned from editval() */ #define KEY_DOWN 6 #define KEY_LEFT 7 #define KEY_RIGHT 8 #define KEY_NULL 9 /* this allows us to spin & redraw */ #define KEY_ZOOM 10 /* these for zoom all/collapse all */ #define KEY_UNZOOM 11 #define KEY_HELP 12 /* duh? */ static void redraw(void); static void insdev(DEV_LIST *dev, DEV_LIST *list); static int devinfo(DEV_LIST *dev); static int visuserconfig(void); static DEV_LIST *active = NULL,*inactive = NULL; /* driver lists */ static DEV_LIST *alist,*ilist; /* visible heads of the driver lists */ static DEV_LIST scratch; /* scratch record */ static int conflicts; /* total conflict count */ static char lines[] = "--------------------------------------------------------------------------------"; static char spaces[] = " "; /** ** Device manipulation stuff : find, describe, configure. **/ /** ** setdev ** ** Sets the device referenced by (*dev) to the parameters in the struct, ** and the enable flag according to (enabled) **/ static void setdev(DEV_LIST *dev, int enabled) { if (dev->iobase == -2) /* PCI device */ return; dev->device->id_iobase = dev->iobase; /* copy happy */ dev->device->id_irq = (u_short)(dev->irq < 16 ? 1<irq : 0); /* IRQ is bitfield */ dev->device->id_drq = (short)dev->drq; dev->device->id_maddr = (caddr_t)dev->maddr; dev->device->id_msize = dev->msize; dev->device->id_flags = dev->flags; dev->device->id_enabled = enabled; } /** ** getdevs ** ** Walk the kernel device tables and build the active and inactive lists **/ static void getdevs(void) { int i,j; struct isa_device *ap; for (j = 0; devtabs[j]; j++) /* ISA devices */ { ap = devtabs[j]; /* pointer to array of devices */ for (i = 0; ap[i].id_id; i++) /* for each device in this table */ { scratch.unit = ap[i].id_unit; /* device parameters */ strcpy(scratch.dev,ap[i].id_driver->name); scratch.iobase = ap[i].id_iobase; scratch.irq = ffs(ap[i].id_irq)-1; scratch.drq = ap[i].id_drq; scratch.maddr = (int)ap[i].id_maddr; scratch.msize = ap[i].id_msize; scratch.flags = ap[i].id_flags; scratch.conflict_ok = ap[i].id_conflicts; scratch.comment = DEV_DEVICE; /* admin stuff */ scratch.conflicts = 0; scratch.device = &ap[i]; /* save pointer for later reference */ scratch.changed = 0; if (!devinfo(&scratch)) /* get more info on the device */ insdev(&scratch,ap[i].id_enabled?active:inactive); } } #if NPCI > 0 for (i = 0; i < pcidevice_set.ls_length; i++) { if (pcidevice_set.ls_items[i]) { if (((const struct pci_device *)pcidevice_set.ls_items[i])->pd_name) { strcpy(scratch.dev,((const struct pci_device *)pcidevice_set.ls_items[i])->pd_name); scratch.iobase = -2; /* mark as PCI for future reference */ scratch.irq = -2; scratch.drq = -2; scratch.maddr = -2; scratch.msize = -2; scratch.flags = 0; scratch.conflict_ok = 0; /* shouldn't conflict */ scratch.comment = DEV_DEVICE; /* is a device */ scratch.unit = 0; /* arbitrary number of them */ scratch.conflicts = 0; scratch.device = NULL; scratch.changed = 0; if (!devinfo(&scratch)) /* look up name, set class and flags */ insdev(&scratch,active); /* always active */ } } } #endif /* NPCI > 0 */ } /** ** Devinfo ** ** Fill in (dev->name), (dev->attrib) and (dev->type) from the device_info array. ** If the device is unknown, put it in the CLS_MISC class, with no flags. ** ** If the device is marked "invisible", return nonzero; the caller should ** not insert any such device into either list. ** ** PCI devices are always inserted into CLS_PCI, regardless of the class associated ** with the driver type. **/ static int devinfo(DEV_LIST *dev) { int i; for (i = 0; device_info[i].class; i++) { if (!strcmp(dev->dev,device_info[i].dev)) { if (device_info[i].attrib & FLG_INVISIBLE) /* forget we ever saw this one */ return(1); strcpy(dev->name,device_info[i].name); /* get the name */ if (dev->iobase == -2) { /* is this a PCI device? */ dev->attrib = FLG_IMMUTABLE; /* dark green ones up the back... */ dev->class = CLS_PCI; } else { dev->attrib = device_info[i].attrib; /* light green ones up the front */ dev->class = device_info[i].class; } return(0); } } strcpy(dev->name,"Unknown device"); dev->attrib = 0; dev->class = CLS_MISC; return(0); } /** ** List manipulation stuff : add, move, initialise, free, traverse ** ** Note that there are assumptions throughout this code that ** the first entry in a list will never move. (assumed to be ** a comment). **/ /** ** Adddev ** ** appends a copy of (dev) to the end of (*list) **/ static void addev(DEV_LIST *dev, DEV_LIST **list) { DEV_LIST *lp,*ap; lp = (DEV_LIST *)malloc(sizeof(DEV_LIST),M_DEVL,M_WAITOK); bcopy(dev,lp,sizeof(DEV_LIST)); /* create copied record */ if (*list) /* list exists */ { ap = *list; while(ap->next) ap = ap->next; /* scoot to end of list */ lp->prev = ap; lp->next = NULL; ap->next = lp; }else{ /* list does not yet exist */ *list = lp; lp->prev = lp->next = NULL; /* list now exists */ } } /** ** Findspot ** ** Finds the 'appropriate' place for (dev) in (list) ** ** 'Appropriate' means in numeric order with other devices of the same type, ** or in alphabetic order following a comment of the appropriate type. ** or at the end of the list if an appropriate comment is not found. (this should ** never happen) ** (Note that the appropriate point is never the top, but may be the bottom) **/ static DEV_LIST * findspot(DEV_LIST *dev, DEV_LIST *list) { DEV_LIST *ap = NULL; /* search for a previous instance of the same device */ if (dev->iobase != -2) /* avoid PCI devices grouping with non-PCI devices */ { for (ap = list; ap; ap = ap->next) { if (ap->comment != DEV_DEVICE) /* ignore comments */ continue; if (ap->iobase == -2) /* don't group with a PCI device */ continue; if (!strcmp(dev->dev,ap->dev)) /* same base device */ { if ((dev->unit <= ap->unit) /* belongs before (equal is bad) */ || !ap->next) /* or end of list */ { ap = ap->prev; /* back up one */ break; /* done here */ } if (ap->next) /* if the next item exists */ { if (ap->next->comment != DEV_DEVICE) /* next is a comment */ break; if (strcmp(dev->dev,ap->next->dev)) /* next is a different device */ break; } } } } if (!ap) /* not sure yet */ { /* search for a class that the device might belong to */ for (ap = list; ap; ap = ap->next) { if (ap->comment != DEV_DEVICE) /* look for simlar devices */ continue; if (dev->class != ap->class) /* of same class too 8) */ continue; if (strcmp(dev->dev,ap->dev) < 0) /* belongs before the current entry */ { ap = ap->prev; /* back up one */ break; /* done here */ } if (ap->next) /* if the next item exists */ if (ap->next->comment != DEV_DEVICE) /* next is a comment, go here */ break; } } if (!ap) /* didn't find a match */ { for (ap = list; ap->next; ap = ap->next) /* try for a matching comment */ if ((ap->comment != DEV_DEVICE) && (ap->class == dev->class)) /* appropriate place? */ break; } /* or just put up with last */ return(ap); } /** ** Insdev ** ** Inserts a copy of (dev) at the appropriate point in (list) **/ static void insdev(DEV_LIST *dev, DEV_LIST *list) { DEV_LIST *lp,*ap; lp = (DEV_LIST *)malloc(sizeof(DEV_LIST),M_DEVL,M_WAITOK); bcopy(dev,lp,sizeof(DEV_LIST)); /* create copied record */ ap = findspot(lp,list); /* find appropriate spot */ lp->next = ap->next; /* point to next */ if (ap->next) ap->next->prev = lp; /* point next to new */ lp->prev = ap; /* point new to current */ ap->next = lp; /* and current to new */ } /** ** Movedev ** ** Moves (dev) from its current list to an appropriate place in (list) ** (dev) may not come from the top of a list, but it may from the bottom. **/ static void movedev(DEV_LIST *dev, DEV_LIST *list) { DEV_LIST *ap; ap = findspot(dev,list); dev->prev->next = dev->next; /* remove from old list */ if (dev->next) dev->next->prev = dev->prev; dev->next = ap->next; /* insert in new list */ if (ap->next) ap->next->prev = dev; /* point next to new */ dev->prev = ap; /* point new to current */ ap->next = dev; /* and current to new */ } /** ** Initlist ** ** Initialises (*list) with the basic headings **/ static void initlist(DEV_LIST **list) { int i; for(i = 0; devclass_names[i].name[0]; i++) /* for each devtype name */ { strcpy(scratch.name,devclass_names[i].name); scratch.comment = DEV_ZOOMED; scratch.class = devclass_names[i].number; scratch.attrib = FLG_MANDATORY; /* can't be moved */ addev(&scratch,list); /* add to the list */ } } /** ** savelist ** ** Walks (list) and saves the settings of any entry marked as changed. ** ** The device's active field is set according to (active). ** ** Builds the isa_devlist used by dset to extract the changed device information. ** The code for this was taken almost verbatim from the original module. **/ static void savelist(DEV_LIST *list, int active) { struct isa_device *id_p,*id_pn; while (list) { if ((list->comment == DEV_DEVICE) && /* is a device */ (list->changed) && /* has been changed */ (list->iobase != -2) && /* is not a PCI device */ (list->device != NULL)) { /* has an isa_device structure */ setdev(list,active); /* set the device itself */ id_pn = NULL; for (id_p=isa_devlist; id_p; id_p=id_p->id_next) { /* look on the list for it */ if (id_p->id_id == list->device->id_id) { id_pn = id_p->id_next; bcopy(list->device,id_p,sizeof(struct isa_device)); id_p->id_next = id_pn; break; } } if (!id_pn) /* not already on the list */ { id_pn = malloc(sizeof(struct isa_device),M_DEVL,M_WAITOK); bcopy(list->device,id_pn,sizeof(struct isa_device)); id_pn->id_next = isa_devlist; isa_devlist = id_pn; /* park at top of list */ } } list = list->next; } } /** ** nukelist ** ** Frees all storage in use by a (list). **/ static void nukelist(DEV_LIST *list) { DEV_LIST *dp; if (!list) return; while(list->prev) /* walk to head of list */ list = list->prev; while(list) { dp = list; list = list->next; free(dp,M_DEVL); } } /** ** prevent ** ** Returns the previous entry in (list), skipping zoomed regions. Returns NULL ** if there is no previous entry. (Only possible if list->prev == NULL given the ** premise that there is always a comment at the head of the list) **/ static DEV_LIST * prevent(DEV_LIST *list) { DEV_LIST *dp; if (!list) return(NULL); dp = list->prev; /* start back one */ while(dp) { if (dp->comment == DEV_ZOOMED) /* previous section is zoomed */ return(dp); /* so skip to comment */ if (dp->comment == DEV_COMMENT) /* not zoomed */ return(list->prev); /* one back as normal */ dp = dp->prev; /* backpedal */ } return(dp); /* NULL, we can assume */ } /** ** nextent ** ** Returns the next entry in (list), skipping zoomed regions. Returns NULL ** if there is no next entry. (Possible if the current entry is last, or ** if the current entry is the last heading and it's collapsed) **/ static DEV_LIST * nextent(DEV_LIST *list) { DEV_LIST *dp; if (!list) return(NULL); if (list->comment != DEV_ZOOMED) /* no reason to skip */ return(list->next); dp = list->next; while(dp) { if (dp->comment != DEV_DEVICE) /* found another heading */ break; dp = dp->next; } return(dp); /* back we go */ } /** ** ofsent ** ** Returns the (ofs)th entry down from (list), or NULL if it doesn't exist **/ static DEV_LIST * ofsent(int ofs, DEV_LIST *list) { while (ofs-- && list) list = nextent(list); return(list); } /** ** findconflict ** ** Scans every element of (list) and sets the conflict tags appropriately ** Returns the number of conflicts found. **/ static int findconflict(DEV_LIST *list) { int count = 0; /* number of conflicts found */ DEV_LIST *dp,*sp; for (dp = list; dp; dp = dp->next) /* over the whole list */ { if (dp->comment != DEV_DEVICE) /* comments don't usually conflict */ continue; if (dp->iobase == -2) /* it's a PCI device, not interested */ continue; dp->conflicts = 0; /* assume the best */ for (sp = list; sp; sp = sp->next) /* scan the entire list for conflicts */ { if (sp->comment != DEV_DEVICE) /* likewise */ continue; if (dp->iobase == -2) /* it's a PCI device, not interested */ continue; if (sp == dp) /* always conflict with itself */ continue; if (sp->conflict_ok && dp->conflict_ok) continue; /* both allowed to conflict */ if ((dp->iobase > 0) && /* iobase conflict? */ (dp->iobase == sp->iobase)) dp->conflicts = 1; if ((dp->irq > 0) && /* irq conflict? */ (dp->irq == sp->irq)) dp->conflicts = 1; if ((dp->drq > 0) && /* drq conflict? */ (dp->drq == sp->drq)) dp->conflicts = 1; if ((sp->maddr > 0) && /* maddr/msize conflict? */ (dp->maddr > 0) && (sp->maddr + ((sp->msize == 0) ? 1 : sp->msize) > dp->maddr) && (dp->maddr + ((dp->msize == 0) ? 1 : dp->msize) > sp->maddr)) dp->conflicts = 1; } count += dp->conflicts; /* count conflicts */ } return(count); } /** ** expandlist ** ** Unzooms all headings in (list) **/ static void expandlist(DEV_LIST *list) { while(list) { if (list->comment == DEV_COMMENT) list->comment = DEV_ZOOMED; list = list->next; } } /** ** collapselist ** ** Zooms all headings in (list) **/ static void collapselist(DEV_LIST *list) { while(list) { if (list->comment == DEV_ZOOMED) list->comment = DEV_COMMENT; list = list->next; } } /** ** Screen-manipulation stuff ** ** This is the basic screen layout : ** ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75 ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|.... ** +--------------------------------------------------------------------------------+ ** 0 -|---Active Drivers----------------------------xx Conflicts------Dev---IRQ--Port--| ** 1 -| ........................ ....... .. 0x....| ** 2 -| ........................ ....... .. 0x....| ** 3 -| ........................ ....... .. 0x....| ** 4 -| ........................ ....... .. 0x....| ** 5 -| ........................ ....... .. 0x....| ** 6 -| ........................ ....... .. 0x....| ** 7 -| ........................ ....... .. 0x....| ** 8 -| ........................ ....... .. 0x....| ** 9 -|---Inactive Drivers--------------------------------------------Dev--------------| ** 10-| ........................ ....... | ** 11-| ........................ ....... | ** 12-| ........................ ....... | ** 13-| ........................ ....... | ** 14-| ........................ ....... | ** 15-| ........................ ....... | ** 16-| ........................ ....... | ** 17-|------------------------------------------------------UP-DOWN-------------------| ** 18-| Relevant parameters for the current device | ** 19-| | ** 20-| | ** 21-|--------------------------------------------------------------------------------| ** 22-| Help texts go here | ** 23-| | ** +--------------------------------------------------------------------------------+ ** ** Help texts ** ** On a collapsed comment : ** ** [Enter] Expand device list [z] Expand all lists ** [TAB] Change fields [Q] Save and Exit ** ** On an expanded comment : ** ** [Enter] Collapse device list [Z] Collapse all lists ** [TAB] Change fields [Q] Save and Exit ** ** On a comment with no followers ** ** ** [TAB] Change fields [Q] Save and Exit ** ** On a device in the active list ** ** [Enter] Edit device parameters [DEL] Disable device ** [TAB] Change fields [Q] Save and Exit [?] Help ** ** On a device in the inactive list ** ** [Enter] Enable device ** [TAB] Change fields [Q] Save and Exit [?] Help ** ** While editing parameters ** ** ** [TAB] Change fields [Q] Save device parameters **/ /** ** ** The base-level screen primitives : ** ** bold() - enter bold mode \E[1m (md) ** inverse() - enter inverse mode \E[7m (so) ** normal() - clear bold/inverse mode \E[m (se) ** clear() - clear the screen \E[H\E[J (ce) ** move(x,y) - move the cursor to x,y \E[y;xH: (cm) **/ static void bold(void) { printf("\033[1m"); } static void inverse(void) { printf("\033[7m"); } static void normal(void) { printf("\033[m"); } static void clear(void) { normal(); printf("\033[H\033[J"); } static void move(int x, int y) { printf("\033[%d;%dH",y+1,x+1); } /** ** ** High-level screen primitives : ** ** putxyl(x,y,str,len) - put (len) bytes of (str) at (x,y), supports embedded formatting ** putxy(x,y,str) - put (str) at (x,y), supports embedded formatting ** erase(x,y,w,h) - clear the box (x,y,w,h) ** txtbox(x,y,w,y,str) - put (str) in a region at (x,y,w,h) ** putmsg(str) - put (str) in the message area ** puthelp(str) - put (str) in the upper helpline ** pad(str,len) - pad (str) to (len) with spaces ** drawline(row,detail,list,inverse,*dhelp) ** - draws a line for (*list) at (row) onscreen. If (detail) is ** nonzero, include port, IRQ and maddr, if (inverse) is nonzero, ** draw the line in inverse video, and display (*dhelp) on the ** helpline. ** drawlist(row,num,detail,list) ** - draw (num) entries from (list) at (row) onscreen, passile (detail) ** through to drawline(). ** showparams(dev) - displays the relevant parameters for (dev) below the lists onscreen. ** yesno(str) - displays (str) in the message area, and returns nonzero on 'y' or 'Y' ** redraw(); - Redraws the entire screen layout, including the ** - two list panels. **/ /** ** putxy ** writes (str) at x,y onscreen ** putxyl ** writes up to (len) of (str) at x,y onscreen. ** ** Supports embedded formatting : ** !i - inverse mode. ** !b - bold mode. ** !n - normal mode. **/ static void putxyl(int x, int y, char *str, int len) { move(x,y); normal(); while((*str) && (len--)) { if (*str == '!') /* format escape? */ { switch(*(str+1)) /* depending on the next character */ { case 'i': inverse(); str +=2; /* skip formatting */ len++; /* doesn't count for length */ break; case 'b': bold(); str +=2; /* skip formatting */ len++; /* doesn't count for length */ break; case 'n': normal(); str +=2; /* skip formatting */ len++; /* doesn't count for length */ break; default: putchar(*str++); /* not an escape */ } }else{ putchar(*str++); /* emit the character */ } } } #define putxy(x,y,str) putxyl(x,y,str,-1) /** ** erase ** ** Erases the region (x,y,w,h) **/ static void erase(int x, int y, int w, int h) { int i; normal(); for (i = 0; i < h; i++) putxyl(x,y++,spaces,w); } /** ** txtbox ** ** Writes (str) into the region (x,y,w,h), supports embedded formatting using ** putxy. Lines are not wrapped, newlines must be forced with \n. **/ static void txtbox(int x, int y, int w, int h, char *str) { int i = 0; h--; while((str[i]) && h) { if (str[i] == '\n') /* newline */ { putxyl(x,y,str,(i= len) /* no padding needed */ return; while(i < len) /* pad */ str[i++] = ' '; str[i] = '\0'; } /** ** drawline ** ** Displays entry (ofs) of (list) in region at (row) onscreen, optionally displaying ** the port and IRQ fields if (detail) is nonzero. If (inverse), in inverse video. ** ** The text (dhelp) is displayed if the item is a normal device, otherwise ** help is shown for normal or zoomed comments **/ static void drawline(int row, int detail, DEV_LIST *list, int inverse, char *dhelp) { char lbuf[90],nb[70],db[20],ib[16],pb[16]; if (list->comment == DEV_DEVICE) { nb[0] = ' '; strncpy(nb+1,list->name,57); }else{ strncpy(nb,list->name,58); if ((list->comment == DEV_ZOOMED) && (list->next)) if (list->next->comment == DEV_DEVICE) /* only mention if there's something hidden */ strcat(nb," (Collapsed)"); } nb[58] = '\0'; pad(nb,60); if (list->conflicts) /* device in conflict? */ if (inverse) { strcpy(nb+54," !nCONF!i "); /* tag conflict, careful of length */ }else{ strcpy(nb+54," !iCONF!n "); /* tag conflict, careful of length */ } if (list->comment == DEV_DEVICE) { sprintf(db,"%s%d",list->dev,list->unit); pad(db,8); }else{ strcpy(db," "); } if ((list->irq > 0) && detail && (list->comment == DEV_DEVICE)) { sprintf(ib," %d",list->irq); pad(ib,4); }else{ strcpy(ib," "); } if ((list->iobase > 0) && detail && (list->comment == DEV_DEVICE)) { sprintf(pb,"0x%x",list->iobase); pad(pb,7); }else{ strcpy(pb," "); } sprintf(lbuf," %s%s%s%s%s",inverse?"!i":"",nb,db,ib,pb); putxyl(0,row,lbuf,80); if (dhelp) { switch(list->comment) { case DEV_DEVICE: /* ordinary device */ puthelp(dhelp); break; case DEV_COMMENT: puthelp(""); if (list->next) if (list->next->comment == DEV_DEVICE) puthelp(" [!bEnter!n] Collapse device list [!bC!n] Collapse all lists"); break; case DEV_ZOOMED: puthelp(""); if (list->next) if (list->next->comment == DEV_DEVICE) puthelp(" [!bEnter!n] Expand device list [!bX!n] Expand all lists"); break; default: puthelp(" WARNING: This list entry corrupted!"); break; } } move(0,row); /* put the cursor somewhere relevant */ } /** ** drawlist ** ** Displays (num) lines of the contents of (list) at (row), optionally displaying the ** port and IRQ fields as well if (detail) is nonzero ** ** printf in the kernel is essentially useless, so we do most of the hard work ourselves here. **/ static void drawlist(int row, int num, int detail, DEV_LIST *list) { int ofs; for(ofs = 0; ofs < num; ofs++) { if (list) { drawline(row+ofs,detail,list,0,NULL); /* NULL -> don't draw empty help string */ list = nextent(list); /* move down visible list */ }else{ erase(0,row+ofs,80,1); } } } /** ** redrawactive ** ** Redraws the active list **/ static void redrawactive(void) { char cbuf[16]; if (conflicts) { sprintf(cbuf,"!i%d conflict%s-",conflicts,(conflicts>1)?"s":""); putxy(45,0,cbuf); }else{ putxyl(45,0,lines,16); } drawlist(1,8,1,alist); /* draw device lists */ } /** ** redrawinactive ** ** Redraws the inactive list **/ static void redrawinactive(void) { drawlist(10,7,0,ilist); /* draw device lists */ } /** ** redraw ** ** Clear the screen and redraw the entire layout **/ static void redraw(void) { clear(); putxy(0,0,lines); putxy(3,0,"!bActive!n-!bDrivers"); putxy(63,0,"!bDev!n---!bIRQ!n--!bPort"); putxy(0,9,lines); putxy(3,9,"!bInactive!n-!bDrivers"); putxy(63,9,"!bDev"); putxy(0,17,lines); putxy(0,21,lines); masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save and Exit [!b?!n] Help"); redrawactive(); redrawinactive(); } /** ** yesnocancel ** ** Put (str) in the message area, and return 1 if the user hits 'y' or 'Y', ** 2 if they hit 'c' or 'C', or 0 for 'n' or 'N'. **/ static int yesnocancel(char *str) { putmsg(str); for(;;) switch(getchar()) { case -1: case 'n': case 'N': return(0); case 'y': case 'Y': return(1); case 'c': case 'C': return(2); } } /** ** showparams ** ** Show device parameters in the region below the lists ** ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75 ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|.... ** +--------------------------------------------------------------------------------+ ** 17-|--------------------------------------------------------------------------------| ** 18-| Port address : 0x0000 Memory address : 0x00000 Conflict allowed | ** 19-| IRQ number : 00 Memory size : 0x0000 | ** 20-| Flags : 0x0000 DRQ number : 00 | ** 21-|--------------------------------------------------------------------------------| **/ static void showparams(DEV_LIST *dev) { char buf[80]; erase(0,18,80,3); /* clear area */ if (!dev) return; if (dev->comment != DEV_DEVICE) return; if (dev->iobase > 0) { sprintf(buf,"Port address : 0x%x",dev->iobase); putxy(1,18,buf); } else { if (dev->iobase == -2) /* a PCI device */ putmsg(" PCI devices are displayed for informational purposes only, and\n" " cannot be disabled or configured here."); } if (dev->irq > 0) { sprintf(buf,"IRQ number : %d",dev->irq); putxy(1,19,buf); } sprintf(buf,"Flags : 0x%x",dev->flags); putxy(1,20,buf); if (dev->maddr > 0) { sprintf(buf,"Memory address : 0x%x",dev->maddr); putxy(26,18,buf); } if (dev->msize > 0) { sprintf(buf,"Memory size : 0x%x",dev->msize); putxy(26,19,buf); } if (dev->drq > 0) { sprintf(buf,"DRQ number : %d",dev->drq); putxy(26,20,buf); } if (dev->conflict_ok) putxy(54,18,"Conflict allowed"); } /** ** Editing functions for device parameters ** ** editval(x,y,width,hex,min,max,val) - Edit (*val) in a field (width) wide at (x,y) ** onscreen. Refuse values outsise (min) and (max). ** editparams(dev) - Edit the parameters for (dev) **/ #define VetRet(code) \ { \ if ((i >= min) && (i <= max)) /* legit? */ \ { \ *val = i; \ sprintf(buf,hex?"0x%x":"%d",i); \ putxy(hex?x-2:x,y,buf); \ return(code); /* all done and exit */ \ } \ i = *val; /* restore original value */ \ delta = 1; /* restore other stuff */ \ } /** ** editval ** ** Edit (*val) at (x,y) in (hex)?hex:decimal mode, allowing values between (min) and (max) ** in a field (width) wide. (Allow one space) ** If (ro) is set, we're in "readonly" mode, so disallow edits. ** ** Return KEY_TAB on \t, KEY_EXIT on 'q' **/ static int editval(int x, int y, int width, int hex, int min, int max, int *val, int ro) { int i = *val; /* work with copy of the value */ char buf[2+11+1],tc[11+1]; /* display buffer, text copy */ int xp = 0; /* cursor offset into text copy */ int delta = 1; /* force redraw first time in */ int c; int extended = 0; /* stage counter for extended key sequences */ if (hex) /* we presume there's a leading 0x onscreen */ putxy(x-2,y,"!i0x"); /* coz there sure is now */ for (;;) { if (delta) /* only update if necessary */ { sprintf(tc,hex?"%x":"%d",i); /* make a text copy of the value */ sprintf(buf,"!i%s",tc); /* format for printing */ erase(x,y,width,1); /* clear the area */ putxy(x,y,buf); /* write */ xp = strlen(tc); /* cursor always at end */ move(x+xp,y); /* position the cursor */ } c = getchar(); switch(extended) /* escape handling */ { case 0: if (c == 0x1b) /* esc? */ { extended = 1; /* flag and spin */ continue; } extended = 0; break; /* nope, drop through */ case 1: /* there was an escape prefix */ if (c == '[' || c == 'O') /* second character in sequence */ { extended = 2; continue; } if (c == 0x1b) return(KEY_EXIT); /* double esc exits */ extended = 0; break; /* nup, not a sequence. */ case 2: extended = 0; switch(c) /* looks like the real McCoy */ { case 'A': VetRet(KEY_UP); /* leave if OK */ continue; case 'B': VetRet(KEY_DOWN); /* leave if OK */ continue; case 'C': VetRet(KEY_RIGHT); /* leave if OK */ continue; case 'D': VetRet(KEY_LEFT); /* leave if OK */ continue; default: continue; } } switch(c) { case '\t': /* trying to tab off */ VetRet(KEY_TAB); /* verify and maybe return */ break; case -1: case 'q': case 'Q': VetRet(KEY_EXIT); break; case '\b': case '\177': /* BS or DEL */ if (ro) /* readonly? */ { puthelp(" !iThis value cannot be edited (Press ESC)"); while(getchar() != 0x1b); /* wait for key */ return(KEY_NULL); /* spin */ } if (xp) /* still something left to delete */ { i = (hex ? i/0x10u : i/10); /* strip last digit */ delta = 1; /* force update */ } break; case 588: VetRet(KEY_UP); break; case '\r': case '\n': case 596: VetRet(KEY_DOWN); break; case 591: VetRet(KEY_LEFT); break; case 593: VetRet(KEY_RIGHT); break; default: if (ro) /* readonly? */ { puthelp(" !iThis value cannot be edited (Press ESC)"); while(getchar() != 0x1b); /* wait for key */ return(KEY_NULL); /* spin */ } if (xp >= width) /* no room for more characters anyway */ break; if (hex) { if ((c >= '0') && (c <= '9')) { i = i*0x10 + (c-'0'); /* update value */ delta = 1; break; } if ((c >= 'a') && (c <= 'f')) { i = i*0x10 + (c-'a'+0xa); delta = 1; break; } if ((c >= 'A') && (c <= 'F')) { i = i*0x10 + (c-'A'+0xa); delta = 1; break; } }else{ if ((c >= '0') && (c <= '9')) { i = i*10 + (c-'0'); /* update value */ delta = 1; /* force redraw */ break; } } break; } } } /** ** editparams ** ** Edit the parameters for (dev) ** ** Note that it's _always_ possible to edit the flags, otherwise it might be ** possible for this to spin in an endless loop... ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75 ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|.... ** +--------------------------------------------------------------------------------+ ** 17-|--------------------------------------------------------------------------------| ** 18-| Port address : 0x0000 Memory address : 0x00000 Conflict allowed | ** 19-| IRQ number : 00 Memory size : 0x0000 | ** 20-| Flags : 0x0000 DRQ number : 00 | ** 21-|--------------------------------------------------------------------------------| ** ** The "intelligence" in this function that hops around based on the directional ** returns from editval isn't very smart, and depends on the layout above. **/ static void editparams(DEV_LIST *dev) { int ret; char buf[16]; /* needs to fit the device name */ putxy(2,17,"!bParameters!n-!bfor!n-!bdevice!n-"); sprintf(buf,"!b%s",dev->dev); putxy(24,17,buf); erase(1,22,80,1); for (;;) { ep_iobase: if (dev->iobase > 0) { puthelp(" IO Port address (Hexadecimal, 0x1-0xffff)"); ret = editval(18,18,5,1,0x1,0xffff,&(dev->iobase),(dev->attrib & FLG_FIXIOBASE)); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_RIGHT: if (dev->maddr > 0) goto ep_maddr; break; case KEY_TAB: case KEY_DOWN: goto ep_irq; } goto ep_iobase; } ep_irq: if (dev->irq > 0) { puthelp(" Interrupt number (Decimal, 1-15)"); ret = editval(16,19,3,0,1,15,&(dev->irq),(dev->attrib & FLG_FIXIRQ)); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_RIGHT: if (dev->msize > 0) goto ep_msize; break; case KEY_UP: if (dev->iobase > 0) goto ep_iobase; break; case KEY_TAB: case KEY_DOWN: goto ep_flags; } goto ep_irq; } ep_flags: puthelp(" Device-specific flag values."); ret = editval(18,20,8,1,INT_MIN,INT_MAX,&(dev->flags),0); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_RIGHT: if (dev->drq > 0) goto ep_drq; break; case KEY_UP: if (dev->irq > 0) goto ep_irq; if (dev->iobase > 0) goto ep_iobase; break; case KEY_DOWN: if (dev->maddr > 0) goto ep_maddr; if (dev->msize > 0) goto ep_msize; if (dev->drq > 0) goto ep_drq; break; case KEY_TAB: goto ep_maddr; } goto ep_flags; ep_maddr: if (dev->maddr > 0) { puthelp(" Device memory start address (Hexadecimal, 0x1-0xfffff)"); ret = editval(45,18,6,1,0x1,0xfffff,&(dev->maddr),(dev->attrib & FLG_FIXMADDR)); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_LEFT: if (dev->iobase > 0) goto ep_iobase; break; case KEY_UP: goto ep_flags; case KEY_DOWN: if (dev->msize > 0) goto ep_msize; if (dev->drq > 0) goto ep_drq; break; case KEY_TAB: goto ep_msize; } goto ep_maddr; } ep_msize: if (dev->msize > 0) { puthelp(" Device memory size (Hexadecimal, 0x1-0x10000)"); ret = editval(45,19,5,1,0x1,0x10000,&(dev->msize),(dev->attrib & FLG_FIXMSIZE)); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_LEFT: if (dev->irq > 0) goto ep_irq; break; case KEY_UP: if (dev->maddr > 0) goto ep_maddr; goto ep_flags; case KEY_DOWN: if (dev->drq > 0) goto ep_drq; break; case KEY_TAB: goto ep_drq; } goto ep_msize; } ep_drq: if (dev->drq > 0) { puthelp(" Device DMA request number (Decimal, 1-7)"); ret = editval(43,20,2,0,1,7,&(dev->drq),(dev->attrib & FLG_FIXDRQ)); switch(ret) { case KEY_EXIT: goto ep_exit; case KEY_LEFT: goto ep_flags; case KEY_UP: if (dev->msize > 0) goto ep_msize; if (dev->maddr > 0) goto ep_maddr; goto ep_flags; case KEY_TAB: goto ep_iobase; } goto ep_drq; } } ep_exit: dev->changed = 1; /* mark as changed */ } static char *helptext[] = { " Using the UserConfig kernel settings editor", " -------------------------------------------", "", "VISUAL MODE:", "", "- - Layout -", "", "The screen displays a list of available drivers, divided into two", "scrolling lists: Active Drivers, and Inactive Drivers. Each list is", "by default collapsed and can be expanded to show all the drivers", "available in each category. The parameters for the currently selected", "driver are shown at the bottom of the screen.", "", "- - Moving around -", "", "To move in the current list, use the UP and DOWN cursor keys to select", "an item (the selected item will be highlighted). If the item is a", "category name, you may alternatively expand or collapse the list of", "drivers for that category by pressing [!bENTER!n]. Once the category is", "expanded, you can select each driver in the same manner and either:", "", " - change its parameters using [!bENTER!n]", " - move it to the Inactive list using [!bDEL!n]", "", "Use the [!bTAB!n] key to toggle between the Active and Inactive list; if", "you need to move a driver from the Inactive list back to the Active", "one, select it in the Inactive list, using [!bTAB!n] to change lists if", "necessary, and press [!bENTER!n] -- the device will be moved back to", "its place in the Active list.", "", "- - Altering the list/parameters -", "", "Any drivers for devices not installed in your system should be moved", "to the Inactive list, until there are no remaining parameter conflicts", "between the drivers, as indicated at the top.", "", "Once the list of Active drivers only contains entries for the devices", "present in your system, you can set their parameters (Interrupt, DMA", "channel, I/O addresses). To do this, select the driver and press", "[!bENTER!n]: it is now possible to edit the settings the settings at the", "bottom of the screen. Use [!bTAB!n] to change fields, and when you are", "finished, use [!bQ!n] to return to the list.", "", "- - Saving changes -", "", "When all settings seem correct, and you wish to proceed with the", "kernel device probing and boot, press [!bQ!n] -- you will be asked to", "confirm your choice.", "", NULL }; /** ** helpscreen ** ** Displays help text onscreen for people that are confused, using a simple ** pager. **/ static void helpscreen(void) { int topline = 0; /* where we are in the text */ int c, delta = 1; char prompt[80]; for (;;) /* loop until user quits */ { int line = 0; /* display help text */ if (delta) { clear(); /* remove everything else */ for (line = topline; (line < (topline + 24)) && (helptext[line]); line++) putxy(0,line-topline,helptext[line]); delta = 0; } /* prompt */ sprintf(prompt,"!i --%s-- [U]p [D]own [Q]uit !n",helptext[line] ? "MORE" : "END"); putxy(0,24,prompt); c = getchar(); /* so what do they say? */ switch (c) { case 'u': case 'U': case 'b': case 'B': /* wired into 'more' users' fingers */ if (topline > 0) /* room to go up? */ { topline -= 24; if (topline < 0) /* don't go too far */ topline = 0; delta = 1; } break; case 'd': case 'D': case ' ': /* expected by most people */ if (helptext[line]) /* maybe more below? */ { topline += 24; delta = 1; } break; case 'q': case 'Q': redraw(); /* restore the screen */ return; } } } /** ** High-level control functions **/ /** ** dolist ** ** Handle user movement within (*list) in the region starting at (row) onscreen with ** (num) lines, starting at (*ofs) offset from row onscreen. ** Pass (detail) on to drawing routines. ** ** If the user hits a key other than a cursor key, maybe return a code. ** ** (*list) points to the device at the top line in the region, (*ofs) is the ** position of the highlight within the region. All routines below ** this take only a device and an absolute row : use ofsent() to find the ** device, and add (*ofs) to (row) to find the absolute row. **/ static int dolist(int row, int num, int detail, int *ofs, DEV_LIST **list, char *dhelp) { int extended = 0; int c; DEV_LIST *lp; int delta = 1; for(;;) { if (delta) { showparams(ofsent(*ofs,*list)); /* show device parameters */ drawline(row+*ofs,detail,ofsent(*ofs,*list),1,dhelp); /* highlight current line */ delta = 0; } c = getchar(); /* get a character */ if ((extended == 2) || (c==588) || (c==596)) /* console gives "alternative" codes */ { extended = 0; /* no longer */ switch(c) { case 588: /* syscons' idea of 'up' */ case 'A': /* up */ if (*ofs) /* just a move onscreen */ { drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp);/* unhighlight current line */ (*ofs)--; /* move up */ }else{ lp = prevent(*list); /* can we go up? */ if (!lp) /* no */ break; *list = lp; /* yes, move up list */ drawlist(row,num,detail,*list); } delta = 1; break; case 596: /* dooby-do */ case 'B': /* down */ lp = ofsent(*ofs,*list); /* get current item */ if (!nextent(lp)) break; /* nothing more to move to */ drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp); /* unhighlight current line */ if (*ofs < (num-1)) /* room to move onscreen? */ { (*ofs)++; }else{ *list = nextent(*list); /* scroll region down */ drawlist(row,num,detail,*list); } delta = 1; break; } }else{ switch(c) { case '\033': extended=1; break; case '[': /* cheat : always preceeds cursor move */ case 'O': /* ANSI application key mode */ if (extended==1) extended=2; else extended=0; break; case 'Q': case 'q': return(KEY_EXIT); /* user requests exit */ case '\r': case '\n': return(KEY_DO); /* "do" something */ case '\b': case '\177': case 599: return(KEY_DEL); /* "delete" response */ case 'X': case 'x': return(KEY_UNZOOM); /* expand everything */ case 'C': case 'c': return(KEY_ZOOM); /* collapse everything */ case '\t': drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp); /* unhighlight current line */ return(KEY_TAB); /* "move" response */ case '\014': /* ^L, redraw */ return(KEY_REDRAW); case '?': /* helptext */ return(KEY_HELP); } } } } /** ** visuserconfig ** ** Do the fullscreen config thang **/ static int visuserconfig(void) { int actofs = 0, inactofs = 0, mode = 0, ret = -1, i; DEV_LIST *dp; initlist(&active); initlist(&inactive); alist = active; ilist = inactive; getdevs(); conflicts = findconflict(active); /* find conflicts in the active list only */ redraw(); for(;;) { switch(mode) { case 0: /* active devices */ ret = dolist(1,8,1,&actofs,&alist, " [!bEnter!n] Edit device parameters [!bDEL!n] Disable device"); switch(ret) { case KEY_TAB: mode = 1; /* swap lists */ break; case KEY_REDRAW: redraw(); break; case KEY_ZOOM: alist = active; actofs = 0; expandlist(active); redrawactive(); break; case KEY_UNZOOM: alist = active; actofs = 0; collapselist(active); redrawactive(); break; case KEY_DEL: dp = ofsent(actofs,alist); /* get current device */ if (dp) /* paranoia... */ { if (dp->attrib & FLG_MANDATORY) /* can't be deleted */ break; if (dp == alist) /* moving top item on list? */ { if (dp->next) { alist = dp->next; /* point list to non-moving item */ }else{ alist = dp->prev; /* end of list, go back instead */ } }else{ if (!dp->next) /* moving last item on list? */ actofs--; } dp->conflicts = 0; /* no conflicts on the inactive list */ movedev(dp,inactive); /* shift to inactive list */ conflicts = findconflict(active); /* update conflict tags */ dp->changed = 1; redrawactive(); /* redraw */ redrawinactive(); } break; case KEY_DO: /* edit device parameters */ dp = ofsent(actofs,alist); /* get current device */ if (dp) /* paranoia... */ { if (dp->comment == DEV_DEVICE) /* can't edit comments, zoom? */ { if (dp->iobase != -2) /* can't edit PCI devices */ { masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save device parameters"); editparams(dp); masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save and Exit [!b?!n] Help"); putxy(0,17,lines); conflicts = findconflict(active); /* update conflict tags */ } }else{ /* DO on comment = zoom */ switch(dp->comment) /* Depends on current state */ { case DEV_COMMENT: /* not currently zoomed */ dp->comment = DEV_ZOOMED; break; case DEV_ZOOMED: dp->comment = DEV_COMMENT; break; } } redrawactive(); } break; } break; case 1: /* inactive devices */ ret = dolist(10,7,0,&inactofs,&ilist, " [!bEnter!n] Enable device "); switch(ret) { case KEY_TAB: mode = 0; break; case KEY_REDRAW: redraw(); break; case KEY_ZOOM: ilist = inactive; inactofs = 0; expandlist(inactive); redrawinactive(); break; case KEY_UNZOOM: ilist = inactive; inactofs = 0; collapselist(inactive); redrawinactive(); break; case KEY_DO: dp = ofsent(inactofs,ilist); /* get current device */ if (dp) /* paranoia... */ { if (dp->comment == DEV_DEVICE) /* can't move comments, zoom? */ { if (dp == ilist) /* moving top of list? */ { if (dp->next) { ilist = dp->next; /* point list to non-moving item */ }else{ ilist = dp->prev; /* can't go down, go up instead */ } }else{ if (!dp->next) /* last entry on list? */ inactofs--; /* shift cursor up one */ } movedev(dp,active); /* shift to active list */ conflicts = findconflict(active); /* update conflict tags */ dp->changed = 1; alist = dp; /* put at top and current */ actofs = 0; while(dp->comment == DEV_DEVICE) dp = dp->prev; /* forcibly unzoom section */ dp ->comment = DEV_COMMENT; mode = 0; /* and swap modes to follow it */ }else{ /* DO on comment = zoom */ switch(dp->comment) /* Depends on current state */ { case DEV_COMMENT: /* not currently zoomed */ dp->comment = DEV_ZOOMED; break; case DEV_ZOOMED: dp->comment = DEV_COMMENT; break; } } redrawactive(); /* redraw */ redrawinactive(); } break; default: /* nothing else relevant here */ break; } break; default: mode = 0; /* shouldn't happen... */ } /* handle returns that are the same for both modes */ switch (ret) { case KEY_HELP: helpscreen(); break; case KEY_EXIT: i = yesnocancel(" Save these parameters before exiting? ([!bY!n]es/[!bN!n]o/[!bC!n]ancel) "); switch(i) { case 2: /* cancel */ redraw(); break; case 1: /* save and exit */ savelist(active,1); savelist(inactive,0); case 0: /* exit */ nukelist(active); /* clean up after ourselves */ nukelist(inactive); normal(); clear(); return(1); } break; } } } #endif /* VISUAL_USERCONFIG */ /* * Copyright (c) 1991 Regents of the University of California. * All rights reserved. * Copyright (c) 1994 Jordan K. Hubbard * All rights reserved. * Copyright (c) 1994 David Greenman * All rights reserved. * * Many additional changes by Bruce Evans * * This code is derived from software contributed by the * University of California Berkeley, Jordan K. Hubbard, * David Greenman and Bruce Evans. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: userconfig.c,v 1.126.2.5 1999/05/15 18:19:37 obrien Exp $ + * $Id: userconfig.c,v 1.126.2.6 1999/06/19 21:37:40 wpaul Exp $ */ #include "scbus.h" #define PARM_DEVSPEC 0x1 #define PARM_INT 0x2 #define PARM_ADDR 0x3 #define PARM_STRING 0x4 typedef struct _cmdparm { int type; union { struct isa_device *dparm; int iparm; void *aparm; } parm; } CmdParm; typedef int (*CmdFunc)(CmdParm *); typedef struct _cmd { char *name; CmdFunc handler; CmdParm *parms; } Cmd; #if 0 static void lsscsi(void); static int list_scsi(CmdParm *); #endif static int lsdevtab(struct isa_device *); static struct isa_device *find_device(char *, int); static struct isa_device *search_devtable(struct isa_device *, char *, int); static void cngets(char *, int); static Cmd *parse_cmd(char *); static int parse_args(char *, CmdParm *); static unsigned long strtoul(const char *, char **, int); static int save_dev(struct isa_device *); static int list_devices(CmdParm *); static int set_device_ioaddr(CmdParm *); static int set_device_irq(CmdParm *); static int set_device_drq(CmdParm *); static int set_device_iosize(CmdParm *); static int set_device_mem(CmdParm *); static int set_device_flags(CmdParm *); static int set_device_enable(CmdParm *); static int set_device_disable(CmdParm *); static int quitfunc(CmdParm *); static int helpfunc(CmdParm *); #if defined(INTRO_USERCONFIG) static int introfunc(CmdParm *); #endif #if NPNP > 0 static int lspnp(void); static int set_pnp_parms(CmdParm *); #endif static int lineno; #include "eisa.h" #if NEISA > 0 #include static int set_num_eisa_slots(CmdParm *); #endif /* NEISA > 0 */ static CmdParm addr_parms[] = { { PARM_DEVSPEC, {} }, { PARM_ADDR, {} }, { -1, {} }, }; static CmdParm int_parms[] = { { PARM_DEVSPEC, {} }, { PARM_INT, {} }, { -1, {} }, }; static CmdParm dev_parms[] = { { PARM_DEVSPEC, {} }, { -1, {} }, }; #if NPNP > 0 static CmdParm string_arg[] = { { PARM_STRING, {} }, { -1, {} }, }; #endif #if NEISA > 0 static CmdParm int_arg[] = { { PARM_INT, {} }, { -1, {} }, }; #endif /* NEISA > 0 */ static Cmd CmdList[] = { { "?", helpfunc, NULL }, /* ? (help) */ { "di", set_device_disable, dev_parms }, /* disable dev */ { "dr", set_device_drq, int_parms }, /* drq dev # */ #if NEISA > 0 { "ei", set_num_eisa_slots, int_arg }, /* # EISA slots */ #endif /* NEISA > 0 */ { "en", set_device_enable, dev_parms }, /* enable dev */ { "ex", quitfunc, NULL }, /* exit (quit) */ { "f", set_device_flags, int_parms }, /* flags dev mask */ { "h", helpfunc, NULL }, /* help */ #if defined(INTRO_USERCONFIG) { "intro", introfunc, NULL }, /* intro screen */ #endif { "iom", set_device_mem, addr_parms }, /* iomem dev addr */ { "ios", set_device_iosize, int_parms }, /* iosize dev size */ { "ir", set_device_irq, int_parms }, /* irq dev # */ { "l", list_devices, NULL }, /* ls, list */ #if NPNP > 0 { "pn", set_pnp_parms, string_arg }, /* pnp ... */ #endif { "po", set_device_ioaddr, int_parms }, /* port dev addr */ { "res", (CmdFunc)cpu_reset, NULL }, /* reset CPU */ { "q", quitfunc, NULL }, /* quit */ #if 0 { "s", list_scsi, NULL }, /* scsi */ #endif #ifdef VISUAL_USERCONFIG { "v", (CmdFunc)visuserconfig, NULL }, /* visual mode */ #endif { NULL, NULL, NULL }, }; void userconfig(void) { static char banner = 1; char input[80]; int rval; Cmd *cmd; init_config_script(); while (1) { /* Only display signon banner if we are about to go interactive */ if (!has_config_script()) { if (!(boothowto & RB_CONFIG)) #ifdef INTRO_USERCONFIG banner = 0; #else return; #endif if (banner) { banner = 0; printf("FreeBSD Kernel Configuration Utility - Version 1.2\n" " Type \"help\" for help" #ifdef VISUAL_USERCONFIG " or \"visual\" to go to the visual\n" " configuration interface (requires MGA/VGA display or\n" " serial terminal capable of displaying ANSI graphics)" #endif ".\n"); } } printf("config> "); cngets(input, 80); if (input[0] == '\0') continue; cmd = parse_cmd(input); if (!cmd) { printf("Invalid command or syntax. Type `?' for help.\n"); continue; } rval = (*cmd->handler)(cmd->parms); if (rval) return; } } static Cmd * parse_cmd(char *cmd) { Cmd *cp; for (cp = CmdList; cp->name; cp++) { int len = strlen(cp->name); if (!strncmp(cp->name, cmd, len)) { while (*cmd && *cmd != ' ' && *cmd != '\t') ++cmd; if (parse_args(cmd, cp->parms)) return NULL; else return cp; } } return NULL; } static int parse_args(char *cmd, CmdParm *parms) { while (1) { char *ptr; if (*cmd == ' ' || *cmd == '\t') { ++cmd; continue; } if (parms == NULL || parms->type == -1) { if (*cmd == '\0') return 0; printf("Extra arg(s): %s\n", cmd); return 1; } if (parms->type == PARM_DEVSPEC) { int i = 0; char devname[64]; int unit = 0; while (*cmd && !(*cmd == ' ' || *cmd == '\t' || (*cmd >= '0' && *cmd <= '9'))) devname[i++] = *(cmd++); devname[i] = '\0'; if (*cmd >= '0' && *cmd <= '9') { unit = strtoul(cmd, &ptr, 10); if (cmd == ptr) { printf("Invalid device number\n"); /* XXX should print invalid token here and elsewhere. */ return 1; } /* XXX else should require end of token. */ cmd = ptr; } if ((parms->parm.dparm = find_device(devname, unit)) == NULL) { printf("No such device: %s%d\n", devname, unit); return 1; } ++parms; continue; } if (parms->type == PARM_INT) { parms->parm.iparm = strtoul(cmd, &ptr, 0); if (cmd == ptr) { printf("Invalid numeric argument\n"); return 1; } cmd = ptr; ++parms; continue; } if (parms->type == PARM_ADDR) { parms->parm.aparm = (void *)(uintptr_t)strtoul(cmd, &ptr, 0); if (cmd == ptr) { printf("Invalid address argument\n"); return 1; } cmd = ptr; ++parms; continue; } if (parms->type == PARM_STRING) { parms->parm.aparm = (void *)cmd ; return 0; } } return 0; } static int list_devices(CmdParm *parms) { lineno = 0; if (lsdevtab(&isa_devtab_bio[0])) return 0; if (lsdevtab(&isa_devtab_tty[0])) return 0; if (lsdevtab(&isa_devtab_net[0])) return 0; if (lsdevtab(&isa_devtab_cam[0])) return 0; if (lsdevtab(&isa_devtab_null[0])) return 0; #if NPNP > 0 if (lspnp()) return 0; #endif #if NEISA > 0 printf("\nNumber of EISA slots to probe: %d\n", num_eisa_slots); #endif /* NEISA > 0 */ return 0; } static int set_device_ioaddr(CmdParm *parms) { parms[0].parm.dparm->id_iobase = parms[1].parm.iparm; save_dev(parms[0].parm.dparm); return 0; } static int set_device_irq(CmdParm *parms) { unsigned irq; irq = parms[1].parm.iparm; if (irq == 2) { printf("Warning: Remapping IRQ 2 to IRQ 9 - see config(8)\n"); irq = 9; } else if (irq != -1 && irq > 15) { printf("An IRQ > 15 would be invalid.\n"); return 0; } parms[0].parm.dparm->id_irq = (irq < 16 ? 1 << irq : 0); save_dev(parms[0].parm.dparm); return 0; } static int set_device_drq(CmdParm *parms) { unsigned drq; /* * The bounds checking is just to ensure that the value can be printed * in 5 characters. 32768 gets converted to -32768 and doesn't fit. */ drq = parms[1].parm.iparm; parms[0].parm.dparm->id_drq = (drq < 32768 ? drq : -1); save_dev(parms[0].parm.dparm); return 0; } static int set_device_iosize(CmdParm *parms) { parms[0].parm.dparm->id_msize = parms[1].parm.iparm; save_dev(parms[0].parm.dparm); return 0; } static int set_device_mem(CmdParm *parms) { parms[0].parm.dparm->id_maddr = parms[1].parm.aparm; save_dev(parms[0].parm.dparm); return 0; } static int set_device_flags(CmdParm *parms) { parms[0].parm.dparm->id_flags = parms[1].parm.iparm; save_dev(parms[0].parm.dparm); return 0; } static int set_device_enable(CmdParm *parms) { parms[0].parm.dparm->id_enabled = TRUE; save_dev(parms[0].parm.dparm); return 0; } static int set_device_disable(CmdParm *parms) { parms[0].parm.dparm->id_enabled = FALSE; save_dev(parms[0].parm.dparm); return 0; } #if NPNP > 0 static int sysctl_machdep_uc_pnplist SYSCTL_HANDLER_ARGS { int error=0; if(!req->oldptr) { /* Only sizing */ return(SYSCTL_OUT(req,0,sizeof(struct pnp_cinfo)*MAX_PNP_LDN)); } else { /* * Output the pnp_ldn_overrides[] table. */ error=sysctl_handle_opaque(oidp,&pnp_ldn_overrides, sizeof(struct pnp_cinfo)*MAX_PNP_LDN,req); if(error) return(error); return(0); } } SYSCTL_PROC( _machdep, OID_AUTO, uc_pnplist, CTLFLAG_RD, 0, 0, sysctl_machdep_uc_pnplist, "A", "List of PnP overrides changed in UserConfig"); /* * this function sets the kernel table to override bios PnP * configuration. */ static int set_pnp_parms(CmdParm *parms) { u_long idx, val, ldn, csn; int i; char *q, *p=parms[0].parm.aparm; struct pnp_cinfo d; csn=strtoul(p,&q, 0); ldn=strtoul(q,&q, 0); for (p=q; *p && (*p==' ' || *p=='\t'); p++) ; if (csn < 1 || csn > MAX_PNP_CARDS || ldn >= MAX_PNP_LDN) { printf("bad csn/ldn %ld:%ld\n", csn, ldn); return 0; } for (i=0; i < MAX_PNP_LDN; i++) { if (pnp_ldn_overrides[i].csn == csn && pnp_ldn_overrides[i].ldn == ldn) break; } if (i==MAX_PNP_LDN) { for (i=0; i < MAX_PNP_LDN; i++) { if (pnp_ldn_overrides[i].csn <1 || pnp_ldn_overrides[i].csn > MAX_PNP_CARDS) break; } } if (i==MAX_PNP_LDN) { printf("sorry, no PnP entries available, try delete one\n"); return 0 ; } d = pnp_ldn_overrides[i] ; d.csn = csn; d.ldn = ldn ; while (*p) { idx = 0; val = 0; if (!strncmp(p,"irq",3)) { idx=strtoul(p+3,&q, 0); val=strtoul(q,&q, 0); if (idx >=0 && idx < 2) d.irq[idx] = val; } else if (!strncmp(p,"flags",5)) { idx=strtoul(p+5,&q, 0); d.flags = idx; } else if (!strncmp(p,"drq",3)) { idx=strtoul(p+3,&q, 0); val=strtoul(q,&q, 0); if (idx >=0 && idx < 2) d.drq[idx] = val; } else if (!strncmp(p,"port",4)) { idx=strtoul(p+4,&q, 0); val=strtoul(q,&q, 0); if (idx >=0 && idx < 8) d.port[idx] = val; } else if (!strncmp(p,"mem",3)) { idx=strtoul(p+3,&q, 0); val=strtoul(q,&q, 0); if (idx >=0 && idx < 4) d.mem[idx].base = val; } else if (!strncmp(p,"bios",4)) { q = p+ 4; d.override = 0 ; } else if (!strncmp(p,"os",2)) { q = p+2 ; d.override = 1 ; } else if (!strncmp(p,"disable",7)) { q = p+7 ; d.enable = 0 ; } else if (!strncmp(p,"enable",6)) { q = p+6; d.enable = 1 ; } else if (!strncmp(p,"delete",6)) { bzero(&pnp_ldn_overrides[i], sizeof (pnp_ldn_overrides[i])); if (i==0) pnp_ldn_overrides[i].csn = 255;/* not reinit */ return 0; } else { printf("unknown command <%s>\n", p); break; } for (p=q; *p && (*p==' ' || *p=='\t'); p++) ; } pnp_ldn_overrides[i] = d ; return 0; } #endif /* NPNP */ #if NEISA > 0 static int set_num_eisa_slots(CmdParm *parms) { int num_slots; num_slots = parms[0].parm.iparm; num_eisa_slots = (num_slots <= 16 ? num_slots : 10); return 0; } #endif /* NEISA > 0 */ static int quitfunc(CmdParm *parms) { /* * If kernel config supplied, and we are parsing it, and -c also supplied, * ignore a quit command, This provides a safety mechanism to allow * recovery from a damaged/buggy kernel config. */ if ((boothowto & RB_CONFIG) && userconfig_boot_parsing) return 0; return 1; } static int helpfunc(CmdParm *parms) { printf( "Command\t\t\tDescription\n" "-------\t\t\t-----------\n" "ls\t\t\tList currently configured devices\n" "port \tSet device port (i/o address)\n" "irq \tSet device irq\n" "drq \tSet device drq\n" "iomem \tSet device maddr (memory address)\n" "iosize \tSet device memory size\n" "flags \tSet device flags\n" "enable \tEnable device\n" "disable \tDisable device (will not be probed)\n"); #if NPNP > 0 printf( "pnp [enable|disable]\tenable/disable device\n" "pnp [os|bios]\tset parameters using FreeBSD or BIOS\n" "pnp [portX ]\tset addr for port X (0..7)\n" "pnp [memX ]\tset addr for memory range X (0..3)\n" "pnp [irq ]\tset irq X (0..1) to number, 0=unused\n" "pnp [drq ]\tset drq X (0..1) to number, 4=unused\n"); #endif #if NEISA > 0 printf("eisa \t\tSet the number of EISA slots to probe\n"); #endif /* NEISA > 0 */ printf( "quit\t\t\tExit this configuration utility\n" "reset\t\t\tReset CPU\n"); #ifdef VISUAL_USERCONFIG printf("visual\t\t\tGo to fullscreen mode.\n"); #endif printf( "help\t\t\tThis message\n\n" "Commands may be abbreviated to a unique prefix\n"); return 0; } #if defined(INTRO_USERCONFIG) #if defined (VISUAL_USERCONFIG) static void center(int y, char *str) { putxy((80 - strlen(str)) / 2, y, str); } #endif static int introfunc(CmdParm *parms) { #if defined (VISUAL_USERCONFIG) int curr_item, first_time, extended = 0; static char *choices[] = { " Skip kernel configuration and continue with installation ", " Start kernel configuration in full-screen visual mode ", " Start kernel configuration in CLI mode ", }; clear(); center(2, "!bKernel Configuration Menu!n"); curr_item = 0; first_time = 1; while (1) { char tmp[80]; int c, i; if (!extended) { for (i = 0; i < 3; i++) { tmp[0] = '\0'; if (curr_item == i) strcpy(tmp, "!i"); strcat(tmp, choices[i]); if (curr_item == i) strcat(tmp, "!n"); putxy(10, 5 + i, tmp); } if (first_time) { putxy(2, 10, "Here you have the chance to go into kernel configuration mode, making"); putxy(2, 11, "any changes which may be necessary to properly adjust the kernel to"); putxy(2, 12, "match your hardware configuration."); putxy(2, 14, "If you are installing FreeBSD for the first time, select Visual Mode"); putxy(2, 15, "(press Down-Arrow then ENTER)."); putxy(2, 17, "If you need to do more specialized kernel configuration and are an"); putxy(2, 18, "experienced FreeBSD user, select CLI mode."); putxy(2, 20, "If you are !icertain!n that you do not need to configure your kernel"); putxy(2, 21, "then simply press ENTER or Q now."); first_time = 0; } move(0, 0); /* move the cursor out of the way */ } c = getchar(); if ((extended == 2) || (c == 588) || (c == 596)) { /* console gives "alternative" codes */ extended = 0; /* no longer */ switch (c) { case 588: case 'A': /* up */ if (curr_item > 0) --curr_item; break; case 596: case 'B': /* down */ if (curr_item < 2) ++curr_item; break; } } else { switch(c) { case '\033': extended = 1; break; case '[': /* cheat : always preceeds cursor move */ case 'O': /* ANSI application key mode */ if (extended == 1) extended = 2; else extended = 0; break; case -1: case 'Q': case 'q': clear(); return 1; /* user requests exit */ case '1': /* select an item */ case 'S': case 's': curr_item = 0; break; case '2': case 'V': case 'v': curr_item = 1; break; case '3': case 'C': case 'c': curr_item = 2; break; case 'U': /* up */ case 'u': case 'P': case 'p': if (curr_item > 0) --curr_item; break; case 'D': /* down */ case 'd': case 'N': case 'n': if (curr_item < 2) ++curr_item; break; case '\r': case '\n': clear(); if (!curr_item) return 1; else if (curr_item == 1) return visuserconfig(); else { putxy(0, 1, "Type \"help\" for help or \"quit\" to exit."); /* enable quitfunc */ userconfig_boot_parsing=0; move (0, 3); boothowto |= RB_CONFIG; /* force -c */ return 0; } break; } } } #endif } #endif #if NPNP > 0 static int lspnp () { struct pnp_cinfo *c; int i, first = 1; for (i=0; i< MAX_PNP_LDN; i++) { c = &pnp_ldn_overrides[i]; if (c->csn >0 && c->csn != 255) { int pmax, mmax; static char pfmt[] = "port 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "; static char mfmt[] = "mem 0x%x 0x%x 0x%x 0x%x"; char buf[256]; if (lineno >= 23) { if (!userconfig_boot_parsing) { printf(" "); if (getchar() == 'q') { printf("quit\n"); return (1); } printf("\n"); } lineno = 0; } if (lineno == 0 || first) printf("CSN LDN conf en irqs drqs others (PnP devices)\n"); first = 0 ; printf("%3d %3d %4s %2s %2d %-2d %2d %-2d ", c->csn, c->ldn, c->override ? "OS ":"BIOS", c->enable ? "Y":"N", c->irq[0], c->irq[1], c->drq[0], c->drq[1]); if (c->flags) printf("flags 0x%08lx ",c->flags); for (pmax = 7; pmax >=0 ; pmax--) if (c->port[pmax]!=0) break; for (mmax = 3; mmax >=0 ; mmax--) if (c->mem[mmax].base!=0) break; if (pmax>=0) { strcpy(buf, pfmt); buf[10 + 5*pmax]='\0'; printf(buf, c->port[0], c->port[1], c->port[2], c->port[3], c->port[4], c->port[5], c->port[6], c->port[7]); } if (mmax>=0) { strcpy(buf, mfmt); buf[8 + 5*mmax]='\0'; printf(buf, c->mem[0].base, c->mem[1].base, c->mem[2].base, c->mem[3].base); } printf("\n"); } } return 0 ; } #endif /* NPNP */ static int lsdevtab(struct isa_device *dt) { for (; dt->id_id != 0; dt++) { char dname[80]; if (lineno >= 23) { printf(" "); if (!userconfig_boot_parsing) { if (getchar() == 'q') { printf("quit\n"); return (1); } printf("\n"); } lineno = 0; } if (lineno == 0) { printf( "Device port irq drq iomem iosize unit flags enab confl\n" ); ++lineno; } sprintf(dname, "%s%d", dt->id_driver->name, dt->id_unit); printf("%-9.9s%-#11x%-6d%-6d%-8p%-9d%-6d%-#11x%-5s%-3s\n", dname, /* dt->id_id, dt->id_driver(by name), */ dt->id_iobase, ffs(dt->id_irq) - 1, dt->id_drq, dt->id_maddr, dt->id_msize, /* dt->id_intr(by name), */ dt->id_unit, dt->id_flags, /* dt->id_scsiid, dt->id_alive, dt->id_ri_flags, */ /* dt->id_reconfig, */ dt->id_enabled ? "Yes" : "No", dt->id_conflicts ? "Yes" : "No"); ++lineno; } return(0); } static struct isa_device * find_device(char *devname, int unit) { struct isa_device *ret; if ((ret = search_devtable(&isa_devtab_bio[0], devname, unit)) != NULL) return ret; if ((ret = search_devtable(&isa_devtab_tty[0], devname, unit)) != NULL) return ret; if ((ret = search_devtable(&isa_devtab_net[0], devname, unit)) != NULL) return ret; if ((ret = search_devtable(&isa_devtab_cam[0], devname, unit)) != NULL) return ret; if ((ret = search_devtable(&isa_devtab_null[0], devname, unit)) != NULL) return ret; return NULL; } static struct isa_device * search_devtable(struct isa_device *dt, char *devname, int unit) { int i; for (i = 0; dt->id_id != 0; dt++) if (!strcmp(dt->id_driver->name, devname) && dt->id_unit == unit) return dt; return NULL; } static void cngets(char *input, int maxin) { int c, nchars = 0; while (1) { c = getchar(); /* Treat ^H or ^? as backspace */ if ((c == '\010' || c == '\177')) { if (nchars) { printf("\010 \010"); *--input = '\0', --nchars; } continue; } /* Treat ^U or ^X as kill line */ else if ((c == '\025' || c == '\030')) { while (nchars) { printf("\010 \010"); *--input = '\0', --nchars; } continue; } printf("%c", c); if ((++nchars == maxin) || (c == '\n') || (c == '\r') || ( c == -1)) { *input = '\0'; break; } *input++ = (u_char)c; } } /* * Kludges to get the library sources of strtoul.c to work in our * environment. isdigit() and isspace() could be used above too. */ #define isalpha(c) (((c) >= 'A' && (c) <= 'Z') \ || ((c) >= 'a' && (c) <= 'z')) /* unsafe */ #define isdigit(c) ((unsigned)((c) - '0') <= '9' - '0') #define isspace(c) ((c) == ' ' || (c) == '\t') /* unsafe */ #define isupper(c) ((unsigned)((c) - 'A') <= 'Z' - 'A') static int errno; /* * The following should be identical with the library sources for strtoul.c. */ /* * Convert a string to an unsigned long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ static unsigned long strtoul(nptr, endptr, base) const char *nptr; char **endptr; register int base; { register const char *s = nptr; register unsigned long acc; register int c; register unsigned long cutoff; register int neg = 0, any, cutlim; /* * See strtol for comments as to the logic used. */ do { c = *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else if (c == '+') c = *s++; if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (neg) acc = -acc; if (endptr != 0) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } #if 0 /* scsi: Support for displaying configured SCSI devices. * There is no way to edit them, and this is inconsistent * with the ISA method. This is here as a basis for further work. */ static char * type_text(char *name) /* XXX: This is bogus */ { if (strcmp(name, "sd") == 0) return "disk"; if (strcmp(name, "st") == 0) return "tape"; return "device"; } id_put(char *desc, int id) { if (id != SCCONF_UNSPEC) { if (desc) printf("%s", desc); if (id == SCCONF_ANY) printf("?"); else printf("%d", id); } } static void lsscsi(void) { int i; printf("scsi: (can't be edited):\n"); for (i = 0; scsi_cinit[i].driver; i++) { id_put("controller scbus", scsi_cinit[i].scbus); if (scsi_cinit[i].unit != -1) { printf(" at "); id_put(scsi_cinit[i].driver, scsi_cinit[i].unit); } printf("\n"); } for (i = 0; scsi_dinit[i].name; i++) { printf("%s ", type_text(scsi_dinit[i].name)); id_put(scsi_dinit[i].name, scsi_dinit[i].unit); id_put(" at scbus", scsi_dinit[i].cunit); id_put(" target ", scsi_dinit[i].target); id_put(" lun ", scsi_dinit[i].lun); if (scsi_dinit[i].flags) printf(" flags 0x%x\n", scsi_dinit[i].flags); printf("\n"); } } static int list_scsi(CmdParm *parms) { lineno = 0; lsscsi(); return 0; } #endif static int save_dev(idev) struct isa_device *idev; { struct isa_device *id_p,*id_pn; for (id_p=isa_devlist; id_p; id_p=id_p->id_next) { if (id_p->id_id == idev->id_id) { id_pn = id_p->id_next; bcopy(idev,id_p,sizeof(struct isa_device)); id_p->id_next = id_pn; return 1; } } id_pn = malloc(sizeof(struct isa_device),M_DEVL,M_WAITOK); bcopy(idev,id_pn,sizeof(struct isa_device)); id_pn->id_next = isa_devlist; isa_devlist = id_pn; return 0; } Index: stable/3/sys/pci/if_sf.c =================================================================== --- stable/3/sys/pci/if_sf.c (revision 49544) +++ stable/3/sys/pci/if_sf.c (revision 49545) @@ -1,1842 +1,1795 @@ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_sf.c,v 1.12 1999/07/25 05:10:18 wpaul Exp $ + * $Id: if_sf.c,v 1.21 1999/08/08 19:54:32 wpaul Exp $ */ /* * Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD. * Programming manual is available from www.adaptec.com. * * Written by Bill Paul * Department of Electical Engineering * Columbia University, New York City */ /* * The Adaptec AIC-6915 "Starfire" is a 64-bit 10/100 PCI ethernet * controller designed with flexibility and reducing CPU load in mind. * The Starfire offers high and low priority buffer queues, a * producer/consumer index mechanism and several different buffer * queue and completion queue descriptor types. Any one of a number * of different driver designs can be used, depending on system and * OS requirements. This driver makes use of type0 transmit frame * descriptors (since BSD fragments packets across an mbuf chain) * and two RX buffer queues prioritized on size (one queue for small * frames that will fit into a single mbuf, another with full size * mbuf clusters for everything else). The producer/consumer indexes * and completion queues are also used. * * One downside to the Starfire has to do with alignment: buffer * queues must be aligned on 256-byte boundaries, and receive buffers * must be aligned on longword boundaries. The receive buffer alignment * causes problems on the Alpha platform, where the packet payload * should be longword aligned. There is no simple way around this. * * For receive filtering, the Starfire offers 16 perfect filter slots * and a 512-bit hash table. * * The Starfire has no internal transceiver, relying instead on an * external MII-based transceiver. Accessing registers on external * PHYs is done through a special register map rather than with the * usual bitbang MDIO method. * * Acesssing the registers on the Starfire is a little tricky. The * Starfire has a 512K internal register space. When programmed for * PCI memory mapped mode, the entire register space can be accessed * directly. However in I/O space mode, only 256 bytes are directly * mapped into PCI I/O space. The other registers can be accessed * indirectly using the SF_INDIRECTIO_ADDR and SF_INDIRECTIO_DATA * registers inside the 256-byte I/O window. */ -#include "bpf.h" +#include "bpfilter.h" #include #include #include #include #include #include #include #include #include #include #include #include -#if NBPF > 0 +#if NBPFILTER > 0 #include #endif #include /* for vtophys */ #include /* for vtophys */ #include /* for DELAY */ #include #include #include -#include -#include -#include #include #include #define SF_USEIOSPACE /* #define SF_BACKGROUND_AUTONEG */ #include #ifndef lint static const char rcsid[] = - "$Id: if_sf.c,v 1.12 1999/07/25 05:10:18 wpaul Exp $"; + "$Id: if_sf.c,v 1.21 1999/08/08 19:54:32 wpaul Exp $"; #endif static struct sf_type sf_devs[] = { { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX" }, { 0, 0, NULL } }; static struct sf_type sf_phys[] = { { 0, 0, "" } }; -static int sf_probe __P((device_t)); -static int sf_attach __P((device_t)); -static int sf_detach __P((device_t)); +static unsigned long sf_count = 0; +static const char *sf_probe __P((pcici_t, pcidi_t)); +static void sf_attach __P((pcici_t, int)); static void sf_intr __P((void *)); static void sf_stats_update __P((void *)); static void sf_rxeof __P((struct sf_softc *)); static void sf_txeof __P((struct sf_softc *)); static int sf_encap __P((struct sf_softc *, struct sf_tx_bufdesc_type0 *, struct mbuf *)); static void sf_start __P((struct ifnet *)); static int sf_ioctl __P((struct ifnet *, u_long, caddr_t)); static void sf_init __P((void *)); static void sf_stop __P((struct sf_softc *)); static void sf_watchdog __P((struct ifnet *)); -static void sf_shutdown __P((device_t)); +static void sf_shutdown __P((int, void *)); static int sf_ifmedia_upd __P((struct ifnet *)); static void sf_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); static void sf_reset __P((struct sf_softc *)); static int sf_init_rx_ring __P((struct sf_softc *)); static void sf_init_tx_ring __P((struct sf_softc *)); static int sf_newbuf __P((struct sf_softc *, struct sf_rx_bufdesc_type0 *, struct mbuf *)); static void sf_setmulti __P((struct sf_softc *)); static int sf_setperf __P((struct sf_softc *, int, caddr_t)); static int sf_sethash __P((struct sf_softc *, caddr_t, int)); #ifdef notdef static int sf_setvlan __P((struct sf_softc *, int, u_int32_t)); #endif static u_int8_t sf_read_eeprom __P((struct sf_softc *, int)); static u_int32_t sf_calchash __P((caddr_t)); static int sf_phy_readreg __P((struct sf_softc *, int)); static void sf_phy_writereg __P((struct sf_softc *, int, int)); static void sf_autoneg_xmit __P((struct sf_softc *)); static void sf_autoneg_mii __P((struct sf_softc *, int, int)); static void sf_getmode_mii __P((struct sf_softc *)); static void sf_setmode_mii __P((struct sf_softc *, int)); static u_int32_t csr_read_4 __P((struct sf_softc *, int)); static void csr_write_4 __P((struct sf_softc *, int, u_int32_t)); -#ifdef SF_USEIOSPACE -#define SF_RES SYS_RES_IOPORT -#define SF_RID SF_PCI_LOIO -#else -#define SF_RES SYS_RES_MEMORY -#define SF_RID SF_PCI_LOMEM +#ifdef __i386__ +#define SF_BUS_SPACE_MEM I386_BUS_SPACE_MEM +#define SF_BUS_SPACE_IO I386_BUS_SPACE_IO #endif -static device_method_t sf_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sf_probe), - DEVMETHOD(device_attach, sf_attach), - DEVMETHOD(device_detach, sf_detach), - DEVMETHOD(device_shutdown, sf_shutdown), - { 0, 0 } -}; +#ifdef __alpha__ +#define SF_BUS_SPACE_MEM ALPHA_BUS_SPACE_MEM +#define SF_BUS_SPACE_IO ALPHA_BUS_SPACE_IO +#endif -static driver_t sf_driver = { - "sf", - sf_methods, - sizeof(struct sf_softc), -}; - -static devclass_t sf_devclass; - -DRIVER_MODULE(sf, pci, sf_driver, sf_devclass, 0, 0); - #define SF_SETBIT(sc, reg, x) \ csr_write_4(sc, reg, csr_read_4(sc, reg) | x) #define SF_CLRBIT(sc, reg, x) \ csr_write_4(sc, reg, csr_read_4(sc, reg) & ~x) static u_int32_t csr_read_4(sc, reg) struct sf_softc *sc; int reg; { u_int32_t val; -#ifdef SF_USEIOSPACE - CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); - val = CSR_READ_4(sc, SF_INDIRECTIO_DATA); -#else - val = CSR_READ_4(sc, (reg + SF_RMAP_INTREG_BASE)); -#endif + switch(sc->sf_btag) { + case SF_BUS_SPACE_MEM: + val = CSR_READ_4(sc, (reg + SF_RMAP_INTREG_BASE)); + break; + case SF_BUS_SPACE_IO: + CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); + val = CSR_READ_4(sc, SF_INDIRECTIO_DATA); + break; + default: + printf("sf%d: bad btag value\n", sc->sf_unit); + val = 0; + break; + } return(val); } static u_int8_t sf_read_eeprom(sc, reg) struct sf_softc *sc; int reg; { u_int8_t val; val = (csr_read_4(sc, SF_EEADDR_BASE + (reg & 0xFFFFFFFC)) >> (8 * (reg & 3))) & 0xFF; return(val); } static void csr_write_4(sc, reg, val) struct sf_softc *sc; int reg; u_int32_t val; { -#ifdef SF_USEIOSPACE - CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); - CSR_WRITE_4(sc, SF_INDIRECTIO_DATA, val); -#else - CSR_WRITE_4(sc, (reg + SF_RMAP_INTREG_BASE), val); -#endif + switch(sc->sf_btag) { + case SF_BUS_SPACE_MEM: + CSR_WRITE_4(sc, (reg + SF_RMAP_INTREG_BASE), val); + break; + case SF_BUS_SPACE_IO: + CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); + CSR_WRITE_4(sc, SF_INDIRECTIO_DATA, val); + break; + default: + printf("sf%d: bad btag value\n", sc->sf_unit); + break; + } + return; } static u_int32_t sf_calchash(addr) caddr_t addr; { u_int32_t crc, carry; int i, j; u_int8_t c; /* Compute CRC for the address value. */ crc = 0xFFFFFFFF; /* initial value */ for (i = 0; i < 6; i++) { c = *(addr + i); for (j = 0; j < 8; j++) { carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01); crc <<= 1; c >>= 1; if (carry) crc = (crc ^ 0x04c11db6) | carry; } } /* return the filter bit position */ return(crc >> 23 & 0x1FF); } /* * Copy the address 'mac' into the perfect RX filter entry at - * offset 'idx.' The perfect filter only has 16 entries so do + * offset 'ifx.' The perfect filter only has 16 entries so do * some sanity tests. */ static int sf_setperf(sc, idx, mac) struct sf_softc *sc; int idx; caddr_t mac; { u_int16_t *p; if (idx < 0 || idx > SF_RXFILT_PERFECT_CNT) return(EINVAL); if (mac == NULL) return(EINVAL); p = (u_int16_t *)mac; csr_write_4(sc, SF_RXFILT_PERFECT_BASE + (idx * SF_RXFILT_PERFECT_SKIP), htons(p[2])); csr_write_4(sc, SF_RXFILT_PERFECT_BASE + (idx * SF_RXFILT_PERFECT_SKIP) + 4, htons(p[1])); csr_write_4(sc, SF_RXFILT_PERFECT_BASE + (idx * SF_RXFILT_PERFECT_SKIP) + 8, htons(p[0])); return(0); } /* * Set the bit in the 512-bit hash table that corresponds to the * specified mac address 'mac.' If 'prio' is nonzero, update the * priority hash table instead of the filter hash table. */ static int sf_sethash(sc, mac, prio) struct sf_softc *sc; caddr_t mac; int prio; { u_int32_t h = 0; if (mac == NULL) return(EINVAL); h = sf_calchash(mac); if (prio) { SF_SETBIT(sc, SF_RXFILT_HASH_BASE + SF_RXFILT_HASH_PRIOOFF + (SF_RXFILT_HASH_SKIP * (h >> 4)), (1 << (h & 0xF))); } else { SF_SETBIT(sc, SF_RXFILT_HASH_BASE + SF_RXFILT_HASH_ADDROFF + (SF_RXFILT_HASH_SKIP * (h >> 4)), (1 << (h & 0xF))); } return(0); } #ifdef notdef /* * Set a VLAN tag in the receive filter. */ static int sf_setvlan(sc, idx, vlan) struct sf_softc *sc; int idx; u_int32_t vlan; { if (idx < 0 || idx >> SF_RXFILT_HASH_CNT) return(EINVAL); csr_write_4(sc, SF_RXFILT_HASH_BASE + (idx * SF_RXFILT_HASH_SKIP) + SF_RXFILT_HASH_VLANOFF, vlan); return(0); } #endif static int sf_phy_readreg(sc, reg) struct sf_softc *sc; int reg; { int i; u_int32_t val = 0; for (i = 0; i < SF_TIMEOUT; i++) { val = csr_read_4(sc, SF_PHY_REG(sc->sf_phy_addr, reg)); if (val & SF_MII_DATAVALID) break; } if (i == SF_TIMEOUT) return(0); if ((val & 0x0000FFFF) == 0xFFFF) return(0); return(val & 0x0000FFFF); } static void sf_phy_writereg(sc, reg, val) struct sf_softc *sc; int reg, val; { int i; int busy; csr_write_4(sc, SF_PHY_REG(sc->sf_phy_addr, reg), val); for (i = 0; i < SF_TIMEOUT; i++) { busy = csr_read_4(sc, SF_PHY_REG(sc->sf_phy_addr, reg)); if (!(busy & SF_MII_BUSY)) break; } return; } static void sf_setmulti(sc) struct sf_softc *sc; { struct ifnet *ifp; int i; struct ifmultiaddr *ifma; u_int8_t dummy[] = { 0, 0, 0, 0, 0, 0 }; ifp = &sc->arpcom.ac_if; /* First zot all the existing filters. */ for (i = 1; i < SF_RXFILT_PERFECT_CNT; i++) sf_setperf(sc, i, (char *)&dummy); for (i = SF_RXFILT_HASH_BASE; i < (SF_RXFILT_HASH_MAX + 1); i += 4) csr_write_4(sc, i, 0); SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_ALLMULTI); /* Now program new ones. */ if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_ALLMULTI); } else { i = 1; /* First find the tail of the list. */ for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; ifma = ifma->ifma_link.le_next) { if (ifma->ifma_link.le_next == NULL) break; } /* Now traverse the list backwards. */ for (; ifma != NULL && ifma != (void *)&ifp->if_multiaddrs; ifma = (struct ifmultiaddr *)ifma->ifma_link.le_prev) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; /* * Program the first 15 multicast groups * into the perfect filter. For all others, * use the hash table. */ if (i < SF_RXFILT_PERFECT_CNT) { sf_setperf(sc, i, LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); i++; continue; } sf_sethash(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 0); } } return; } /* * Initiate an autonegotiation session. */ static void sf_autoneg_xmit(sc) struct sf_softc *sc; { u_int16_t phy_sts; sf_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET); DELAY(500); while(sf_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_RESET); phy_sts = sf_phy_readreg(sc, PHY_BMCR); phy_sts |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR; sf_phy_writereg(sc, PHY_BMCR, phy_sts); return; } /* * Invoke autonegotiation on a PHY. */ static void sf_autoneg_mii(sc, flag, verbose) struct sf_softc *sc; int flag; int verbose; { u_int16_t phy_sts = 0, media, advert, ability; struct ifnet *ifp; struct ifmedia *ifm; ifm = &sc->ifmedia; ifp = &sc->arpcom.ac_if; ifm->ifm_media = IFM_ETHER | IFM_AUTO; #ifndef FORCE_AUTONEG_TFOUR /* * First, see if autoneg is supported. If not, there's * no point in continuing. */ phy_sts = sf_phy_readreg(sc, PHY_BMSR); if (!(phy_sts & PHY_BMSR_CANAUTONEG)) { if (verbose) printf("sf%d: autonegotiation not supported\n", sc->sf_unit); ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX; return; } #endif switch (flag) { case SF_FLAG_FORCEDELAY: /* * XXX Never use this option anywhere but in the probe * routine: making the kernel stop dead in its tracks * for three whole seconds after we've gone multi-user * is really bad manners. */ sf_autoneg_xmit(sc); DELAY(5000000); break; case SF_FLAG_SCHEDDELAY: /* * Wait for the transmitter to go idle before starting * an autoneg session, otherwise sf_start() may clobber * our timeout, and we don't want to allow transmission * during an autoneg session since that can screw it up. */ if (sc->sf_tx_cnt) { sc->sf_want_auto = 1; return; } sf_autoneg_xmit(sc); ifp->if_timer = 5; sc->sf_autoneg = 1; sc->sf_want_auto = 0; return; break; case SF_FLAG_DELAYTIMEO: ifp->if_timer = 0; sc->sf_autoneg = 0; break; default: printf("sf%d: invalid autoneg flag: %d\n", sc->sf_unit, flag); return; } if (sf_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) { if (verbose) printf("sf%d: autoneg complete, ", sc->sf_unit); phy_sts = sf_phy_readreg(sc, PHY_BMSR); } else { if (verbose) printf("sf%d: autoneg not complete, ", sc->sf_unit); } media = sf_phy_readreg(sc, PHY_BMCR); /* Link is good. Report modes and set duplex mode. */ if (sf_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) { if (verbose) printf("link status good "); advert = sf_phy_readreg(sc, PHY_ANAR); ability = sf_phy_readreg(sc, PHY_LPAR); if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) { ifm->ifm_media = IFM_ETHER|IFM_100_T4; media |= PHY_BMCR_SPEEDSEL; media &= ~PHY_BMCR_DUPLEX; printf("(100baseT4)\n"); } else if (advert & PHY_ANAR_100BTXFULL && ability & PHY_ANAR_100BTXFULL) { ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX; media |= PHY_BMCR_SPEEDSEL; media |= PHY_BMCR_DUPLEX; printf("(full-duplex, 100Mbps)\n"); } else if (advert & PHY_ANAR_100BTXHALF && ability & PHY_ANAR_100BTXHALF) { ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX; media |= PHY_BMCR_SPEEDSEL; media &= ~PHY_BMCR_DUPLEX; printf("(half-duplex, 100Mbps)\n"); } else if (advert & PHY_ANAR_10BTFULL && ability & PHY_ANAR_10BTFULL) { ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX; media &= ~PHY_BMCR_SPEEDSEL; media |= PHY_BMCR_DUPLEX; printf("(full-duplex, 10Mbps)\n"); } else if (advert & PHY_ANAR_10BTHALF && ability & PHY_ANAR_10BTHALF) { ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX; media &= ~PHY_BMCR_SPEEDSEL; media &= ~PHY_BMCR_DUPLEX; printf("(half-duplex, 10Mbps)\n"); } media &= ~PHY_BMCR_AUTONEGENBL; /* Set ASIC's duplex mode to match the PHY. */ sf_phy_writereg(sc, PHY_BMCR, media); if ((media & IFM_GMASK) == IFM_FDX) { SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } else { SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } } else { if (verbose) printf("no carrier\n"); } sf_init(sc); if (sc->sf_tx_pend) { sc->sf_autoneg = 0; sc->sf_tx_pend = 0; sf_start(ifp); } return; } static void sf_getmode_mii(sc) struct sf_softc *sc; { u_int16_t bmsr; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; bmsr = sf_phy_readreg(sc, PHY_BMSR); if (bootverbose) printf("sf%d: PHY status word: %x\n", sc->sf_unit, bmsr); /* fallback */ sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX; if (bmsr & PHY_BMSR_10BTHALF) { if (bootverbose) printf("sf%d: 10Mbps half-duplex mode supported\n", sc->sf_unit); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); } if (bmsr & PHY_BMSR_10BTFULL) { if (bootverbose) printf("sf%d: 10Mbps full-duplex mode supported\n", sc->sf_unit); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX; } if (bmsr & PHY_BMSR_100BTXHALF) { if (bootverbose) printf("sf%d: 100Mbps half-duplex mode supported\n", sc->sf_unit); ifp->if_baudrate = 100000000; ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX; } if (bmsr & PHY_BMSR_100BTXFULL) { if (bootverbose) printf("sf%d: 100Mbps full-duplex mode supported\n", sc->sf_unit); ifp->if_baudrate = 100000000; ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX; } /* Some also support 100BaseT4. */ if (bmsr & PHY_BMSR_100BT4) { if (bootverbose) printf("sf%d: 100baseT4 mode supported\n", sc->sf_unit); ifp->if_baudrate = 100000000; ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_T4, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_T4; #ifdef FORCE_AUTONEG_TFOUR if (bootverbose) printf("sf%d: forcing on autoneg support for BT4\n", sc->sf_unit); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0 NULL): sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO; #endif } if (bmsr & PHY_BMSR_CANAUTONEG) { if (bootverbose) printf("sf%d: autoneg supported\n", sc->sf_unit); ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO; } return; } /* * Set speed and duplex mode. */ static void sf_setmode_mii(sc, media) struct sf_softc *sc; int media; { u_int16_t bmcr; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; /* * If an autoneg session is in progress, stop it. */ if (sc->sf_autoneg) { printf("sf%d: canceling autoneg session\n", sc->sf_unit); ifp->if_timer = sc->sf_autoneg = sc->sf_want_auto = 0; bmcr = sf_phy_readreg(sc, PHY_BMCR); bmcr &= ~PHY_BMCR_AUTONEGENBL; sf_phy_writereg(sc, PHY_BMCR, bmcr); } printf("sf%d: selecting MII, ", sc->sf_unit); bmcr = sf_phy_readreg(sc, PHY_BMCR); bmcr &= ~(PHY_BMCR_AUTONEGENBL|PHY_BMCR_SPEEDSEL| PHY_BMCR_DUPLEX|PHY_BMCR_LOOPBK); if (IFM_SUBTYPE(media) == IFM_100_T4) { printf("100Mbps/T4, half-duplex\n"); bmcr |= PHY_BMCR_SPEEDSEL; bmcr &= ~PHY_BMCR_DUPLEX; } if (IFM_SUBTYPE(media) == IFM_100_TX) { printf("100Mbps, "); bmcr |= PHY_BMCR_SPEEDSEL; } if (IFM_SUBTYPE(media) == IFM_10_T) { printf("10Mbps, "); bmcr &= ~PHY_BMCR_SPEEDSEL; } if ((media & IFM_GMASK) == IFM_FDX) { printf("full duplex\n"); bmcr |= PHY_BMCR_DUPLEX; SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } else { printf("half duplex\n"); bmcr &= ~PHY_BMCR_DUPLEX; SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } sf_phy_writereg(sc, PHY_BMCR, bmcr); return; } /* * Set media options. */ static int sf_ifmedia_upd(ifp) struct ifnet *ifp; { struct sf_softc *sc; struct ifmedia *ifm; sc = ifp->if_softc; ifm = &sc->ifmedia; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return(EINVAL); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) sf_autoneg_mii(sc, SF_FLAG_SCHEDDELAY, 1); else { sf_setmode_mii(sc, ifm->ifm_media); } return(0); } /* * Report current media status. */ static void sf_ifmedia_sts(ifp, ifmr) struct ifnet *ifp; struct ifmediareq *ifmr; { struct sf_softc *sc; u_int16_t advert = 0, ability = 0; sc = ifp->if_softc; ifmr->ifm_active = IFM_ETHER; if (!(sf_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL)) { if (sf_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL) ifmr->ifm_active = IFM_ETHER|IFM_100_TX; else ifmr->ifm_active = IFM_ETHER|IFM_10_T; if (sf_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX) ifmr->ifm_active |= IFM_FDX; else ifmr->ifm_active |= IFM_HDX; return; } ability = sf_phy_readreg(sc, PHY_LPAR); advert = sf_phy_readreg(sc, PHY_ANAR); if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) { ifmr->ifm_active = IFM_ETHER|IFM_100_T4; } else if (advert & PHY_ANAR_100BTXFULL && ability & PHY_ANAR_100BTXFULL) { ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_FDX; } else if (advert & PHY_ANAR_100BTXHALF && ability & PHY_ANAR_100BTXHALF) { ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_HDX; } else if (advert & PHY_ANAR_10BTFULL && ability & PHY_ANAR_10BTFULL) { ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_FDX; } else if (advert & PHY_ANAR_10BTHALF && ability & PHY_ANAR_10BTHALF) { ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_HDX; } return; } static int sf_ioctl(ifp, command, data) struct ifnet *ifp; u_long command; caddr_t data; { struct sf_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; int s, error = 0; s = splimp(); switch(command) { case SIOCSIFADDR: case SIOCGIFADDR: case SIOCSIFMTU: error = ether_ioctl(ifp, command, data); break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { sf_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) sf_stop(sc); } error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: sf_setmulti(sc); error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); break; default: error = EINVAL; break; } (void)splx(s); return(error); } static void sf_reset(sc) struct sf_softc *sc; { register int i; csr_write_4(sc, SF_GEN_ETH_CTL, 0); SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); DELAY(1000); SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_RESET); for (i = 0; i < SF_TIMEOUT; i++) { DELAY(10); if (!(csr_read_4(sc, SF_PCI_DEVCFG) & SF_PCIDEVCFG_RESET)) break; } if (i == SF_TIMEOUT) printf("sf%d: reset never completed!\n", sc->sf_unit); /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); return; } /* * Probe for an Adaptec AIC-6915 chip. Check the PCI vendor and device * IDs against our list and return a device name if we find a match. * We also check the subsystem ID so that we can identify exactly which * NIC has been found, if possible. */ -static int sf_probe(dev) - device_t dev; +static const char *sf_probe(config_id, device_id) + pcici_t config_id; + pcidi_t device_id; { struct sf_type *t; t = sf_devs; while(t->sf_name != NULL) { - if ((pci_get_vendor(dev) == t->sf_vid) && - (pci_get_device(dev) == t->sf_did)) { - switch(pci_read_config(dev, - SF_PCI_SUBVEN_ID >> 16, 4) & 0x8FFF) { + if ((device_id & 0xFFFF) == t->sf_vid && + ((device_id >> 16) & 0xFFFF) == t->sf_did) { + switch((pci_conf_read(config_id, + SF_PCI_SUBVEN_ID) >> 16) & 0x8FFF) { case AD_SUBSYSID_62011_REV0: case AD_SUBSYSID_62011_REV1: - device_set_desc(dev, - "Adaptec ANA-62011 10/100BaseTX"); - return(0); + return("Adaptec ANA-62011 10/100BaseTX"); break; case AD_SUBSYSID_62022: - device_set_desc(dev, - "Adaptec ANA-62022 10/100BaseTX"); - return(0); + return("Adaptec ANA-62022 10/100BaseTX"); break; case AD_SUBSYSID_62044: - device_set_desc(dev, - "Adaptec ANA-62044 10/100BaseTX"); - return(0); + return("Adaptec ANA-62044 10/100BaseTX"); break; case AD_SUBSYSID_62020: - device_set_desc(dev, - "Adaptec ANA-62020 10/100BaseFX"); - return(0); + return("Adaptec ANA-62020 10/100BaseFX"); break; case AD_SUBSYSID_69011: - device_set_desc(dev, - "Adaptec ANA-69011 10/100BaseTX"); - return(0); + return("Adaptec ANA-69011 10/100BaseTX"); break; default: - device_set_desc(dev, t->sf_name); - return(0); + return(t->sf_name); break; } } t++; } - return(ENXIO); + return(NULL); } /* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ -static int sf_attach(dev) - device_t dev; +static void +sf_attach(config_id, unit) + pcici_t config_id; + int unit; { int s, i; +#ifndef SF_USEIOSPACE + vm_offset_t pbase, vbase; +#endif u_int32_t command; struct sf_softc *sc; struct ifnet *ifp; int media = IFM_ETHER|IFM_100_TX|IFM_FDX; struct sf_type *p; u_int16_t phy_vid, phy_did, phy_sts; - int unit, rid, error = 0; s = splimp(); - sc = device_get_softc(dev); - unit = device_get_unit(dev); + sc = malloc(sizeof(struct sf_softc), M_DEVBUF, M_NOWAIT); + if (sc == NULL) { + printf("sf%d: no memory for softc struct!\n", unit); + goto fail; + } bzero(sc, sizeof(struct sf_softc)); /* * Handle power management nonsense. */ - command = pci_read_config(dev, SF_PCI_CAPID, 4) & 0x000000FF; + command = pci_conf_read(config_id, SF_PCI_CAPID) & 0x000000FF; if (command == 0x01) { - command = pci_read_config(dev, SF_PCI_PWRMGMTCTRL, 4); + command = pci_conf_read(config_id, SF_PCI_PWRMGMTCTRL); if (command & SF_PSTATE_MASK) { u_int32_t iobase, membase, irq; /* Save important PCI config data. */ - iobase = pci_read_config(dev, SF_PCI_LOIO, 4); - membase = pci_read_config(dev, SF_PCI_LOMEM, 4); - irq = pci_read_config(dev, SF_PCI_INTLINE, 4); + iobase = pci_conf_read(config_id, SF_PCI_LOIO); + membase = pci_conf_read(config_id, SF_PCI_LOMEM); + irq = pci_conf_read(config_id, SF_PCI_INTLINE); /* Reset the power state. */ printf("sf%d: chip is in D%d power mode " "-- setting to D0\n", unit, command & SF_PSTATE_MASK); command &= 0xFFFFFFFC; - pci_write_config(dev, SF_PCI_PWRMGMTCTRL, command, 4); + pci_conf_write(config_id, SF_PCI_PWRMGMTCTRL, command); /* Restore PCI config data. */ - pci_write_config(dev, SF_PCI_LOIO, iobase, 4); - pci_write_config(dev, SF_PCI_LOMEM, membase, 4); - pci_write_config(dev, SF_PCI_INTLINE, irq, 4); + pci_conf_write(config_id, SF_PCI_LOIO, iobase); + pci_conf_write(config_id, SF_PCI_LOMEM, membase); + pci_conf_write(config_id, SF_PCI_INTLINE, irq); } } /* * Map control/status registers. */ - command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); + command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); - pci_write_config(dev, PCI_COMMAND_STATUS_REG, command, 4); - command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); + pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command); + command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); #ifdef SF_USEIOSPACE if (!(command & PCIM_CMD_PORTEN)) { printf("sf%d: failed to enable I/O ports!\n", unit); - error = ENXIO; + free(sc, M_DEVBUF); goto fail; } + + if (!pci_map_port(config_id, SF_PCI_LOIO, + (u_short *)&(sc->sf_bhandle))) { + printf ("sf%d: couldn't map ports\n", unit); + goto fail; + } + + sc->sf_btag = SF_BUS_SPACE_IO; #else if (!(command & PCIM_CMD_MEMEN)) { printf("sf%d: failed to enable memory mapping!\n", unit); - error = ENXIO; goto fail; } -#endif - rid = SF_RID; - sc->sf_res = bus_alloc_resource(dev, SF_RES, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (sc->sf_res == NULL) { - printf ("sf%d: couldn't map ports\n", unit); - error = ENXIO; + if (!pci_map_mem(config_id, SF_PCI_LOMEM, &vbase, &pbase)) { + printf ("sf%d: couldn't map memory\n", unit); goto fail; } + sc->sf_btag = SF_BUS_SPACE_MEM; + sc->sf_bhandle = vbase; +#endif - sc->sf_btag = rman_get_bustag(sc->sf_res); - sc->sf_bhandle = rman_get_bushandle(sc->sf_res); - /* Allocate interrupt */ - rid = 0; - sc->sf_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); - - if (sc->sf_irq == NULL) { + if (!pci_map_int(config_id, sf_intr, sc, &net_imask)) { printf("sf%d: couldn't map interrupt\n", unit); - bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res); - error = ENXIO; goto fail; } - error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET, - sf_intr, sc, &sc->sf_intrhand); - - if (error) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_res); - bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res); - printf("sf%d: couldn't set up irq\n", unit); - goto fail; - } - callout_handle_init(&sc->sf_stat_ch); /* Reset the adapter. */ sf_reset(sc); /* * Get station address from the EEPROM. */ for (i = 0; i < ETHER_ADDR_LEN; i++) sc->arpcom.ac_enaddr[i] = sf_read_eeprom(sc, SF_EE_NODEADDR + ETHER_ADDR_LEN - i); /* * An Adaptec chip was detected. Inform the world. */ printf("sf%d: Ethernet address: %6D\n", unit, sc->arpcom.ac_enaddr, ":"); sc->sf_unit = unit; /* Allocate the descriptor queues. */ sc->sf_ldata = contigmalloc(sizeof(struct sf_list_data), M_DEVBUF, M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0); if (sc->sf_ldata == NULL) { + free(sc, M_DEVBUF); printf("sf%d: no memory for list buffers!\n", unit); - bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq); - bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res); - error = ENXIO; goto fail; } bzero(sc->sf_ldata, sizeof(struct sf_list_data)); if (bootverbose) printf("sf%d: probing for a PHY\n", sc->sf_unit); for (i = SF_PHYADDR_MIN; i < SF_PHYADDR_MAX + 1; i++) { if (bootverbose) printf("sf%d: checking address: %d\n", sc->sf_unit, i); sc->sf_phy_addr = i; sf_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET); DELAY(500); while(sf_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_RESET); if ((phy_sts = sf_phy_readreg(sc, PHY_BMSR))) break; } if (phy_sts) { phy_vid = sf_phy_readreg(sc, PHY_VENID); phy_did = sf_phy_readreg(sc, PHY_DEVID); if (bootverbose) printf("sf%d: found PHY at address %d, ", sc->sf_unit, sc->sf_phy_addr); if (bootverbose) printf("vendor id: %x device id: %x\n", phy_vid, phy_did); p = sf_phys; while(p->sf_vid) { if (phy_vid == p->sf_vid && (phy_did | 0x000F) == p->sf_did) { sc->sf_pinfo = p; break; } p++; } if (sc->sf_pinfo == NULL) sc->sf_pinfo = &sf_phys[PHY_UNKNOWN]; if (bootverbose) printf("sf%d: PHY type: %s\n", sc->sf_unit, sc->sf_pinfo->sf_name); } else { printf("sf%d: MII without any phy!\n", sc->sf_unit); free(sc->sf_ldata, M_DEVBUF); - bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq); - bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res); - error = ENXIO; + free(sc, M_DEVBUF); goto fail; } ifp = &sc->arpcom.ac_if; ifp->if_softc = sc; ifp->if_unit = unit; ifp->if_name = "sf"; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = sf_ioctl; ifp->if_output = ether_output; ifp->if_start = sf_start; ifp->if_watchdog = sf_watchdog; ifp->if_init = sf_init; ifp->if_baudrate = 10000000; ifp->if_snd.ifq_maxlen = SF_TX_DLIST_CNT - 1; /* * Do ifmedia setup. */ ifmedia_init(&sc->ifmedia, 0, sf_ifmedia_upd, sf_ifmedia_sts); sf_getmode_mii(sc); - if (cold) { - sf_autoneg_mii(sc, SF_FLAG_FORCEDELAY, 1); - sf_stop(sc); - } else { - sf_init(sc); - sf_autoneg_mii(sc, SF_FLAG_SCHEDDELAY, 1); - } - + sf_autoneg_mii(sc, SF_FLAG_FORCEDELAY, 1); media = sc->ifmedia.ifm_media; + sf_stop(sc); + ifmedia_set(&sc->ifmedia, media); /* * Call MI attach routines. */ if_attach(ifp); ether_ifattach(ifp); -#if NBPF > 0 +#if NBPFILTER > 0 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif + at_shutdown(sf_shutdown, sc, SHUTDOWN_POST_SYNC); + fail: splx(s); - return(error); + return; } -static int sf_detach(dev) - device_t dev; -{ - struct sf_softc *sc; - struct ifnet *ifp; - int s; - - s = splimp(); - - sc = device_get_softc(dev); - ifp = &sc->arpcom.ac_if; - - if_detach(ifp); - sf_stop(sc); - - bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq); - bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res); - - free(sc->sf_ldata, M_DEVBUF); - ifmedia_removeall(&sc->ifmedia); - - splx(s); - - return(0); -} - static int sf_init_rx_ring(sc) struct sf_softc *sc; { struct sf_list_data *ld; int i; ld = sc->sf_ldata; bzero((char *)ld->sf_rx_dlist_big, sizeof(struct sf_rx_bufdesc_type0) * SF_RX_DLIST_CNT); bzero((char *)ld->sf_rx_clist, sizeof(struct sf_rx_cmpdesc_type3) * SF_RX_CLIST_CNT); for (i = 0; i < SF_RX_DLIST_CNT; i++) { if (sf_newbuf(sc, &ld->sf_rx_dlist_big[i], NULL) == ENOBUFS) return(ENOBUFS); } return(0); } static void sf_init_tx_ring(sc) struct sf_softc *sc; { struct sf_list_data *ld; int i; ld = sc->sf_ldata; bzero((char *)ld->sf_tx_dlist, sizeof(struct sf_tx_bufdesc_type0) * SF_TX_DLIST_CNT); bzero((char *)ld->sf_tx_clist, sizeof(struct sf_tx_cmpdesc_type0) * SF_TX_CLIST_CNT); for (i = 0; i < SF_TX_DLIST_CNT; i++) ld->sf_tx_dlist[i].sf_id = SF_TX_BUFDESC_ID; for (i = 0; i < SF_TX_CLIST_CNT; i++) ld->sf_tx_clist[i].sf_type = SF_TXCMPTYPE_TX; ld->sf_tx_dlist[SF_TX_DLIST_CNT - 1].sf_end = 1; sc->sf_tx_cnt = 0; return; } static int sf_newbuf(sc, c, m) struct sf_softc *sc; struct sf_rx_bufdesc_type0 *c; struct mbuf *m; { struct mbuf *m_new = NULL; if (m == NULL) { MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { printf("sf%d: no memory for rx list -- " "packet dropped!\n", sc->sf_unit); return(ENOBUFS); } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { printf("sf%d: no memory for rx list -- " "packet dropped!\n", sc->sf_unit); m_freem(m_new); return(ENOBUFS); } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { m_new = m; m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; m_new->m_data = m_new->m_ext.ext_buf; } m_adj(m_new, sizeof(u_int64_t)); c->sf_mbuf = m_new; c->sf_addrlo = SF_RX_HOSTADDR(vtophys(mtod(m_new, caddr_t))); c->sf_valid = 1; return(0); } /* * The starfire is programmed to use 'normal' mode for packet reception, * which means we use the consumer/producer model for both the buffer * descriptor queue and the completion descriptor queue. The only problem * with this is that it involves a lot of register accesses: we have to * read the RX completion consumer and producer indexes and the RX buffer * producer index, plus the RX completion consumer and RX buffer producer * indexes have to be updated. It would have been easier if Adaptec had * put each index in a separate register, especially given that the damn * NIC has a 512K register space. * * In spite of all the lovely features that Adaptec crammed into the 6915, * it is marred by one truly stupid design flaw, which is that receive * buffer addresses must be aligned on a longword boundary. This forces * the packet payload to be unaligned, which is suboptimal on the x86 and * completely unuseable on the Alpha. Our only recourse is to copy received * packets into properly aligned buffers before handing them off. */ static void sf_rxeof(sc) struct sf_softc *sc; { struct ether_header *eh; struct mbuf *m; struct ifnet *ifp; struct sf_rx_bufdesc_type0 *desc; struct sf_rx_cmpdesc_type3 *cur_rx; u_int32_t rxcons, rxprod; int cmpprodidx, cmpconsidx, bufprodidx; ifp = &sc->arpcom.ac_if; rxcons = csr_read_4(sc, SF_CQ_CONSIDX); rxprod = csr_read_4(sc, SF_RXDQ_PTR_Q1); cmpprodidx = SF_IDX_LO(csr_read_4(sc, SF_CQ_PRODIDX)); cmpconsidx = SF_IDX_LO(rxcons); bufprodidx = SF_IDX_LO(rxprod); while (cmpconsidx != cmpprodidx) { struct mbuf *m0; cur_rx = &sc->sf_ldata->sf_rx_clist[cmpconsidx]; desc = &sc->sf_ldata->sf_rx_dlist_big[cur_rx->sf_endidx]; m = desc->sf_mbuf; SF_INC(cmpconsidx, SF_RX_CLIST_CNT); SF_INC(bufprodidx, SF_RX_DLIST_CNT); if (!(cur_rx->sf_status1 & SF_RXSTAT1_OK)) { ifp->if_ierrors++; sf_newbuf(sc, desc, m); continue; } m0 = m_devget(mtod(m, char *) - ETHER_ALIGN, cur_rx->sf_len + ETHER_ALIGN, 0, ifp, NULL); sf_newbuf(sc, desc, m); if (m0 == NULL) { ifp->if_ierrors++; continue; } m_adj(m0, ETHER_ALIGN); m = m0; eh = mtod(m, struct ether_header *); ifp->if_ipackets++; -#if NBPF > 0 +#if NBPFILTER > 0 if (ifp->if_bpf) { bpf_mtap(ifp, m); if (ifp->if_flags & IFF_PROMISC && (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) { m_freem(m); continue; } } #endif /* Remove header from mbuf and pass it on. */ m_adj(m, sizeof(struct ether_header)); ether_input(ifp, eh, m); } csr_write_4(sc, SF_CQ_CONSIDX, (rxcons & ~SF_CQ_CONSIDX_RXQ1) | cmpconsidx); csr_write_4(sc, SF_RXDQ_PTR_Q1, (rxprod & ~SF_RXDQ_PRODIDX) | bufprodidx); return; } /* * Read the transmit status from the completion queue and release * mbufs. Note that the buffer descriptor index in the completion * descriptor is an offset from the start of the transmit buffer * descriptor list in bytes. This is important because the manual * gives the impression that it should match the producer/consumer * index, which is the offset in 8 byte blocks. */ static void sf_txeof(sc) struct sf_softc *sc; { int txcons, cmpprodidx, cmpconsidx; struct sf_tx_cmpdesc_type1 *cur_cmp; struct sf_tx_bufdesc_type0 *cur_tx; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; txcons = csr_read_4(sc, SF_CQ_CONSIDX); cmpprodidx = SF_IDX_HI(csr_read_4(sc, SF_CQ_PRODIDX)); cmpconsidx = SF_IDX_HI(txcons); while (cmpconsidx != cmpprodidx) { cur_cmp = &sc->sf_ldata->sf_tx_clist[cmpconsidx]; cur_tx = &sc->sf_ldata->sf_tx_dlist[cur_cmp->sf_index >> 7]; SF_INC(cmpconsidx, SF_TX_CLIST_CNT); if (cur_cmp->sf_txstat & SF_TXSTAT_TX_OK) ifp->if_opackets++; else ifp->if_oerrors++; sc->sf_tx_cnt--; if (cur_tx->sf_mbuf != NULL) { m_freem(cur_tx->sf_mbuf); cur_tx->sf_mbuf = NULL; } } ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; csr_write_4(sc, SF_CQ_CONSIDX, (txcons & ~SF_CQ_CONSIDX_TXQ) | ((cmpconsidx << 16) & 0xFFFF0000)); return; } static void sf_intr(arg) void *arg; { struct sf_softc *sc; struct ifnet *ifp; u_int32_t status; sc = arg; ifp = &sc->arpcom.ac_if; if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) return; /* Disable interrupts. */ csr_write_4(sc, SF_IMR, 0x00000000); for (;;) { status = csr_read_4(sc, SF_ISR); if (status) csr_write_4(sc, SF_ISR, status); if (!(status & SF_INTRS)) break; if (status & SF_ISR_RXDQ1_DMADONE) sf_rxeof(sc); if (status & SF_ISR_TX_TXDONE) sf_txeof(sc); if (status & SF_ISR_ABNORMALINTR) { if (status & SF_ISR_STATSOFLOW) { untimeout(sf_stats_update, sc, sc->sf_stat_ch); sf_stats_update(sc); } else sf_init(sc); } } /* Re-enable interrupts. */ csr_write_4(sc, SF_IMR, SF_INTRS); if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); return; } static void sf_init(xsc) void *xsc; { struct sf_softc *sc; struct ifnet *ifp; int i, s; s = splimp(); sc = xsc; ifp = &sc->arpcom.ac_if; sf_stop(sc); sf_reset(sc); /* Init all the receive filter registers */ for (i = SF_RXFILT_PERFECT_BASE; i < (SF_RXFILT_HASH_MAX + 1); i += 4) csr_write_4(sc, i, 0); - /* Empty stats counter registers. */ + /* Empty stats counter registers */ for (i = 0; i < sizeof(struct sf_stats)/sizeof(u_int32_t); i++) csr_write_4(sc, SF_STATS_BASE + (i + sizeof(u_int32_t)), 0); /* Init our MAC address */ csr_write_4(sc, SF_PAR0, *(u_int32_t *)(&sc->arpcom.ac_enaddr[0])); csr_write_4(sc, SF_PAR1, *(u_int32_t *)(&sc->arpcom.ac_enaddr[4])); sf_setperf(sc, 0, (caddr_t)&sc->arpcom.ac_enaddr); if (sf_init_rx_ring(sc) == ENOBUFS) { printf("sf%d: initialization failed: no " "memory for rx buffers\n", sc->sf_unit); (void)splx(s); return; } sf_init_tx_ring(sc); csr_write_4(sc, SF_RXFILT, SF_PERFMODE_NORMAL|SF_HASHMODE_WITHVLAN); /* If we want promiscuous mode, set the allframes bit. */ if (ifp->if_flags & IFF_PROMISC) { SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC); } else { SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC); } if (ifp->if_flags & IFF_BROADCAST) { SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_BROAD); } else { SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_BROAD); } /* Init the completion queue indexes */ csr_write_4(sc, SF_CQ_CONSIDX, 0); csr_write_4(sc, SF_CQ_PRODIDX, 0); /* Init the RX completion queue */ csr_write_4(sc, SF_RXCQ_CTL_1, vtophys(sc->sf_ldata->sf_rx_clist) & SF_RXCQ_ADDR); SF_SETBIT(sc, SF_RXCQ_CTL_1, SF_RXCQTYPE_3); /* Init RX DMA control. */ SF_SETBIT(sc, SF_RXDMA_CTL, SF_RXDMA_REPORTBADPKTS); /* Init the RX buffer descriptor queue. */ csr_write_4(sc, SF_RXDQ_ADDR_Q1, vtophys(sc->sf_ldata->sf_rx_dlist_big)); csr_write_4(sc, SF_RXDQ_CTL_1, (MCLBYTES << 16) | SF_DESCSPACE_16BYTES); csr_write_4(sc, SF_RXDQ_PTR_Q1, SF_RX_DLIST_CNT - 1); /* Init the TX completion queue */ csr_write_4(sc, SF_TXCQ_CTL, vtophys(sc->sf_ldata->sf_tx_clist) & SF_RXCQ_ADDR); /* Init the TX buffer descriptor queue. */ csr_write_4(sc, SF_TXDQ_ADDR_HIPRIO, vtophys(sc->sf_ldata->sf_tx_dlist)); SF_SETBIT(sc, SF_TX_FRAMCTL, SF_TXFRMCTL_CPLAFTERTX); csr_write_4(sc, SF_TXDQ_CTL, SF_TXBUFDESC_TYPE0|SF_TXMINSPACE_128BYTES|SF_TXSKIPLEN_8BYTES); SF_SETBIT(sc, SF_TXDQ_CTL, SF_TXDQCTL_NODMACMP); /* Enable autopadding of short TX frames. */ SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_AUTOPAD); /* Make sure the duplex mode is set correctly. */ if ((sc->ifmedia.ifm_media & IFM_GMASK) == IFM_FDX) { SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } else { SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_FULLDUPLEX); } /* Enable interrupts. */ csr_write_4(sc, SF_IMR, SF_INTRS); SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_INTR_ENB); /* Enable the RX and TX engines. */ SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_RX_ENB|SF_ETHCTL_RXDMA_ENB); SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_TX_ENB|SF_ETHCTL_TXDMA_ENB); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); splx(s); return; } static int sf_encap(sc, c, m_head) struct sf_softc *sc; struct sf_tx_bufdesc_type0 *c; struct mbuf *m_head; { int frag = 0; struct sf_frag *f = NULL; struct mbuf *m; m = m_head; for (m = m_head, frag = 0; m != NULL; m = m->m_next) { if (m->m_len != 0) { if (frag == SF_MAXFRAGS) break; f = &c->sf_frags[frag]; if (frag == 0) f->sf_pktlen = m_head->m_pkthdr.len; f->sf_fraglen = m->m_len; f->sf_addr = vtophys(mtod(m, vm_offset_t)); frag++; } } if (m != NULL) { struct mbuf *m_new = NULL; MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { printf("sf%d: no memory for tx list", sc->sf_unit); return(1); } if (m_head->m_pkthdr.len > MHLEN) { MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { m_freem(m_new); printf("sf%d: no memory for tx list", sc->sf_unit); return(1); } } m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t)); m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; m_freem(m_head); m_head = m_new; f = &c->sf_frags[0]; f->sf_fraglen = f->sf_pktlen = m_head->m_pkthdr.len; f->sf_addr = vtophys(mtod(m_head, caddr_t)); frag = 1; } c->sf_mbuf = m_head; c->sf_id = SF_TX_BUFDESC_ID; c->sf_fragcnt = frag; c->sf_intr = 1; c->sf_caltcp = 0; c->sf_crcen = 1; return(0); } static void sf_start(ifp) struct ifnet *ifp; { struct sf_softc *sc; struct sf_tx_bufdesc_type0 *cur_tx = NULL; struct mbuf *m_head = NULL; int i, txprod; sc = ifp->if_softc; if (ifp->if_flags & IFF_OACTIVE) return; if (sc->sf_autoneg) { sc->sf_tx_pend = 1; return; } txprod = csr_read_4(sc, SF_TXDQ_PRODIDX); i = SF_IDX_HI(txprod) >> 4; while(sc->sf_ldata->sf_tx_dlist[i].sf_mbuf == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; cur_tx = &sc->sf_ldata->sf_tx_dlist[i]; sf_encap(sc, cur_tx, m_head); /* * If there's a BPF listener, bounce a copy of this frame * to him. */ -#if NBPF > 0 +#if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp, m_head); #endif SF_INC(i, SF_TX_DLIST_CNT); sc->sf_tx_cnt++; if (sc->sf_tx_cnt == (SF_TX_DLIST_CNT - 2)) break; } if (cur_tx == NULL) return; /* Transmit */ csr_write_4(sc, SF_TXDQ_PRODIDX, (txprod & ~SF_TXDQ_PRODIDX_HIPRIO) | ((i << 20) & 0xFFFF0000)); ifp->if_timer = 5; return; } static void sf_stop(sc) struct sf_softc *sc; { int i; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; untimeout(sf_stats_update, sc, sc->sf_stat_ch); csr_write_4(sc, SF_GEN_ETH_CTL, 0); csr_write_4(sc, SF_CQ_CONSIDX, 0); csr_write_4(sc, SF_CQ_PRODIDX, 0); csr_write_4(sc, SF_RXDQ_ADDR_Q1, 0); csr_write_4(sc, SF_RXDQ_CTL_1, 0); csr_write_4(sc, SF_RXDQ_PTR_Q1, 0); csr_write_4(sc, SF_TXCQ_CTL, 0); csr_write_4(sc, SF_TXDQ_ADDR_HIPRIO, 0); csr_write_4(sc, SF_TXDQ_CTL, 0); sf_reset(sc); for (i = 0; i < SF_RX_DLIST_CNT; i++) { if (sc->sf_ldata->sf_rx_dlist_big[i].sf_mbuf != NULL) { m_freem(sc->sf_ldata->sf_rx_dlist_big[i].sf_mbuf); sc->sf_ldata->sf_rx_dlist_big[i].sf_mbuf = NULL; } } for (i = 0; i < SF_TX_DLIST_CNT; i++) { if (sc->sf_ldata->sf_tx_dlist[i].sf_mbuf != NULL) { m_freem(sc->sf_ldata->sf_tx_dlist[i].sf_mbuf); sc->sf_ldata->sf_tx_dlist[i].sf_mbuf = NULL; } } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); return; } /* * Note: it is important that this function not be interrupted. We * use a two-stage register access scheme: if we are interrupted in * between setting the indirect address register and reading from the * indirect data register, the contents of the address register could * be changed out from under us. - */ + */ static void sf_stats_update(xsc) void *xsc; { struct sf_softc *sc; struct ifnet *ifp; struct sf_stats stats; u_int32_t *ptr; int i, s; s = splimp(); sc = xsc; ifp = &sc->arpcom.ac_if; ptr = (u_int32_t *)&stats; for (i = 0; i < sizeof(stats)/sizeof(u_int32_t); i++) ptr[i] = csr_read_4(sc, SF_STATS_BASE + (i + sizeof(u_int32_t))); for (i = 0; i < sizeof(stats)/sizeof(u_int32_t); i++) csr_write_4(sc, SF_STATS_BASE + (i + sizeof(u_int32_t)), 0); ifp->if_collisions += stats.sf_tx_single_colls + stats.sf_tx_multi_colls + stats.sf_tx_excess_colls; sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); splx(s); return; } static void sf_watchdog(ifp) struct ifnet *ifp; { struct sf_softc *sc; sc = ifp->if_softc; if (sc->sf_autoneg) { sf_autoneg_mii(sc, SF_FLAG_DELAYTIMEO, 1); - if (!(ifp->if_flags & IFF_UP)) - sf_stop(sc); return; } ifp->if_oerrors++; printf("sf%d: watchdog timeout\n", sc->sf_unit); if (sc->sf_pinfo != NULL) { if (!(sf_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) printf("sf%d: no carrier - transceiver " "cable problem?\n", sc->sf_unit); } sf_stop(sc); sf_reset(sc); sf_init(sc); if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); return; } -static void sf_shutdown(dev) - device_t dev; +static void sf_shutdown(howto, arg) + int howto; + void *arg; { struct sf_softc *sc; - sc = device_get_softc(dev); + sc = (struct sf_softc *)arg; sf_stop(sc); return; } + +static struct pci_device sf_device = { + "sf", + sf_probe, + sf_attach, + &sf_count, + NULL +}; + +#ifdef COMPAT_PCI_DRIVER +COMPAT_PCI_DRIVER(sf, sf_device); +#else +DATA_SET(pcidevice_set, sf_device); +#endif Index: stable/3/sys/pci/if_sfreg.h =================================================================== --- stable/3/sys/pci/if_sfreg.h (revision 49544) +++ stable/3/sys/pci/if_sfreg.h (revision 49545) @@ -1,1171 +1,1169 @@ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_sfreg.h,v 1.4 1999/07/21 03:44:25 wpaul Exp $ + * $Id: if_sfreg.h,v 1.9 1999/07/21 04:54:46 wpaul Exp $ */ /* * Registers for the Adaptec AIC-6915 Starfire. The Starfire has a 512K * register space. These registers can be accessed in the following way: * - PCI config registers are always accessible through PCI config space * - Full 512K space mapped into memory using PCI memory mapped access * - 256-byte I/O space mapped through PCI I/O access * - Full 512K space mapped through indirect I/O using PCI I/O access * It's possible to use either memory mapped mode or I/O mode to access * the registers, but memory mapped is usually the easiest. All registers * are 32 bits wide and must be accessed using 32-bit operations. */ /* * Adaptec PCI vendor ID. */ #define AD_VENDORID 0x9004 /* * AIC-6915 PCI device ID. */ #define AD_DEVICEID_STARFIRE 0x6915 /* * AIC-6915 subsystem IDs. Adaptec uses the subsystem ID to identify * the exact kind of NIC on which the ASIC is mounted. Currently there * are six different variations. Note: the Adaptec manual lists code 0x28 * for two different NICs: the 62044 and the 69011/TX. This is a typo: * the code for the 62044 is really 0x18. */ #define AD_SUBSYSID_62011_REV0 0x0008 /* single port 10/100baseTX 64-bit */ #define AD_SUBSYSID_62011_REV1 0x0009 /* single port 10/100baseTX 64-bit */ #define AD_SUBSYSID_62022 0x0010 /* dual port 10/100baseTX 64-bit */ #define AD_SUBSYSID_62044 0x0018 /* quad port 10/100baseTX 64-bit */ #define AD_SUBSYSID_62020 0x0020 /* single port 10/100baseFX 64-bit */ #define AD_SUBSYSID_69011 0x0028 /* single port 10/100baseTX 32-bit */ /* * Starfire internal register space map. The entire register space * is available using PCI memory mapped mode. The SF_RMAP_INTREG * space is available using PCI I/O mode. The entire space can be * accessed using indirect I/O using the indirect I/O addr and * indirect I/O data registers located within the SF_RMAP_INTREG space. */ #define SF_RMAP_ROMADDR_BASE 0x00000 /* Expansion ROM space */ #define SF_RMAP_ROMADDR_MAX 0x3FFFF #define SF_RMAP_EXGPIO_BASE 0x40000 /* External general purpose regs */ #define SF_RMAP_EXGPIO_MAX 0x3FFFF #define SF_RMAP_INTREG_BASE 0x50000 /* Internal functional registers */ #define SF_RMAP_INTREG_MAX 0x500FF #define SF_RMAP_GENREG_BASE 0x50100 /* General purpose registers */ #define SF_RMAP_GENREG_MAX 0x5FFFF #define SF_RMAP_FIFO_BASE 0x60000 #define SF_RMAP_FIFO_MAX 0x6FFFF #define SF_RMAP_STS_BASE 0x70000 #define SF_RMAP_STS_MAX 0x70083 #define SF_RMAP_RSVD_BASE 0x70084 #define SF_RMAP_RSVD_MAX 0x7FFFF /* * PCI config header registers, 0x0000 to 0x003F */ #define SF_PCI_VENDOR_ID 0x0000 #define SF_PCI_DEVICE_ID 0x0002 #define SF_PCI_COMMAND 0x0004 #define SF_PCI_STATUS 0x0006 #define SF_PCI_REVID 0x0008 #define SF_PCI_CLASSCODE 0x0009 #define SF_PCI_CACHELEN 0x000C #define SF_PCI_LATENCY_TIMER 0x000D #define SF_PCI_HEADER_TYPE 0x000E #define SF_PCI_LOMEM 0x0010 #define SF_PCI_LOIO 0x0014 #define SF_PCI_SUBVEN_ID 0x002C #define SF_PCI_SYBSYS_ID 0x002E #define SF_PCI_BIOSROM 0x0030 #define SF_PCI_INTLINE 0x003C #define SF_PCI_INTPIN 0x003D #define SF_PCI_MINGNT 0x003E #define SF_PCI_MINLAT 0x003F /* * PCI registers, 0x0040 to 0x006F */ #define SF_PCI_DEVCFG 0x0040 #define SF_BACCTL 0x0044 #define SF_PCI_MON1 0x0048 #define SF_PCI_MON2 0x004C #define SF_PCI_CAPID 0x0050 /* 8 bits */ #define SF_PCI_NEXTPTR 0x0051 /* 8 bits */ #define SF_PCI_PWRMGMTCAP 0x0052 /* 16 bits */ #define SF_PCI_PWRMGMTCTRL 0x0054 /* 16 bits */ #define SF_PCI_PME_EVENT 0x0058 #define SF_PCI_EECTL 0x0060 #define SF_PCI_COMPLIANCE 0x0064 #define SF_INDIRECTIO_ADDR 0x0068 #define SF_INDIRECTIO_DATA 0x006C #define SF_PCIDEVCFG_RESET 0x00000001 #define SF_PCIDEVCFG_FORCE64 0x00000002 #define SF_PCIDEVCFG_SYSTEM64 0x00000004 #define SF_PCIDEVCFG_RSVD0 0x00000008 #define SF_PCIDEVCFG_INCR_INB 0x00000010 #define SF_PCIDEVCFG_ABTONPERR 0x00000020 #define SF_PCIDEVCFG_STPONPERR 0x00000040 #define SF_PCIDEVCFG_MR_ENB 0x00000080 #define SF_PCIDEVCFG_FIFOTHR 0x00000F00 #define SF_PCIDEVCFG_STPONCA 0x00001000 #define SF_PCIDEVCFG_PCIMEN 0x00002000 /* enable PCI bus master */ #define SF_PCIDEVCFG_LATSTP 0x00004000 #define SF_PCIDEVCFG_BYTE_ENB 0x00008000 #define SF_PCIDEVCFG_EECSWIDTH 0x00070000 #define SF_PCIDEVCFG_STPMWCA 0x00080000 #define SF_PCIDEVCFG_REGCSWIDTH 0x00700000 #define SF_PCIDEVCFG_INTR_ENB 0x00800000 #define SF_PCIDEVCFG_DPR_ENB 0x01000000 #define SF_PCIDEVCFG_RSVD1 0x02000000 #define SF_PCIDEVCFG_RSVD2 0x04000000 #define SF_PCIDEVCFG_STA_ENB 0x08000000 #define SF_PCIDEVCFG_RTA_ENB 0x10000000 #define SF_PCIDEVCFG_RMA_ENB 0x20000000 #define SF_PCIDEVCFG_SSE_ENB 0x40000000 #define SF_PCIDEVCFG_DPE_ENB 0x80000000 #define SF_BACCTL_BACDMA_ENB 0x00000001 #define SF_BACCTL_PREFER_RXDMA 0x00000002 #define SF_BACCTL_PREFER_TXDMA 0x00000004 #define SF_BACCTL_SINGLE_DMA 0x00000008 #define SF_BACCTL_SWAPMODE_DATA 0x00000030 #define SF_BACCTL_SWAPMODE_DESC 0x000000C0 #define SF_SWAPMODE_LE 0x00000000 #define SF_SWAPMODE_BE 0x00000010 #define SF_PSTATE_MASK 0x0003 #define SF_PSTATE_D0 0x0000 #define SF_PSTATE_D1 0x0001 #define SF_PSTATE_D2 0x0002 #define SF_PSTATE_D3 0x0003 #define SF_PME_EN 0x0010 #define SF_PME_STATUS 0x8000 /* * Ethernet registers 0x0070 to 0x00FF */ #define SF_GEN_ETH_CTL 0x0070 #define SF_TIMER_CTL 0x0074 #define SF_CURTIME 0x0078 #define SF_ISR 0x0080 #define SF_ISR_SHADOW 0x0084 #define SF_IMR 0x0088 #define SF_GPIO 0x008C #define SF_TXDQ_CTL 0x0090 #define SF_TXDQ_ADDR_HIPRIO 0x0094 #define SF_TXDQ_ADDR_LOPRIO 0x0098 #define SF_TXDQ_ADDR_HIADDR 0x009C #define SF_TXDQ_PRODIDX 0x00A0 #define SF_TXDQ_CONSIDX 0x00A4 #define SF_TXDMA_STS1 0x00A8 #define SF_TXDMA_STS2 0x00AC #define SF_TX_FRAMCTL 0x00B0 #define SF_TXCQ_ADDR_HI 0x00B4 #define SF_TXCQ_CTL 0x00B8 #define SF_RXCQ_CTL_1 0x00BC #define SF_RXCQ_CTL_2 0x00C0 #define SF_CQ_CONSIDX 0x00C4 #define SF_CQ_PRODIDX 0x00C8 #define SF_CQ_RXQ2 0x00CC #define SF_RXDMA_CTL 0x00D0 #define SF_RXDQ_CTL_1 0x00D4 #define SF_RXDQ_CTL_2 0x00D8 #define SF_RXDQ_ADDR_HIADDR 0x00DC #define SF_RXDQ_ADDR_Q1 0x00E0 #define SF_RXDQ_ADDR_Q2 0x00E4 #define SF_RXDQ_PTR_Q1 0x00E8 #define SF_RXDQ_PTR_Q2 0x00EC #define SF_RXDMA_STS 0x00F0 #define SF_RXFILT 0x00F4 #define SF_RX_FRAMETEST_OUT 0x00F8 /* Ethernet control register */ #define SF_ETHCTL_RX_ENB 0x00000001 #define SF_ETHCTL_TX_ENB 0x00000002 #define SF_ETHCTL_RXDMA_ENB 0x00000004 #define SF_ETHCTL_TXDMA_ENB 0x00000008 #define SF_ETHCTL_RXGFP_ENB 0x00000010 #define SF_ETHCTL_TXGFP_ENB 0x00000020 #define SF_ETHCTL_SOFTINTR 0x00000800 /* Timer control register */ #define SF_TIMER_IMASK_INTERVAL 0x0000001F #define SF_TIMER_IMASK_MODE 0x00000060 #define SF_TIMER_SMALLFRAME_BYP 0x00000100 #define SF_TIMER_SMALLRX_FRAME 0x00000600 #define SF_TIMER_TIMES_TEN 0x00000800 #define SF_TIMER_RXHIPRIO_BYP 0x00001000 #define SF_TIMER_TX_DMADONE_DLY 0x00002000 #define SF_TIMER_TX_QDONE_DLY 0x00004000 #define SF_TIMER_TX_FRDONE_DLY 0x00008000 #define SF_TIMER_GENTIMER 0x00FF0000 #define SF_TIMER_ONESHOT 0x01000000 #define SF_TIMER_GENTIMER_RES 0x02000000 #define SF_TIMER_TIMEST_RES 0x04000000 #define SF_TIMER_RXQ2DONE_DLY 0x10000000 #define SF_TIMER_EARLYRX2_DLY 0x20000000 #define SF_TIMER_RXQ1DONE_DLY 0x40000000 #define SF_TIMER_EARLYRX1_DLY 0x80000000 /* Interrupt status register */ #define SF_ISR_PCIINT_ASSERTED 0x00000001 #define SF_ISR_GFP_TX 0x00000002 #define SF_ISR_GFP_RX 0x00000004 #define SF_ISR_TX_BADID_HIPRIO 0x00000008 #define SF_ISR_TX_BADID_LOPRIO 0x00000010 #define SF_ISR_NO_TX_CSUM 0x00000020 #define SF_ISR_RXDQ2_NOBUFS 0x00000040 #define SF_ISR_RXGFP_NORESP 0x00000080 #define SF_ISR_RXDQ1_DMADONE 0x00000100 #define SF_ISR_RXDQ2_DMADONE 0x00000200 #define SF_ISR_RXDQ1_EARLY 0x00000400 #define SF_ISR_RXDQ2_EARLY 0x00000800 #define SF_ISR_TX_QUEUEDONE 0x00001000 #define SF_ISR_TX_DMADONE 0x00002000 #define SF_ISR_TX_TXDONE 0x00004000 #define SF_ISR_NORMALINTR 0x00008000 #define SF_ISR_RXDQ1_NOBUFS 0x00010000 #define SF_ISR_RXCQ2_NOBUFS 0x00020000 #define SF_ISR_TX_LOFIFO 0x00040000 #define SF_ISR_DMAERR 0x00080000 #define SF_ISR_PCIINT 0x00100000 #define SF_ISR_TXCQ_NOBUFS 0x00200000 #define SF_ISR_RXCQ1_NOBUFS 0x00400000 #define SF_ISR_SOFTINTR 0x00800000 #define SF_ISR_GENTIMER 0x01000000 #define SF_ISR_ABNORMALINTR 0x02000000 #define SF_ISR_RSVD0 0x04000000 #define SF_ISR_STATSOFLOW 0x08000000 #define SF_ISR_GPIO 0xF0000000 /* * Shadow interrupt status register. Unlike the normal IRQ register, * reading bits here does not automatically cause them to reset. */ #define SF_SISR_PCIINT_ASSERTED 0x00000001 #define SF_SISR_GFP_TX 0x00000002 #define SF_SISR_GFP_RX 0x00000004 #define SF_SISR_TX_BADID_HIPRIO 0x00000008 #define SF_SISR_TX_BADID_LOPRIO 0x00000010 #define SF_SISR_NO_TX_CSUM 0x00000020 #define SF_SISR_RXDQ2_NOBUFS 0x00000040 #define SF_SISR_RXGFP_NORESP 0x00000080 #define SF_SISR_RXDQ1_DMADONE 0x00000100 #define SF_SISR_RXDQ2_DMADONE 0x00000200 #define SF_SISR_RXDQ1_EARLY 0x00000400 #define SF_SISR_RXDQ2_EARLY 0x00000800 #define SF_SISR_TX_QUEUEDONE 0x00001000 #define SF_SISR_TX_DMADONE 0x00002000 #define SF_SISR_TX_TXDONE 0x00004000 #define SF_SISR_NORMALINTR 0x00008000 #define SF_SISR_RXDQ1_NOBUFS 0x00010000 #define SF_SISR_RXCQ2_NOBUFS 0x00020000 #define SF_SISR_TX_LOFIFO 0x00040000 #define SF_SISR_DMAERR 0x00080000 #define SF_SISR_PCIINT 0x00100000 #define SF_SISR_TXCQ_NOBUFS 0x00200000 #define SF_SISR_RXCQ1_NOBUFS 0x00400000 #define SF_SISR_SOFTINTR 0x00800000 #define SF_SISR_GENTIMER 0x01000000 #define SF_SISR_ABNORMALINTR 0x02000000 #define SF_SISR_RSVD0 0x04000000 #define SF_SISR_STATSOFLOW 0x08000000 #define SF_SISR_GPIO 0xF0000000 /* Interrupt mask register */ #define SF_IMR_PCIINT_ASSERTED 0x00000001 #define SF_IMR_GFP_TX 0x00000002 #define SF_IMR_GFP_RX 0x00000004 #define SF_IMR_TX_BADID_HIPRIO 0x00000008 #define SF_IMR_TX_BADID_LOPRIO 0x00000010 #define SF_IMR_NO_TX_CSUM 0x00000020 #define SF_IMR_RXDQ2_NOBUFS 0x00000040 #define SF_IMR_RXGFP_NORESP 0x00000080 #define SF_IMR_RXDQ1_DMADONE 0x00000100 #define SF_IMR_RXDQ2_DMADONE 0x00000200 #define SF_IMR_RXDQ1_EARLY 0x00000400 #define SF_IMR_RXDQ2_EARLY 0x00000800 #define SF_IMR_TX_QUEUEDONE 0x00001000 #define SF_IMR_TX_DMADONE 0x00002000 #define SF_IMR_TX_TXDONE 0x00004000 #define SF_IMR_NORMALINTR 0x00008000 #define SF_IMR_RXDQ1_NOBUFS 0x00010000 #define SF_IMR_RXCQ2_NOBUFS 0x00020000 #define SF_IMR_TX_LOFIFO 0x00040000 #define SF_IMR_DMAERR 0x00080000 #define SF_IMR_PCIINT 0x00100000 #define SF_IMR_TXCQ_NOBUFS 0x00200000 #define SF_IMR_RXCQ1_NOBUFS 0x00400000 #define SF_IMR_SOFTINTR 0x00800000 #define SF_IMR_GENTIMER 0x01000000 #define SF_IMR_ABNORMALINTR 0x02000000 #define SF_IMR_RSVD0 0x04000000 #define SF_IMR_STATSOFLOW 0x08000000 #define SF_IMR_GPIO 0xF0000000 #define SF_INTRS \ (SF_IMR_RXDQ2_NOBUFS|SF_IMR_RXDQ1_DMADONE|SF_IMR_RXDQ2_DMADONE| \ SF_IMR_TX_TXDONE|SF_IMR_RXDQ1_NOBUFS|SF_IMR_RXDQ2_DMADONE| \ SF_IMR_NORMALINTR|SF_IMR_ABNORMALINTR|SF_IMR_TXCQ_NOBUFS| \ SF_IMR_RXCQ1_NOBUFS|SF_IMR_RXCQ2_NOBUFS|SF_IMR_STATSOFLOW) /* TX descriptor queue control registers */ #define SF_TXDQCTL_DESCTYPE 0x00000007 #define SF_TXDQCTL_NODMACMP 0x00000008 #define SF_TXDQCTL_MINSPACE 0x00000070 #define SF_TXDQCTL_64BITADDR 0x00000080 #define SF_TXDQCTL_BURSTLEN 0x00003F00 #define SF_TXDQCTL_SKIPLEN 0x001F0000 #define SF_TXDQCTL_HIPRIOTHRESH 0xFF000000 #define SF_TXBUFDESC_TYPE0 0x00000000 #define SF_TXBUFDESC_TYPE1 0x00000001 #define SF_TXBUFDESC_TYPE2 0x00000002 #define SF_TXBUFDESC_TYPE3 0x00000003 #define SF_TXBUFDESC_TYPE4 0x00000004 #define SF_TXMINSPACE_UNLIMIT 0x00000000 #define SF_TXMINSPACE_32BYTES 0x00000010 #define SF_TXMINSPACE_64BYTES 0x00000020 #define SF_TXMINSPACE_128BYTES 0x00000030 #define SF_TXMINSPACE_256BYTES 0x00000040 #define SF_TXSKIPLEN_0BYTES 0x00000000 #define SF_TXSKIPLEN_8BYTES 0x00010000 #define SF_TXSKIPLEN_16BYTES 0x00020000 #define SF_TXSKIPLEN_24BYTES 0x00030000 #define SF_TXSKIPLEN_32BYTES 0x00040000 /* TX frame control register */ #define SF_TXFRMCTL_TXTHRESH 0x000000FF #define SF_TXFRMCTL_CPLAFTERTX 0x00000100 #define SF_TXFRMCRL_DEBUG 0x0000FE00 #define SF_TXFRMCTL_STATUS 0x01FF0000 #define SF_TXFRMCTL_MAC_TXIF 0xFE000000 /* TX completion queue control register */ #define SF_TXCQ_THRESH 0x0000000F #define SF_TXCQ_COMMON 0x00000010 #define SF_TXCQ_SIZE 0x00000020 #define SF_TXCQ_WRITEENB 0x00000040 #define SF_TXCQ_USE_64BIT 0x00000080 #define SF_TXCQ_ADDR 0xFFFFFF00 /* RX completion queue control register */ #define SF_RXCQ_THRESH 0x0000000F #define SF_RXCQ_TYPE 0x00000030 #define SF_RXCQ_WRITEENB 0x00000040 #define SF_RXCQ_USE_64BIT 0x00000080 #define SF_RXCQ_ADDR 0xFFFFFF00 #define SF_RXCQTYPE_0 0x00000000 #define SF_RXCQTYPE_1 0x00000010 #define SF_RXCQTYPE_2 0x00000020 #define SF_RXCQTYPE_3 0x00000030 /* TX descriptor queue producer index register */ #define SF_TXDQ_PRODIDX_LOPRIO 0x000007FF #define SF_TXDQ_PRODIDX_HIPRIO 0x07FF0000 /* TX descriptor queue consumer index register */ #define SF_TXDQ_CONSIDX_LOPRIO 0x000007FF #define SF_TXDQ_CONSIDX_HIPRIO 0x07FF0000 /* Completion queue consumer index register */ #define SF_CQ_CONSIDX_RXQ1 0x000003FF #define SF_CQ_CONSIDX_RXTHRMODE 0x00008000 #define SF_CQ_CONSIDX_TXQ 0x03FF0000 #define SF_CQ_CONSIDX_TXTHRMODE 0x80000000 /* Completion queue producer index register */ #define SF_CQ_PRODIDX_RXQ1 0x000003FF #define SF_CQ_PRODIDX_TXQ 0x03FF0000 /* RX completion queue 2 consumer/producer index register */ #define SF_CQ_RXQ2_CONSIDX 0x000003FF #define SF_CQ_RXQ2_RXTHRMODE 0x00008000 #define SF_CQ_RXQ2_PRODIDX 0x03FF0000 #define SF_CQ_RXTHRMODE_INT_ON 0x00008000 #define SF_CQ_RXTHRMODE_INT_OFF 0x00000000 #define SF_CQ_TXTHRMODE_INT_ON 0x80000000 #define SF_CQ_TXTHRMODE_INT_OFF 0x00000000 #define SF_IDX_LO(x) ((x) & 0x000007FF) #define SF_IDX_HI(x) (((x) >> 16) & 0x000007FF) /* RX DMA control register */ #define SF_RXDMA_BURSTSIZE 0x0000007F #define SF_RXDMA_FPTESTMODE 0x00000080 #define SF_RXDMA_HIPRIOTHRESH 0x00000F00 #define SF_RXDMA_RXEARLYTHRESH 0x0001F000 #define SF_RXDMA_DMACRC 0x00040000 #define SF_RXDMA_USEBKUPQUEUE 0x00080000 #define SF_RXDMA_QUEUEMODE 0x00700000 #define SF_RXDMA_RXCQ2_ON 0x00800000 #define SF_RXDMA_CSUMMODE 0x03000000 #define SF_RXDMA_DMAPAUSEPKTS 0x04000000 #define SF_RXDMA_DMACTLPKTS 0x08000000 #define SF_RXDMA_DMACRXERRPKTS 0x10000000 #define SF_RXDMA_DMABADPKTS 0x20000000 #define SF_RXDMA_DMARUNTS 0x40000000 #define SF_RXDMA_REPORTBADPKTS 0x80000000 #define SF_RXDQMODE_Q1ONLY 0x00100000 #define SF_RXDQMODE_Q2_ON_FP 0x00200000 #define SF_RXDQMODE_Q2_ON_SHORT 0x00300000 #define SF_RXDQMODE_Q2_ON_PRIO 0x00400000 #define SF_RXDQMODE_SPLITHDR 0x00500000 #define SF_RXCSUMMODE_IGNORE 0x00000000 #define SF_RXCSUMMODE_REJECT_BAD_TCP 0x01000000 #define SF_RXCSUMMODE_REJECT_BAD_TCPUDP 0x02000000 #define SF_RXCSUMMODE_RSVD 0x03000000 /* RX descriptor queue control registers */ #define SF_RXDQCTL_MINDESCTHR 0x0000007F #define SF_RXDQCTL_Q1_WE 0x00000080 #define SF_RXDQCTL_DESCSPACE 0x00000700 #define SF_RXDQCTL_64BITDADDR 0x00000800 #define SF_RXDQCTL_64BITBADDR 0x00001000 #define SF_RXDQCTL_VARIABLE 0x00002000 #define SF_RXDQCTL_ENTRIES 0x00004000 #define SF_RXDQCTL_PREFETCH 0x00008000 #define SF_RXDQCTL_BUFLEN 0xFFFF0000 #define SF_DESCSPACE_4BYTES 0x00000000 #define SF_DESCSPACE_8BYTES 0x00000100 #define SF_DESCSPACE_16BYTES 0x00000200 #define SF_DESCSPACE_32BYTES 0x00000300 #define SF_DESCSPACE_64BYTES 0x00000400 #define SF_DESCSPACE_128_BYTES 0x00000500 /* RX buffer consumer/producer index registers */ #define SF_RXDQ_PRODIDX 0x000007FF #define SF_RXDQ_CONSIDX 0x07FF0000 /* RX filter control register */ #define SF_RXFILT_PROMISC 0x00000001 #define SF_RXFILT_ALLMULTI 0x00000002 #define SF_RXFILT_BROAD 0x00000004 #define SF_RXFILT_HASHPRIO 0x00000008 #define SF_RXFILT_HASHMODE 0x00000030 #define SF_RXFILT_PERFMODE 0x000000C0 #define SF_RXFILT_VLANMODE 0x00000300 #define SF_RXFILT_WAKEMODE 0x00000C00 #define SF_RXFILT_MULTI_NOBROAD 0x00001000 #define SF_RXFILT_MIN_VLANPRIO 0x0000E000 #define SF_RXFILT_PEFECTPRIO 0xFFFF0000 /* Hash filtering mode */ #define SF_HASHMODE_OFF 0x00000000 #define SF_HASHMODE_WITHVLAN 0x00000010 #define SF_HASHMODE_ANYVLAN 0x00000020 #define SF_HASHMODE_ANY 0x00000030 /* Perfect filtering mode */ #define SF_PERFMODE_OFF 0x00000000 #define SF_PERFMODE_NORMAL 0x00000040 #define SF_PERFMODE_INVERSE 0x00000080 #define SF_PERFMODE_VLAN 0x000000C0 /* VLAN mode */ #define SF_VLANMODE_OFF 0x00000000 #define SF_VLANMODE_NOSTRIP 0x00000100 #define SF_VLANMODE_STRIP 0x00000200 #define SF_VLANMODE_RSVD 0x00000300 /* Wakeup mode */ #define SF_WAKEMODE_OFF 0x00000000 #define SF_WAKEMODE_FILTER 0x00000400 #define SF_WAKEMODE_FP 0x00000800 #define SF_WAKEMODE_HIPRIO 0x00000C00 /* * Extra PCI registers 0x0100 to 0x0FFF */ #define SF_PCI_TARGSTAT 0x0100 #define SF_PCI_MASTSTAT1 0x0104 #define SF_PCI_MASTSTAT2 0x0108 #define SF_PCI_DMAHOSTADDR_LO 0x010C #define SF_BAC_DMADIAG0 0x0110 #define SF_BAC_DMADIAG1 0x0114 #define SF_BAC_DMADIAG2 0x0118 #define SF_BAC_DMADIAG3 0x011C #define SF_PAR0 0x0120 #define SF_PAR1 0x0124 #define SF_PCICB_FUNCEVENT 0x0130 #define SF_PCICB_FUNCEVENT_MASK 0x0134 #define SF_PCICB_FUNCSTATE 0x0138 #define SF_PCICB_FUNCFORCE 0x013C /* * Serial EEPROM registers 0x1000 to 0x1FFF * Presumeably the EEPROM is mapped into this 8K window. */ #define SF_EEADDR_BASE 0x1000 #define SF_EEADDR_MAX 0x1FFF #define SF_EE_NODEADDR 14 /* * MII registers registers 0x2000 to 0x3FFF * There are 32 sets of 32 registers, one set for each possible * PHY address. Each 32 bit register is split into a 16-bit data * port and a couple of status bits. */ #define SF_MIIADDR_BASE 0x2000 #define SF_MIIADDR_MAX 0x3FFF #define SF_MII_BLOCKS 32 #define SF_MII_DATAVALID 0x80000000 #define SF_MII_BUSY 0x40000000 #define SF_MII_DATAPORT 0x0000FFFF #define SF_PHY_REG(phy, reg) \ (SF_MIIADDR_BASE + (phy * SF_MII_BLOCKS * sizeof(u_int32_t)) + \ (reg * sizeof(u_int32_t))) /* * Ethernet extra registers 0x4000 to 0x4FFF */ #define SF_TESTMODE 0x4000 #define SF_RX_FRAMEPROC_CTL 0x4004 #define SF_TX_FRAMEPROC_CTL 0x4008 /* * MAC registers 0x5000 to 0x5FFF */ #define SF_MACCFG_1 0x5000 #define SF_MACCFG_2 0x5004 #define SF_BKTOBKIPG 0x5008 #define SF_NONBKTOBKIPG 0x500C #define SF_COLRETRY 0x5010 #define SF_MAXLEN 0x5014 #define SF_TXNIBBLECNT 0x5018 #define SF_TXBYTECNT 0x501C #define SF_RETXCNT 0x5020 #define SF_RANDNUM 0x5024 #define SF_RANDNUM_MASK 0x5028 #define SF_TOTALTXCNT 0x5034 #define SF_RXBYTECNT 0x5040 #define SF_TXPAUSETIMER 0x5060 #define SF_VLANTYPE 0x5064 #define SF_MIISTATUS 0x5070 #define SF_MACCFG1_HUGEFRAMES 0x00000001 #define SF_MACCFG1_FULLDUPLEX 0x00000002 #define SF_MACCFG1_AUTOPAD 0x00000004 #define SF_MACCFG1_HDJAM 0x00000008 #define SF_MACCFG1_DELAYCRC 0x00000010 #define SF_MACCFG1_NOBACKOFF 0x00000020 #define SF_MACCFG1_LENGTHCHECK 0x00000040 #define SF_MACCFG1_PUREPREAMBLE 0x00000080 #define SF_MACCFG1_PASSALLRX 0x00000100 #define SF_MACCFG1_PREAM_DETCNT 0x00000200 #define SF_MACCFG1_RX_FLOWENB 0x00000400 #define SF_MACCFG1_TX_FLOWENB 0x00000800 #define SF_MACCFG1_TESTMODE 0x00003000 #define SF_MACCFG1_MIILOOPBK 0x00004000 #define SF_MACCFG1_SOFTRESET 0x00008000 /* * RX filter registers 0x6000 to 0x6FFF */ #define SF_RXFILT_PERFECT_BASE 0x6000 #define SF_RXFILT_PERFECT_MAX 0x60FF #define SF_RXFILT_PERFECT_SKIP 0x0010 #define SF_RXFILT_PERFECT_CNT 0x0010 #define SF_RXFILT_HASH_BASE 0x6100 #define SF_RXFILT_HASH_MAX 0x62FF #define SF_RXFILT_HASH_SKIP 0x0010 #define SF_RXFILT_HASH_CNT 0x001F #define SF_RXFILT_HASH_ADDROFF 0x0000 #define SF_RXFILT_HASH_PRIOOFF 0x0004 #define SF_RXFILT_HASH_VLANOFF 0x0008 /* * Statistics registers 0x7000 to 0x7FFF */ #define SF_STATS_BASE 0x7000 #define SF_STATS_END 0x7FFF /* * TX frame processor instruction space 0x8000 to 0x9FFF */ /* * RX frame processor instruction space 0xA000 to 0xBFFF */ /* * Ethernet FIFO access space 0xC000 to 0xDFFF */ /* * Reserved 0xE000 to 0xFFFF */ /* * Descriptor data structures. */ /* Receive descriptor formats. */ #define SF_RX_MINSPACING 8 #define SF_RX_DLIST_CNT 256 #define SF_RX_CLIST_CNT 1024 #define SF_RX_HOSTADDR(x) (((x) >> 2) & 0x3FFFFFFF) /* * RX buffer descriptor type 0, 32-bit addressing. Note that we * program the RX buffer queue control register(s) to allow a * descriptor spacing of 16 bytes, which leaves room after each * descriptor to store a pointer to the mbuf for each buffer. */ struct sf_rx_bufdesc_type0 { u_int32_t sf_valid:1, sf_end:1, sf_addrlo:30; u_int32_t sf_pad0; #ifdef __i386__ u_int32_t sf_pad1; #endif struct mbuf *sf_mbuf; }; /* * RX buffer descriptor type 0, 64-bit addressing. */ struct sf_rx_bufdesc_type1 { u_int32_t sf_valid:1, sf_end:1, sf_addrlo:30; u_int32_t sf_addrhi; #ifdef __i386__ u_int32_t sf_pad; #endif struct mbuf *sf_mbuf; }; /* * RX completion descriptor, type 0 (short). */ struct sf_rx_cmpdesc_type0 { u_int32_t sf_len:16, sf_endidx:11, sf_status1:3, sf_id:2; }; /* * RX completion descriptor, type 1 (basic). Includes vlan ID * if this is a vlan-addressed packet, plus extended status. */ struct sf_rx_cmpdesc_type1 { u_int32_t sf_len:16, sf_endidx:11, sf_status1:3, sf_id:2; u_int16_t sf_status2; u_int16_t sf_vlanid; }; /* * RX completion descriptor, type 2 (checksum). Includes partial TCP/IP * checksum instead of vlan tag, plus extended status. */ struct sf_rx_cmpdesc_type2 { u_int32_t sf_len:16, sf_endidx:11, sf_status1:3, sf_id:2; u_int16_t sf_status2; u_int16_t sf_cksum; }; /* * RX completion descriptor type 3 (full). Includes timestamp, partial * TCP/IP checksum, vlan tag plus priority, two extended status fields. */ struct sf_rx_cmpdesc_type3 { u_int32_t sf_len:16, sf_endidx:11, sf_status1:3, sf_id:2; u_int32_t sf_startidx:10, sf_status3:6, sf_status2:16; u_int16_t sf_cksum; u_int16_t sf_vlanid_prio; u_int32_t sf_timestamp; }; #define SF_RXSTAT1_QUEUE 0x1 #define SF_RXSTAT1_FIFOFULL 0x2 #define SF_RXSTAT1_OK 0x4 /* 0=unknown,5=unsupported */ #define SF_RXSTAT2_FRAMETYPE 0x0007 /* 1=IPv4,2=IPv2,3=IPX,4=ICMP */ #define SF_RXSTAT2_UDP 0x0008 #define SF_RXSTAT2_TCP 0x0010 #define SF_RXSTAT2_FRAG 0x0020 #define SF_RXSTAT2_PCSUM_OK 0x0040 /* partial checksum ok */ #define SF_RXSTAT2_CSUM_BAD 0x0080 /* TCP/IP checksum bad */ #define SF_RXSTAT2_CSUM_OK 0x0100 /* TCP/IP checksum ok */ #define SF_RXSTAT2_VLAN 0x0200 #define SF_RXSTAT2_BADRXCODE 0x0400 #define SF_RXSTAT2_DRIBBLE 0x0800 #define SF_RXSTAT2_ISL_CRCERR 0x1000 #define SF_RXSTAT2_CRCERR 0x2000 #define SF_RXSTAT2_HASH 0x4000 #define SF_RXSTAT2_PERFECT 0x8000 #define SF_RXSTAT3_TRAILER 0x01 #define SF_RXSTAT3_HEADER 0x02 #define SF_RXSTAT3_CONTROL 0x04 #define SF_RXSTAT3_PAUSE 0x08 #define SF_RXSTAT3_ISL 0x10 /* * Transmit descriptor formats. * Each transmit descriptor type allows for a skip field at the * start of each structure. The size of the skip field can vary, * however we always set it for 8 bytes, which is enough to hold * a pointer (32 bits on x86, 64-bits on alpha) that we can use * to hold the address of the head of the mbuf chain for the * frame or fragment associated with the descriptor. This saves * us from having to create a separate pointer array to hold * the mbuf addresses. */ #define SF_TX_BUFDESC_ID 0xB #define SF_MAXFRAGS 14 #define SF_TX_MINSPACING 128 #define SF_TX_DLIST_CNT 128 #define SF_TX_DLIST_SIZE 16384 #define SF_TX_SKIPLEN 1 #define SF_TX_CLIST_CNT 1024 struct sf_frag { u_int32_t sf_addr; u_int16_t sf_fraglen; u_int16_t sf_pktlen; }; struct sf_frag_msdos { u_int16_t sf_pktlen; u_int16_t sf_fraglen; u_int32_t sf_addr; }; /* * TX frame descriptor type 0, 32-bit addressing. One descriptor can * be used to map multiple packet fragments. We use this format since * BSD networking fragments packet data across mbuf chains. Note that * the number of fragments can be variable depending on how the descriptor * spacing is specified in the TX descriptor queue control register. * We always use a spacing of 128 bytes, and a skipfield length of 8 * bytes: this means 16 bytes for the descriptor, including the skipfield, * with 121 bytes left for fragment maps. Each fragment requires 8 bytes, * which allows for 14 fragments per descriptor. The total size of the * transmit buffer queue is limited to 16384 bytes, so with a spacing of * 128 bytes per descriptor, we have room for 128 descriptors in the queue. */ struct sf_tx_bufdesc_type0 { #ifdef __i386__ u_int32_t sf_pad; #endif struct mbuf *sf_mbuf; u_int32_t sf_rsvd0:24, sf_crcen:1, sf_caltcp:1, sf_end:1, sf_intr:1, sf_id:4; u_int8_t sf_fragcnt; u_int8_t sf_rsvd2; u_int16_t sf_rsvd1; struct sf_frag sf_frags[14]; }; /* * TX buffer descriptor type 1, 32-bit addressing. Each descriptor * maps a single fragment. */ struct sf_tx_bufdesc_type1 { #ifdef __i386__ u_int32_t sf_pad; #endif struct mbuf *sf_mbuf; u_int32_t sf_fraglen:16, sf_fragcnt:8, sf_crcen:1, sf_caltcp:1, sf_end:1, sf_intr:1, sf_id:4; u_int32_t sf_addr; }; /* * TX buffer descriptor type 2, 64-bit addressing. Each descriptor * maps a single fragment. */ struct sf_tx_bufdesc_type2 { #ifdef __i386__ u_int32_t sf_pad; #endif struct mbuf *sf_mbuf; u_int32_t sf_fraglen:16, sf_fragcnt:8, sf_crcen:1, sf_caltcp:1, sf_end:1, sf_intr:1, sf_id:4; u_int32_t sf_addrlo; u_int32_t sf_addrhi; }; /* TX buffer descriptor type 3 is not defined. */ /* * TX frame descriptor type 4, 32-bit addressing. This is a special * case of the type 0 descriptor, identical except that the fragment * address and length fields are ordered differently. This is done * to optimize copies in MS-DOS and OS/2 drivers. */ struct sf_tx_bufdesc_type4 { #ifdef __i386__ u_int32_t sf_pad; #endif struct mbuf *sf_mbuf; u_int32_t sf_rsvd0:24, sf_crcen:1, sf_caltcp:1, sf_end:1, sf_intr:1, sf_id:4; u_int8_t sf_fragcnt; u_int8_t sf_rsvd2; u_int16_t sf_rsvd1; struct sf_frag_msdos sf_frags[14]; }; /* * Transmit completion queue descriptor formats. */ /* * Transmit DMA completion descriptor, type 0. */ #define SF_TXCMPTYPE_DMA 0x4 struct sf_tx_cmpdesc_type0 { u_int32_t sf_index:15, sf_priority:1, sf_timestamp:13, sf_type:3; }; /* * Transmit completion descriptor, type 1. */ #define SF_TXCMPTYPE_TX 0x5 struct sf_tx_cmpdesc_type1 { u_int32_t sf_index:15, sf_priority:1, sf_txstat:13, sf_type:3; }; #define SF_TXSTAT_CRCERR 0x0001 #define SF_TXSTAT_LENCHECKERR 0x0002 #define SF_TXSTAT_LENRANGEERR 0x0004 #define SF_TXSTAT_TX_OK 0x0008 #define SF_TXSTAT_TX_DEFERED 0x0010 #define SF_TXSTAT_EXCESS_DEFER 0x0020 #define SF_TXSTAT_EXCESS_COLL 0x0040 #define SF_TXSTAT_LATE_COLL 0x0080 #define SF_TXSTAT_TOOBIG 0x0100 #define SF_TXSTAT_TX_UNDERRUN 0x0200 #define SF_TXSTAT_CTLFRAME_OK 0x0400 #define SF_TXSTAT_PAUSEFRAME_OK 0x0800 #define SF_TXSTAT_PAUSED 0x1000 /* Statistics counters. */ struct sf_stats { u_int32_t sf_tx_frames; u_int32_t sf_tx_single_colls; u_int32_t sf_tx_multi_colls; u_int32_t sf_tx_crcerrs; u_int32_t sf_tx_bytes; u_int32_t sf_tx_defered; u_int32_t sf_tx_late_colls; u_int32_t sf_tx_pause_frames; u_int32_t sf_tx_control_frames; u_int32_t sf_tx_excess_colls; u_int32_t sf_tx_excess_defer; u_int32_t sf_tx_mcast_frames; u_int32_t sf_tx_bcast_frames; u_int32_t sf_tx_frames_lost; u_int32_t sf_rx_rx_frames; u_int32_t sf_rx_crcerrs; u_int32_t sf_rx_alignerrs; u_int32_t sf_rx_bytes; u_int32_t sf_rx_control_frames; u_int32_t sf_rx_unsup_control_frames; u_int32_t sf_rx_giants; u_int32_t sf_rx_runts; u_int32_t sf_rx_jabbererrs; u_int32_t sf_rx_pkts_64; u_int32_t sf_rx_pkts_65_127; u_int32_t sf_rx_pkts_128_255; u_int32_t sf_rx_pkts_256_511; u_int32_t sf_rx_pkts_512_1023; u_int32_t sf_rx_pkts_1024_1518; u_int32_t sf_rx_frames_lost; u_int16_t sf_tx_underruns; u_int16_t sf_pad; }; /* * register space access macros */ #define CSR_WRITE_4(sc, reg, val) \ bus_space_write_4(sc->sf_btag, sc->sf_bhandle, reg, val) #define CSR_READ_4(sc, reg) \ bus_space_read_4(sc->sf_btag, sc->sf_bhandle, reg) #define CSR_READ_1(sc, reg) \ bus_space_read_1(sc->sf_btag, sc->sf_bhandle, reg) struct sf_type { u_int16_t sf_vid; u_int16_t sf_did; char *sf_name; }; #define SF_INC(x, y) (x) = (x + 1) % y #define ETHER_ALIGN 2 /* * Note: alignment is important here: each list must be aligned to * a 256-byte boundary. It turns out that each ring is some multiple * of 4K in length, so we can stack them all on top of each other * and just worry about aligning the whole mess. There's one transmit * buffer ring and two receive buffer rings: one RX ring is for small * packets and the other is for large packets. Each buffer ring also * has a companion completion queue. */ struct sf_list_data { struct sf_tx_bufdesc_type0 sf_tx_dlist[SF_TX_DLIST_CNT]; struct sf_tx_cmpdesc_type1 sf_tx_clist[SF_TX_CLIST_CNT]; struct sf_rx_bufdesc_type0 sf_rx_dlist_big[SF_RX_DLIST_CNT]; struct sf_rx_bufdesc_type0 sf_rx_dlist_small[SF_RX_DLIST_CNT]; struct sf_rx_cmpdesc_type3 sf_rx_clist[SF_RX_CLIST_CNT]; }; struct sf_softc { struct arpcom arpcom; /* interface info */ struct ifmedia ifmedia; /* media info */ bus_space_handle_t sf_bhandle; /* bus space handle */ bus_space_tag_t sf_btag; /* bus space tag */ - void *sf_intrhand; /* interrupt handler cookie */ - struct resource *sf_irq; /* irq resource descriptor */ - struct resource *sf_res; /* mem/ioport resource */ struct sf_type *sf_info; /* Starfire adapter info */ struct sf_type *sf_pinfo; /* phy info */ u_int8_t sf_unit; /* interface number */ u_int8_t sf_type; u_int8_t sf_phy_addr; /* PHY address */ u_int8_t sf_tx_pend; /* TX pending */ u_int8_t sf_want_auto; u_int8_t sf_autoneg; struct sf_list_data *sf_ldata; int sf_tx_cnt; struct callout_handle sf_stat_ch; }; #define SF_TIMEOUT 1000 #define SF_FLAG_FORCEDELAY 1 #define SF_FLAG_SCHEDDELAY 2 #define SF_FLAG_DELAYTIMEO 3 /* * Texas Instruments PHY identifiers */ #define TI_PHY_VENDORID 0x4000 #define TI_PHY_10BT 0x501F #define TI_PHY_100VGPMI 0x502F /* * These ID values are for the NS DP83840A 10/100 PHY */ #define NS_PHY_VENDORID 0x2000 #define NS_PHY_83840A 0x5C0F /* * Level 1 10/100 PHY */ #define LEVEL1_PHY_VENDORID 0x7810 #define LEVEL1_PHY_LXT970 0x000F /* * Intel 82555 10/100 PHY */ #define INTEL_PHY_VENDORID 0x0A28 #define INTEL_PHY_82555 0x015F /* * SEEQ 80220 10/100 PHY */ #define SEEQ_PHY_VENDORID 0x0016 #define SEEQ_PHY_80220 0xF83F #define PHY_UNKNOWN 6 #define SF_PHYADDR_MIN 0x00 #define SF_PHYADDR_MAX 0x1F #define PHY_BMCR 0x00 #define PHY_BMSR 0x01 #define PHY_VENID 0x02 #define PHY_DEVID 0x03 #define PHY_ANAR 0x04 #define PHY_LPAR 0x05 #define PHY_ANEXP 0x06 #define PHY_ANAR_NEXTPAGE 0x8000 #define PHY_ANAR_RSVD0 0x4000 #define PHY_ANAR_TLRFLT 0x2000 #define PHY_ANAR_RSVD1 0x1000 #define PHY_ANAR_RSVD2 0x0800 #define PHY_ANAR_RSVD3 0x0400 #define PHY_ANAR_100BT4 0x0200 #define PHY_ANAR_100BTXFULL 0x0100 #define PHY_ANAR_100BTXHALF 0x0080 #define PHY_ANAR_10BTFULL 0x0040 #define PHY_ANAR_10BTHALF 0x0020 #define PHY_ANAR_PROTO4 0x0010 #define PHY_ANAR_PROTO3 0x0008 #define PHY_ANAR_PROTO2 0x0004 #define PHY_ANAR_PROTO1 0x0002 #define PHY_ANAR_PROTO0 0x0001 /* * These are the register definitions for the PHY (physical layer * interface chip). */ /* * PHY BMCR Basic Mode Control Register */ #define PHY_BMCR_RESET 0x8000 #define PHY_BMCR_LOOPBK 0x4000 #define PHY_BMCR_SPEEDSEL 0x2000 #define PHY_BMCR_AUTONEGENBL 0x1000 #define PHY_BMCR_RSVD0 0x0800 /* write as zero */ #define PHY_BMCR_ISOLATE 0x0400 #define PHY_BMCR_AUTONEGRSTR 0x0200 #define PHY_BMCR_DUPLEX 0x0100 #define PHY_BMCR_COLLTEST 0x0080 #define PHY_BMCR_RSVD1 0x0040 /* write as zero, don't care */ #define PHY_BMCR_RSVD2 0x0020 /* write as zero, don't care */ #define PHY_BMCR_RSVD3 0x0010 /* write as zero, don't care */ #define PHY_BMCR_RSVD4 0x0008 /* write as zero, don't care */ #define PHY_BMCR_RSVD5 0x0004 /* write as zero, don't care */ #define PHY_BMCR_RSVD6 0x0002 /* write as zero, don't care */ #define PHY_BMCR_RSVD7 0x0001 /* write as zero, don't care */ /* * RESET: 1 == software reset, 0 == normal operation * Resets status and control registers to default values. * Relatches all hardware config values. * * LOOPBK: 1 == loopback operation enabled, 0 == normal operation * * SPEEDSEL: 1 == 100Mb/s, 0 == 10Mb/s * Link speed is selected byt his bit or if auto-negotiation if bit * 12 (AUTONEGENBL) is set (in which case the value of this register * is ignored). * * AUTONEGENBL: 1 == Autonegotiation enabled, 0 == Autonegotiation disabled * Bits 8 and 13 are ignored when autoneg is set, otherwise bits 8 and 13 * determine speed and mode. Should be cleared and then set if PHY configured * for no autoneg on startup. * * ISOLATE: 1 == isolate PHY from MII, 0 == normal operation * * AUTONEGRSTR: 1 == restart autonegotiation, 0 = normal operation * * DUPLEX: 1 == full duplex mode, 0 == half duplex mode * * COLLTEST: 1 == collision test enabled, 0 == normal operation */ /* * PHY, BMSR Basic Mode Status Register */ #define PHY_BMSR_100BT4 0x8000 #define PHY_BMSR_100BTXFULL 0x4000 #define PHY_BMSR_100BTXHALF 0x2000 #define PHY_BMSR_10BTFULL 0x1000 #define PHY_BMSR_10BTHALF 0x0800 #define PHY_BMSR_RSVD1 0x0400 /* write as zero, don't care */ #define PHY_BMSR_RSVD2 0x0200 /* write as zero, don't care */ #define PHY_BMSR_RSVD3 0x0100 /* write as zero, don't care */ #define PHY_BMSR_RSVD4 0x0080 /* write as zero, don't care */ #define PHY_BMSR_MFPRESUP 0x0040 #define PHY_BMSR_AUTONEGCOMP 0x0020 #define PHY_BMSR_REMFAULT 0x0010 #define PHY_BMSR_CANAUTONEG 0x0008 #define PHY_BMSR_LINKSTAT 0x0004 #define PHY_BMSR_JABBER 0x0002 #define PHY_BMSR_EXTENDED 0x0001 #ifdef __alpha__ #undef vtophys -#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) +#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \ + + 1*1024*1024*1024) #endif Index: stable/3/sys/pci/if_sk.c =================================================================== --- stable/3/sys/pci/if_sk.c (revision 49544) +++ stable/3/sys/pci/if_sk.c (revision 49545) @@ -1,1974 +1,1919 @@ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_sk.c,v 1.51 1999/07/14 21:48:19 wpaul Exp $ + * $Id: if_sk.c,v 1.52 1999/07/25 05:00:53 wpaul Exp $ */ /* * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports * the SK-984x series adapters, both single port and dual port. * References: * The XaQti XMAC II datasheet, http://www.xaqti.com * The SysKonnect GEnesis manual, http://www.syskonnect.com * * Written by Bill Paul * Department of Electrical Engineering * Columbia University, New York City */ /* * The SysKonnect gigabit ethernet adapters consist of two main * components: the SysKonnect GEnesis controller chip and the XaQti Corp. * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC * components and a PHY while the GEnesis controller provides a PCI * interface with DMA support. Each card may have between 512K and * 2MB of SRAM on board depending on the configuration. * * The SysKonnect GEnesis controller can have either one or two XMAC * chips connected to it, allowing single or dual port NIC configurations. * SysKonnect has the distinction of being the only vendor on the market * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs, * dual DMA queues, packet/MAC/transmit arbiters and direct access to the * XMAC registers. This driver takes advantage of these features to allow * both XMACs to operate as independent interfaces. */ -#include "bpf.h" +#include "bpfilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include -#if NBPF > 0 +#if NBPFILTER > 0 #include #endif #include /* for vtophys */ #include /* for vtophys */ #include /* for DELAY */ #include #include #include -#include -#include -#include #include #include #define SK_USEIOSPACE #include #include #ifndef lint static const char rcsid[] = - "$Id: if_sk.c,v 1.51 1999/07/14 21:48:19 wpaul Exp $"; + "$Id: if_sk.c,v 1.52 1999/07/25 05:00:53 wpaul Exp $"; #endif static struct sk_type sk_devs[] = { { SK_VENDORID, SK_DEVICEID_GE, "SysKonnect Gigabit Ethernet" }, { 0, 0, NULL } }; static unsigned long sk_count = 0; -static int sk_probe __P((device_t)); -static int sk_attach __P((device_t)); -static int sk_detach __P((device_t)); +static unsigned long skc_count = 0; +static const char *sk_probe __P((pcici_t, pcidi_t)); +static void sk_attach __P((pcici_t, int)); static int sk_attach_xmac __P((struct sk_softc *, int)); static void sk_intr __P((void *)); static void sk_intr_xmac __P((struct sk_if_softc *)); static void sk_rxeof __P((struct sk_if_softc *)); static void sk_txeof __P((struct sk_if_softc *)); static int sk_encap __P((struct sk_if_softc *, struct mbuf *, u_int32_t *)); static void sk_start __P((struct ifnet *)); static int sk_ioctl __P((struct ifnet *, u_long, caddr_t)); static void sk_init __P((void *)); static void sk_init_xmac __P((struct sk_if_softc *)); static void sk_stop __P((struct sk_if_softc *)); static void sk_watchdog __P((struct ifnet *)); -static void sk_shutdown __P((device_t)); +static void sk_shutdown __P((int, void *)); static int sk_ifmedia_upd __P((struct ifnet *)); static void sk_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); static void sk_reset __P((struct sk_softc *)); static int sk_newbuf __P((struct sk_if_softc *, struct sk_chain *, struct mbuf *)); static int sk_alloc_jumbo_mem __P((struct sk_if_softc *)); static void *sk_jalloc __P((struct sk_if_softc *)); static void sk_jfree __P((caddr_t, u_int)); static void sk_jref __P((caddr_t, u_int)); static int sk_init_rx_ring __P((struct sk_if_softc *)); static void sk_init_tx_ring __P((struct sk_if_softc *)); #ifdef notdef static u_int32_t sk_win_read_4 __P((struct sk_softc *, int)); #endif static u_int16_t sk_win_read_2 __P((struct sk_softc *, int)); static u_int8_t sk_win_read_1 __P((struct sk_softc *, int)); static void sk_win_write_4 __P((struct sk_softc *, int, u_int32_t)); static void sk_win_write_2 __P((struct sk_softc *, int, u_int32_t)); static void sk_win_write_1 __P((struct sk_softc *, int, u_int32_t)); static u_int8_t sk_vpd_readbyte __P((struct sk_softc *, int)); static void sk_vpd_read_res __P((struct sk_softc *, struct vpd_res *, int)); static void sk_vpd_read __P((struct sk_softc *)); static u_int16_t sk_phy_readreg __P((struct sk_if_softc *, int)); static void sk_phy_writereg __P((struct sk_if_softc *, int, u_int32_t)); static u_int32_t sk_calchash __P((caddr_t)); static void sk_setfilt __P((struct sk_if_softc *, caddr_t, int)); static void sk_setmulti __P((struct sk_if_softc *)); -#ifdef SK_USEIOSPACE -#define SK_RES SYS_RES_IOPORT -#define SK_RID SK_PCI_LOIO -#else -#define SK_RES SYS_RES_MEMORY -#define SK_RID SK_PCI_LOMEM +#ifdef __i386__ +#define SK_BUS_SPACE_MEM I386_BUS_SPACE_MEM +#define SK_BUS_SPACE_IO I386_BUS_SPACE_IO #endif -static device_method_t sk_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sk_probe), - DEVMETHOD(device_attach, sk_attach), - DEVMETHOD(device_detach, sk_detach), - DEVMETHOD(device_shutdown, sk_shutdown), - { 0, 0 } -}; +#ifdef __alpha__ +#define SK_BUS_SPACE_MEM ALPHA_BUS_SPACE_MEM +#define SK_BUS_SPACE_IO ALPHA_BUS_SPACE_IO +#endif -static driver_t sk_driver = { - "skc", - sk_methods, - sizeof(struct sk_softc) -}; - -static devclass_t sk_devclass; - -DRIVER_MODULE(sk, pci, sk_driver, sk_devclass, 0, 0); - #define SK_SETBIT(sc, reg, x) \ CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | x) #define SK_CLRBIT(sc, reg, x) \ CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~x) #define SK_WIN_SETBIT_4(sc, reg, x) \ sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) | x) #define SK_WIN_CLRBIT_4(sc, reg, x) \ sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) & ~x) #define SK_WIN_SETBIT_2(sc, reg, x) \ sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) | x) #define SK_WIN_CLRBIT_2(sc, reg, x) \ sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) & ~x) #ifdef notdef static u_int32_t sk_win_read_4(sc, reg) struct sk_softc *sc; int reg; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_4(sc, SK_WIN_BASE + SK_REG(reg))); } #endif static u_int16_t sk_win_read_2(sc, reg) struct sk_softc *sc; int reg; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_2(sc, SK_WIN_BASE + SK_REG(reg))); } static u_int8_t sk_win_read_1(sc, reg) struct sk_softc *sc; int reg; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_1(sc, SK_WIN_BASE + SK_REG(reg))); } static void sk_win_write_4(sc, reg, val) struct sk_softc *sc; int reg; u_int32_t val; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); CSR_WRITE_4(sc, SK_WIN_BASE + SK_REG(reg), val); return; } static void sk_win_write_2(sc, reg, val) struct sk_softc *sc; int reg; u_int32_t val; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); CSR_WRITE_2(sc, SK_WIN_BASE + SK_REG(reg), (u_int32_t)val); return; } static void sk_win_write_1(sc, reg, val) struct sk_softc *sc; int reg; u_int32_t val; { CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); CSR_WRITE_1(sc, SK_WIN_BASE + SK_REG(reg), val); return; } /* * The VPD EEPROM contains Vital Product Data, as suggested in * the PCI 2.1 specification. The VPD data is separared into areas * denoted by resource IDs. The SysKonnect VPD contains an ID string * resource (the name of the adapter), a read-only area resource * containing various key/data fields and a read/write area which * can be used to store asset management information or log messages. * We read the ID string and read-only into buffers attached to * the controller softc structure for later use. At the moment, * we only use the ID string during sk_attach(). */ static u_int8_t sk_vpd_readbyte(sc, addr) struct sk_softc *sc; int addr; { int i; sk_win_write_2(sc, SK_PCI_REG(SK_PCI_VPD_ADDR), addr); for (i = 0; i < SK_TIMEOUT; i++) { DELAY(1); if (sk_win_read_2(sc, SK_PCI_REG(SK_PCI_VPD_ADDR)) & SK_VPD_FLAG) break; } if (i == SK_TIMEOUT) return(0); return(sk_win_read_1(sc, SK_PCI_REG(SK_PCI_VPD_DATA))); } static void sk_vpd_read_res(sc, res, addr) struct sk_softc *sc; struct vpd_res *res; int addr; { int i; u_int8_t *ptr; ptr = (u_int8_t *)res; for (i = 0; i < sizeof(struct vpd_res); i++) ptr[i] = sk_vpd_readbyte(sc, i + addr); return; } static void sk_vpd_read(sc) struct sk_softc *sc; { int pos = 0, i; struct vpd_res res; if (sc->sk_vpd_prodname != NULL) free(sc->sk_vpd_prodname, M_DEVBUF); if (sc->sk_vpd_readonly != NULL) free(sc->sk_vpd_readonly, M_DEVBUF); sc->sk_vpd_prodname = NULL; sc->sk_vpd_readonly = NULL; sk_vpd_read_res(sc, &res, pos); if (res.vr_id != VPD_RES_ID) { printf("skc%d: bad VPD resource id: expected %x got %x\n", sc->sk_unit, VPD_RES_ID, res.vr_id); return; } pos += sizeof(res); sc->sk_vpd_prodname = malloc(res.vr_len + 1, M_DEVBUF, M_NOWAIT); for (i = 0; i < res.vr_len; i++) sc->sk_vpd_prodname[i] = sk_vpd_readbyte(sc, i + pos); sc->sk_vpd_prodname[i] = '\0'; pos += i; sk_vpd_read_res(sc, &res, pos); if (res.vr_id != VPD_RES_READ) { printf("skc%d: bad VPD resource id: expected %x got %x\n", sc->sk_unit, VPD_RES_READ, res.vr_id); return; } pos += sizeof(res); sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT); for (i = 0; i < res.vr_len + 1; i++) sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos); return; } static u_int16_t sk_phy_readreg(sc_if, reg) struct sk_if_softc *sc_if; int reg; { int i; SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg); for (i = 0; i < SK_TIMEOUT; i++) { if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) break; } if (i == SK_TIMEOUT) { printf("sk%d: phy failed to come ready\n", sc_if->sk_unit); return(0); } return(SK_XM_READ_2(sc_if, XM_PHY_DATA)); } static void sk_phy_writereg(sc_if, reg, val) struct sk_if_softc *sc_if; int reg; u_int32_t val; { int i; SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg); for (i = 0; i < SK_TIMEOUT; i++) { if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) break; } if (i == SK_TIMEOUT) { printf("sk%d: phy failed to come ready\n", sc_if->sk_unit); return; } SK_XM_WRITE_2(sc_if, XM_PHY_DATA, val); for (i = 0; i < SK_TIMEOUT; i++) { if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) break; } if (i == SK_TIMEOUT) printf("sk%d: phy write timed out\n", sc_if->sk_unit); return; } #define SK_POLY 0xEDB88320 #define SK_BITS 6 static u_int32_t sk_calchash(addr) caddr_t addr; { u_int32_t idx, bit, data, crc; /* Compute CRC for the address value. */ crc = 0xFFFFFFFF; /* initial value */ for (idx = 0; idx < 6; idx++) { for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) crc = (crc >> 1) ^ (((crc ^ data) & 1) ? SK_POLY : 0); } return (~crc & ((1 << SK_BITS) - 1)); } static void sk_setfilt(sc_if, addr, slot) struct sk_if_softc *sc_if; caddr_t addr; int slot; { int base; base = XM_RXFILT_ENTRY(slot); SK_XM_WRITE_2(sc_if, base, *(u_int16_t *)(&addr[0])); SK_XM_WRITE_2(sc_if, base + 2, *(u_int16_t *)(&addr[2])); SK_XM_WRITE_2(sc_if, base + 4, *(u_int16_t *)(&addr[4])); return; } static void sk_setmulti(sc_if) struct sk_if_softc *sc_if; { struct ifnet *ifp; u_int32_t hashes[2] = { 0, 0 }; int h, i; struct ifmultiaddr *ifma; u_int8_t dummy[] = { 0, 0, 0, 0, 0 ,0 }; ifp = &sc_if->arpcom.ac_if; /* First, zot all the existing filters. */ for (i = 1; i < XM_RXFILT_MAX; i++) sk_setfilt(sc_if, (caddr_t)&dummy, i); SK_XM_WRITE_4(sc_if, XM_MAR0, 0); SK_XM_WRITE_4(sc_if, XM_MAR2, 0); /* Now program new ones. */ if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { hashes[0] = 0xFFFFFFFF; hashes[1] = 0xFFFFFFFF; } else { i = 1; /* First find the tail of the list. */ for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; ifma = ifma->ifma_link.le_next) { if (ifma->ifma_link.le_next == NULL) break; } /* Now traverse the list backwards. */ for (; ifma != NULL && ifma != (void *)&ifp->if_multiaddrs; ifma = (struct ifmultiaddr *)ifma->ifma_link.le_prev) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; /* * Program the first XM_RXFILT_MAX multicast groups * into the perfect filter. For all others, * use the hash table. */ if (i < XM_RXFILT_MAX) { sk_setfilt(sc_if, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), i); i++; continue; } h = sk_calchash( LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); if (h < 32) hashes[0] |= (1 << h); else hashes[1] |= (1 << (h - 32)); } } SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH| XM_MODE_RX_USE_PERFECT); SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]); SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]); return; } static int sk_init_rx_ring(sc_if) struct sk_if_softc *sc_if; { struct sk_chain_data *cd; struct sk_ring_data *rd; int i; cd = &sc_if->sk_cdata; rd = sc_if->sk_rdata; bzero((char *)rd->sk_rx_ring, sizeof(struct sk_rx_desc) * SK_RX_RING_CNT); for (i = 0; i < SK_RX_RING_CNT; i++) { cd->sk_rx_chain[i].sk_desc = &rd->sk_rx_ring[i]; if (sk_newbuf(sc_if, &cd->sk_rx_chain[i], NULL) == ENOBUFS) return(ENOBUFS); if (i == (SK_RX_RING_CNT - 1)) { cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[0]; rd->sk_rx_ring[i].sk_next = vtophys(&rd->sk_rx_ring[0]); } else { cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[i + 1]; rd->sk_rx_ring[i].sk_next = vtophys(&rd->sk_rx_ring[i + 1]); } } sc_if->sk_cdata.sk_rx_prod = 0; sc_if->sk_cdata.sk_rx_cons = 0; return(0); } static void sk_init_tx_ring(sc_if) struct sk_if_softc *sc_if; { struct sk_chain_data *cd; struct sk_ring_data *rd; int i; cd = &sc_if->sk_cdata; rd = sc_if->sk_rdata; bzero((char *)sc_if->sk_rdata->sk_tx_ring, sizeof(struct sk_tx_desc) * SK_TX_RING_CNT); for (i = 0; i < SK_TX_RING_CNT; i++) { cd->sk_tx_chain[i].sk_desc = &rd->sk_tx_ring[i]; if (i == (SK_TX_RING_CNT - 1)) { cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[0]; rd->sk_tx_ring[i].sk_next = vtophys(&rd->sk_tx_ring[0]); } else { cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[i + 1]; rd->sk_tx_ring[i].sk_next = vtophys(&rd->sk_tx_ring[i + 1]); } } sc_if->sk_cdata.sk_tx_prod = 0; sc_if->sk_cdata.sk_tx_cons = 0; sc_if->sk_cdata.sk_tx_cnt = 0; return; } static int sk_newbuf(sc_if, c, m) struct sk_if_softc *sc_if; struct sk_chain *c; struct mbuf *m; { struct mbuf *m_new = NULL; struct sk_rx_desc *r; if (m == NULL) { caddr_t *buf = NULL; MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { printf("sk%d: no memory for rx list -- " "packet dropped!\n", sc_if->sk_unit); return(ENOBUFS); } /* Allocate the jumbo buffer */ buf = sk_jalloc(sc_if); if (buf == NULL) { m_freem(m_new); #ifdef SK_VERBOSE printf("sk%d: jumbo allocation failed " "-- packet dropped!\n", sc_if->sk_unit); #endif return(ENOBUFS); } /* Attach the buffer to the mbuf */ m_new->m_data = m_new->m_ext.ext_buf = (void *)buf; m_new->m_flags |= M_EXT; m_new->m_ext.ext_size = m_new->m_pkthdr.len = m_new->m_len = SK_MCLBYTES; m_new->m_ext.ext_free = sk_jfree; m_new->m_ext.ext_ref = sk_jref; } else { /* * We're re-using a previously allocated mbuf; * be sure to re-init pointers and lengths to * default values. */ m_new = m; m_new->m_len = m_new->m_pkthdr.len = SK_MCLBYTES; m_new->m_data = m_new->m_ext.ext_buf; } /* * Adjust alignment so packet payload begins on a * longword boundary. Mandatory for Alpha, useful on * x86 too. */ m_adj(m_new, ETHER_ALIGN); r = c->sk_desc; c->sk_mbuf = m_new; r->sk_data_lo = vtophys(mtod(m_new, caddr_t)); r->sk_ctl = m_new->m_len | SK_RXSTAT; return(0); } /* * Allocate jumbo buffer storage. The SysKonnect adapters support * "jumbograms" (9K frames), although SysKonnect doesn't currently * use them in their drivers. In order for us to use them, we need * large 9K receive buffers, however standard mbuf clusters are only * 2048 bytes in size. Consequently, we need to allocate and manage * our own jumbo buffer pool. Fortunately, this does not require an * excessive amount of additional code. */ static int sk_alloc_jumbo_mem(sc_if) struct sk_if_softc *sc_if; { caddr_t ptr; register int i; struct sk_jpool_entry *entry; /* Grab a big chunk o' storage. */ sc_if->sk_cdata.sk_jumbo_buf = contigmalloc(SK_JMEM, M_DEVBUF, M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0); if (sc_if->sk_cdata.sk_jumbo_buf == NULL) { printf("sk%d: no memory for jumbo buffers!\n", sc_if->sk_unit); return(ENOBUFS); } SLIST_INIT(&sc_if->sk_jfree_listhead); SLIST_INIT(&sc_if->sk_jinuse_listhead); /* * Now divide it up into 9K pieces and save the addresses * in an array. Note that we play an evil trick here by using * the first few bytes in the buffer to hold the the address * of the softc structure for this interface. This is because * sk_jfree() needs it, but it is called by the mbuf management * code which will not pass it to us explicitly. */ ptr = sc_if->sk_cdata.sk_jumbo_buf; for (i = 0; i < SK_JSLOTS; i++) { u_int64_t **aptr; aptr = (u_int64_t **)ptr; aptr[0] = (u_int64_t *)sc_if; ptr += sizeof(u_int64_t); sc_if->sk_cdata.sk_jslots[i].sk_buf = ptr; sc_if->sk_cdata.sk_jslots[i].sk_inuse = 0; ptr += SK_MCLBYTES; entry = malloc(sizeof(struct sk_jpool_entry), M_DEVBUF, M_NOWAIT); if (entry == NULL) { free(sc_if->sk_cdata.sk_jumbo_buf, M_DEVBUF); sc_if->sk_cdata.sk_jumbo_buf = NULL; printf("sk%d: no memory for jumbo " "buffer queue!\n", sc_if->sk_unit); return(ENOBUFS); } entry->slot = i; SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries); } return(0); } /* * Allocate a jumbo buffer. */ static void *sk_jalloc(sc_if) struct sk_if_softc *sc_if; { struct sk_jpool_entry *entry; entry = SLIST_FIRST(&sc_if->sk_jfree_listhead); if (entry == NULL) { #ifdef SK_VERBOSE printf("sk%d: no free jumbo buffers\n", sc_if->sk_unit); #endif return(NULL); } SLIST_REMOVE_HEAD(&sc_if->sk_jfree_listhead, jpool_entries); SLIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries); sc_if->sk_cdata.sk_jslots[entry->slot].sk_inuse = 1; return(sc_if->sk_cdata.sk_jslots[entry->slot].sk_buf); } /* * Adjust usage count on a jumbo buffer. In general this doesn't * get used much because our jumbo buffers don't get passed around * a lot, but it's implemented for correctness. */ static void sk_jref(buf, size) caddr_t buf; u_int size; { struct sk_if_softc *sc_if; u_int64_t **aptr; register int i; /* Extract the softc struct pointer. */ aptr = (u_int64_t **)(buf - sizeof(u_int64_t)); sc_if = (struct sk_if_softc *)(aptr[0]); if (sc_if == NULL) panic("sk_jref: can't find softc pointer!"); if (size != SK_MCLBYTES) panic("sk_jref: adjusting refcount of buf of wrong size!"); /* calculate the slot this buffer belongs to */ i = ((vm_offset_t)aptr - (vm_offset_t)sc_if->sk_cdata.sk_jumbo_buf) / SK_JLEN; if ((i < 0) || (i >= SK_JSLOTS)) panic("sk_jref: asked to reference buffer " "that we don't manage!"); else if (sc_if->sk_cdata.sk_jslots[i].sk_inuse == 0) panic("sk_jref: buffer already free!"); else sc_if->sk_cdata.sk_jslots[i].sk_inuse++; return; } /* * Release a jumbo buffer. */ static void sk_jfree(buf, size) caddr_t buf; u_int size; { struct sk_if_softc *sc_if; u_int64_t **aptr; int i; struct sk_jpool_entry *entry; /* Extract the softc struct pointer. */ aptr = (u_int64_t **)(buf - sizeof(u_int64_t)); sc_if = (struct sk_if_softc *)(aptr[0]); if (sc_if == NULL) panic("sk_jfree: can't find softc pointer!"); if (size != SK_MCLBYTES) panic("sk_jfree: freeing buffer of wrong size!"); /* calculate the slot this buffer belongs to */ i = ((vm_offset_t)aptr - (vm_offset_t)sc_if->sk_cdata.sk_jumbo_buf) / SK_JLEN; if ((i < 0) || (i >= SK_JSLOTS)) panic("sk_jfree: asked to free buffer that we don't manage!"); else if (sc_if->sk_cdata.sk_jslots[i].sk_inuse == 0) panic("sk_jfree: buffer already free!"); else { sc_if->sk_cdata.sk_jslots[i].sk_inuse--; if(sc_if->sk_cdata.sk_jslots[i].sk_inuse == 0) { entry = SLIST_FIRST(&sc_if->sk_jinuse_listhead); if (entry == NULL) panic("sk_jfree: buffer not in use!"); entry->slot = i; SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries); SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries); } } return; } /* * Set media options. */ static int sk_ifmedia_upd(ifp) struct ifnet *ifp; { struct sk_if_softc *sc_if; struct ifmedia *ifm; sc_if = ifp->if_softc; ifm = &sc_if->ifmedia; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return(EINVAL); switch(IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: sk_phy_writereg(sc_if, XM_PHY_BMCR, XM_BMCR_RENEGOTIATE|XM_BMCR_AUTONEGENBL); break; case IFM_1000_LX: case IFM_1000_SX: case IFM_1000_CX: case IFM_1000_TX: if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) sk_phy_writereg(sc_if, XM_PHY_BMCR, XM_BMCR_DUPLEX); else sk_phy_writereg(sc_if, XM_PHY_BMCR, 0); break; default: printf("sk%d: invalid media selected\n", sc_if->sk_unit); return(EINVAL); break; } return(0); } /* * Report current media status. */ static void sk_ifmedia_sts(ifp, ifmr) struct ifnet *ifp; struct ifmediareq *ifmr; { struct sk_softc *sc; struct sk_if_softc *sc_if; u_int16_t bmsr, extsts; sc_if = ifp->if_softc; sc = sc_if->sk_softc; ifmr->ifm_status = IFM_AVALID; ifmr->ifm_active = IFM_ETHER; bmsr = sk_phy_readreg(sc_if, XM_PHY_BMSR); extsts = sk_phy_readreg(sc_if, XM_PHY_EXTSTS); if (!(bmsr & XM_BMSR_LINKSTAT)) return; ifmr->ifm_status |= IFM_ACTIVE; ifmr->ifm_active |= sc->sk_pmd;; if (extsts & XM_EXTSTS_FULLDUPLEX) ifmr->ifm_active |= IFM_FDX; else ifmr->ifm_active |= IFM_HDX; return; } static int sk_ioctl(ifp, command, data) struct ifnet *ifp; u_long command; caddr_t data; { struct sk_if_softc *sc_if = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; int s, error = 0; s = splimp(); switch(command) { case SIOCSIFADDR: case SIOCGIFADDR: error = ether_ioctl(ifp, command, data); break; case SIOCSIFMTU: if (ifr->ifr_mtu > SK_JUMBO_MTU) error = EINVAL; else { ifp->if_mtu = ifr->ifr_mtu; sk_init(sc_if); } break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING && ifp->if_flags & IFF_PROMISC && !(sc_if->sk_if_flags & IFF_PROMISC)) { SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); sk_setmulti(sc_if); } else if (ifp->if_flags & IFF_RUNNING && !(ifp->if_flags & IFF_PROMISC) && sc_if->sk_if_flags & IFF_PROMISC) { SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); sk_setmulti(sc_if); } else sk_init(sc_if); } else { if (ifp->if_flags & IFF_RUNNING) sk_stop(sc_if); } sc_if->sk_if_flags = ifp->if_flags; error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: sk_setmulti(sc_if); error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc_if->ifmedia, command); break; default: error = EINVAL; break; } (void)splx(s); return(error); } /* * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device * IDs against our list and return a device name if we find a match. */ -static int sk_probe(dev) - device_t dev; +static const char *sk_probe(config_id, device_id) + pcici_t config_id; + pcidi_t device_id; { struct sk_type *t; t = sk_devs; while(t->sk_name != NULL) { - if ((pci_get_vendor(dev) == t->sk_vid) && - (pci_get_device(dev) == t->sk_did)) { - device_set_desc(dev, t->sk_name); - return(0); + if ((device_id & 0xFFFF) == t->sk_vid && + ((device_id >> 16) & 0xFFFF) == t->sk_did) { + return(t->sk_name); } t++; } - return(ENXIO); + return(NULL); } /* * Force the GEnesis into reset, then bring it out of reset. */ static void sk_reset(sc) struct sk_softc *sc; { CSR_WRITE_4(sc, SK_CSR, SK_CSR_SW_RESET); CSR_WRITE_4(sc, SK_CSR, SK_CSR_MASTER_RESET); DELAY(1000); CSR_WRITE_4(sc, SK_CSR, SK_CSR_SW_UNRESET); CSR_WRITE_4(sc, SK_CSR, SK_CSR_MASTER_UNRESET); /* Configure packet arbiter */ sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET); sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT); sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT); sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT); sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT); /* Enable RAM interface */ sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET); /* * Configure interrupt moderation. The moderation timer * defers interrupts specified in the interrupt moderation * timer mask based on the timeout specified in the interrupt * moderation timer init register. Each bit in the timer * register represents 18.825ns, so to specify a timeout in * microseconds, we have to multiply by 54. */ sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(200)); sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF| SK_ISR_RX1_EOF|SK_ISR_RX2_EOF); sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START); return; } /* * Each XMAC chip is attached as a separate logical IP interface. * Single port cards will have only one logical interface of course. */ static int sk_attach_xmac(sc, port) struct sk_softc *sc; int port; { struct sk_if_softc *sc_if; struct ifnet *ifp; int i; if (sc == NULL) return(EINVAL); if (port != SK_PORT_A && port != SK_PORT_B) return(EINVAL); sc_if = malloc(sizeof(struct sk_if_softc), M_DEVBUF, M_NOWAIT); if (sc_if == NULL) { printf("sk%d: no memory for interface softc!\n", sc->sk_unit); return(ENOMEM); } bzero((char *)sc_if, sizeof(struct sk_if_softc)); sc_if->sk_unit = sk_count; sc_if->sk_port = port; sk_count++; sc_if->sk_softc = sc; sc->sk_if[port] = sc_if; if (port == SK_PORT_A) sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0; if (port == SK_PORT_B) sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1; /* * Get station address for this interface. Note that * dual port cards actually come with three station * addresses: one for each port, plus an extra. The * extra one is used by the SysKonnect driver software * as a 'virtual' station address for when both ports * are operating in failover mode. Currently we don't * use this extra address. */ for (i = 0; i < ETHER_ADDR_LEN; i++) sc_if->arpcom.ac_enaddr[i] = sk_win_read_1(sc, SK_MAC0_0 + (port * 8) + i); printf("sk%d: at skc%d port %d\n", sc_if->sk_unit, sc->sk_unit, port); printf("sk%d: Ethernet address: %6D\n", sc_if->sk_unit, sc_if->arpcom.ac_enaddr, ":"); /* * Set up RAM buffer addresses. The NIC will have a certain * amount of SRAM on it, somewhere between 512K and 2MB. We * need to divide this up a) between the transmitter and * receiver and b) between the two XMACs, if this is a * dual port NIC. Our algotithm is to divide up the memory * evenly so that everyone gets a fair share. */ if (sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC) { u_int32_t chunk, val; chunk = sc->sk_ramsize / 2; val = sc->sk_rboff / sizeof(u_int64_t); sc_if->sk_rx_ramstart = val; val += (chunk / sizeof(u_int64_t)); sc_if->sk_rx_ramend = val - 1; sc_if->sk_tx_ramstart = val; val += (chunk / sizeof(u_int64_t)); sc_if->sk_tx_ramend = val - 1; } else { u_int32_t chunk, val; chunk = sc->sk_ramsize / 4; val = (sc->sk_rboff + (chunk * 2 * sc_if->sk_port)) / sizeof(u_int64_t); sc_if->sk_rx_ramstart = val; val += (chunk / sizeof(u_int64_t)); sc_if->sk_rx_ramend = val - 1; sc_if->sk_tx_ramstart = val; val += (chunk / sizeof(u_int64_t)); sc_if->sk_tx_ramend = val - 1; } /* Allocate the descriptor queues. */ sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF, M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0); if (sc_if->sk_rdata == NULL) { printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit); free(sc_if, M_DEVBUF); sc->sk_if[port] = NULL; return(ENOMEM); } bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data)); /* Try to allocate memory for jumbo buffers. */ if (sk_alloc_jumbo_mem(sc_if)) { printf("sk%d: jumbo buffer allocation failed\n", sc_if->sk_unit); free(sc_if->sk_rdata, M_DEVBUF); free(sc_if, M_DEVBUF); sc->sk_if[port] = NULL; return(ENOMEM); } ifp = &sc_if->arpcom.ac_if; ifp->if_softc = sc_if; ifp->if_unit = sc_if->sk_unit; ifp->if_name = "sk"; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = sk_ioctl; ifp->if_output = ether_output; ifp->if_start = sk_start; ifp->if_watchdog = sk_watchdog; ifp->if_init = sk_init; ifp->if_baudrate = 1000000000; ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1; /* * Do ifmedia setup. */ ifmedia_init(&sc_if->ifmedia, 0, sk_ifmedia_upd, sk_ifmedia_sts); ifmedia_add(&sc_if->ifmedia, IFM_ETHER|sc->sk_pmd, 0, NULL); ifmedia_add(&sc_if->ifmedia, IFM_ETHER|sc->sk_pmd|IFM_FDX, 0, NULL); ifmedia_add(&sc_if->ifmedia, IFM_ETHER|sc->sk_pmd|IFM_HDX, 0, NULL); ifmedia_add(&sc_if->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); ifmedia_set(&sc_if->ifmedia, IFM_ETHER|IFM_AUTO); /* * Call MI attach routines. */ if_attach(ifp); ether_ifattach(ifp); -#if NBPF > 0 +#if NBPFILTER > 0 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif return(0); } /* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ -static int sk_attach(dev) - device_t dev; +static void +sk_attach(config_id, unit) + pcici_t config_id; + int unit; { int s; +#ifndef SK_USEIOSPACE + vm_offset_t pbase, vbase; +#endif u_int32_t command; struct sk_softc *sc; - int unit, error = 0, rid; s = splimp(); - sc = device_get_softc(dev); - unit = device_get_unit(dev); + sc = malloc(sizeof(struct sk_softc), M_DEVBUF, M_NOWAIT); + if (sc == NULL) { + printf("skc%d: no memory for softc struct!\n", unit); + goto fail; + } bzero(sc, sizeof(struct sk_softc)); /* * Handle power management nonsense. */ - command = pci_read_config(dev, SK_PCI_CAPID, 4) & 0x000000FF; + command = pci_conf_read(config_id, SK_PCI_CAPID) & 0x000000FF; if (command == 0x01) { - command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4); + command = pci_conf_read(config_id, SK_PCI_PWRMGMTCTRL); if (command & SK_PSTATE_MASK) { u_int32_t iobase, membase, irq; /* Save important PCI config data. */ - iobase = pci_read_config(dev, SK_PCI_LOIO, 4); - membase = pci_read_config(dev, SK_PCI_LOMEM, 4); - irq = pci_read_config(dev, SK_PCI_INTLINE, 4); + iobase = pci_conf_read(config_id, SK_PCI_LOIO); + membase = pci_conf_read(config_id, SK_PCI_LOMEM); + irq = pci_conf_read(config_id, SK_PCI_INTLINE); /* Reset the power state. */ printf("skc%d: chip is in D%d power mode " "-- setting to D0\n", unit, command & SK_PSTATE_MASK); command &= 0xFFFFFFFC; - pci_write_config(dev, SK_PCI_PWRMGMTCTRL, command, 4); + pci_conf_write(config_id, SK_PCI_PWRMGMTCTRL, command); /* Restore PCI config data. */ - pci_write_config(dev, SK_PCI_LOIO, iobase, 4); - pci_write_config(dev, SK_PCI_LOMEM, membase, 4); - pci_write_config(dev, SK_PCI_INTLINE, irq, 4); + pci_conf_write(config_id, SK_PCI_LOIO, iobase); + pci_conf_write(config_id, SK_PCI_LOMEM, membase); + pci_conf_write(config_id, SK_PCI_INTLINE, irq); } } /* * Map control/status registers. */ - command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); + command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); - pci_write_config(dev, PCI_COMMAND_STATUS_REG, command, 4); - command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); + pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command); + command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); #ifdef SK_USEIOSPACE if (!(command & PCIM_CMD_PORTEN)) { printf("skc%d: failed to enable I/O ports!\n", unit); - error = ENXIO; + free(sc, M_DEVBUF); goto fail; } + + if (!pci_map_port(config_id, SK_PCI_LOIO, + (u_short *)&(sc->sk_bhandle))) { + printf ("skc%d: couldn't map ports\n", unit); + goto fail; + } + + sc->sk_btag = SK_BUS_SPACE_IO; #else if (!(command & PCIM_CMD_MEMEN)) { printf("skc%d: failed to enable memory mapping!\n", unit); - error = ENXIO; goto fail; } -#endif - rid = SK_RID; - sc->sk_res = bus_alloc_resource(dev, SK_RES, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (sc->sk_res == NULL) { - printf("sk%d: couldn't map ports/memory\n", unit); - error = ENXIO; + if (!pci_map_mem(config_id, SK_PCI_LOMEM, &vbase, &pbase)) { + printf ("skc%d: couldn't map memory\n", unit); goto fail; } + sc->sk_btag = SK_BUS_SPACE_MEM; + sc->sk_bhandle = vbase; +#endif - sc->sk_btag = rman_get_bustag(sc->sk_res); - sc->sk_bhandle = rman_get_bushandle(sc->sk_res); - /* Allocate interrupt */ - rid = 0; - sc->sk_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); - - if (sc->sk_irq == NULL) { + if (!pci_map_int(config_id, sk_intr, sc, &net_imask)) { printf("skc%d: couldn't map interrupt\n", unit); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - error = ENXIO; goto fail; } - error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET, - sk_intr, sc, &sc->sk_intrhand); - - if (error) { - printf("skc%d: couldn't set up irq\n", unit); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_res); - goto fail; - } - /* Reset the adapter. */ sk_reset(sc); sc->sk_unit = unit; /* Read and save vital product data from EEPROM. */ sk_vpd_read(sc); /* Read and save RAM size and RAMbuffer offset */ switch(sk_win_read_1(sc, SK_EPROM0)) { case SK_RAMSIZE_512K_64: sc->sk_ramsize = 0x80000; sc->sk_rboff = SK_RBOFF_0; break; case SK_RAMSIZE_1024K_64: sc->sk_ramsize = 0x100000; sc->sk_rboff = SK_RBOFF_80000; break; case SK_RAMSIZE_1024K_128: sc->sk_ramsize = 0x100000; sc->sk_rboff = SK_RBOFF_0; break; case SK_RAMSIZE_2048K_128: sc->sk_ramsize = 0x200000; sc->sk_rboff = SK_RBOFF_0; break; default: printf("skc%d: unknown ram size: %d\n", sc->sk_unit, sk_win_read_1(sc, SK_EPROM0)); - bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - error = ENXIO; goto fail; break; } /* Read and save physical media type */ switch(sk_win_read_1(sc, SK_PMDTYPE)) { case SK_PMD_1000BASESX: sc->sk_pmd = IFM_1000_SX; break; case SK_PMD_1000BASELX: sc->sk_pmd = IFM_1000_LX; break; case SK_PMD_1000BASECX: sc->sk_pmd = IFM_1000_CX; break; case SK_PMD_1000BASETX: sc->sk_pmd = IFM_1000_TX; break; default: printf("skc%d: unknown media type: 0x%x\n", sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE)); - bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - error = ENXIO; goto fail; } /* Announce the product name. */ printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname); sk_attach_xmac(sc, SK_PORT_A); if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC)) sk_attach_xmac(sc, SK_PORT_B); /* Turn on the 'driver is loaded' LED. */ CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON); + at_shutdown(sk_shutdown, sc, SHUTDOWN_POST_SYNC); + fail: splx(s); - return(error); + return; } -static int sk_detach(dev) - device_t dev; -{ - struct sk_softc *sc; - struct sk_if_softc *sc_if0 = NULL, *sc_if1 = NULL; - struct ifnet *ifp0 = NULL, *ifp1 = NULL; - int s; - - s = splimp(); - - sc = device_get_softc(dev); - sc_if0 = sc->sk_if[SK_PORT_A]; - ifp0 = &sc_if0->arpcom.ac_if; - sk_stop(sc_if0); - if_detach(ifp0); - free(sc_if0->sk_cdata.sk_jumbo_buf, M_DEVBUF); - ifmedia_removeall(&sc_if0->ifmedia); - if (sc->sk_if[SK_PORT_B] != NULL) { - sc_if1 = sc->sk_if[SK_PORT_B]; - ifp1 = &sc_if1->arpcom.ac_if; - sk_stop(sc_if1); - if_detach(ifp1); - free(sc_if1->sk_cdata.sk_jumbo_buf, M_DEVBUF); - ifmedia_removeall(&sc_if1->ifmedia); - } - - bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - - splx(s); - - return(0); -} - static int sk_encap(sc_if, m_head, txidx) struct sk_if_softc *sc_if; struct mbuf *m_head; u_int32_t *txidx; { struct sk_tx_desc *f = NULL; struct mbuf *m; u_int32_t frag, cur, cnt = 0; m = m_head; cur = frag = *txidx; /* * Start packing the mbufs in this chain into * the fragment pointers. Stop when we run out * of fragments or hit the end of the mbuf chain. */ for (m = m_head; m != NULL; m = m->m_next) { if (m->m_len != 0) { if ((SK_TX_RING_CNT - (sc_if->sk_cdata.sk_tx_cnt + cnt)) < 2) return(ENOBUFS); f = &sc_if->sk_rdata->sk_tx_ring[frag]; f->sk_data_lo = vtophys(mtod(m, vm_offset_t)); f->sk_ctl = m->m_len | SK_OPCODE_DEFAULT; if (cnt == 0) f->sk_ctl |= SK_TXCTL_FIRSTFRAG; else f->sk_ctl |= SK_TXCTL_OWN; cur = frag; SK_INC(frag, SK_TX_RING_CNT); cnt++; } } if (m != NULL) return(ENOBUFS); sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |= SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR; sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head; sc_if->sk_rdata->sk_tx_ring[*txidx].sk_ctl |= SK_TXCTL_OWN; sc_if->sk_cdata.sk_tx_cnt += cnt; *txidx = frag; return(0); } static void sk_start(ifp) struct ifnet *ifp; { struct sk_softc *sc; struct sk_if_softc *sc_if; struct mbuf *m_head = NULL; u_int32_t idx; sc_if = ifp->if_softc; sc = sc_if->sk_softc; idx = sc_if->sk_cdata.sk_tx_prod; while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; /* * Pack the data into the transmit ring. If we * don't have room, set the OACTIVE flag and wait * for the NIC to drain the ring. */ if (sk_encap(sc_if, m_head, &idx)) { IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } /* * If there's a BPF listener, bounce a copy of this frame * to him. */ -#if NBPF > 0 +#if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp, m_head); #endif } /* Transmit */ sc_if->sk_cdata.sk_tx_prod = idx; CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START); /* Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; return; } static void sk_watchdog(ifp) struct ifnet *ifp; { struct sk_if_softc *sc_if; sc_if = ifp->if_softc; printf("sk%d: watchdog timeout\n", sc_if->sk_unit); sk_init(sc_if); return; } -static void sk_shutdown(dev) - device_t dev; +static void sk_shutdown(howto, arg) + int howto; + void *arg; { struct sk_softc *sc; - sc = device_get_softc(dev); + sc = arg; /* Turn off the 'driver is loaded' LED. */ CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF); /* * Reset the GEnesis controller. Doing this should also * assert the resets on the attached XMAC(s). */ sk_reset(sc); return; } static void sk_rxeof(sc_if) struct sk_if_softc *sc_if; { struct ether_header *eh; struct mbuf *m; struct ifnet *ifp; struct sk_chain *cur_rx; int total_len = 0; int i; u_int32_t rxstat; ifp = &sc_if->arpcom.ac_if; i = sc_if->sk_cdata.sk_rx_prod; cur_rx = &sc_if->sk_cdata.sk_rx_chain[i]; while(!(sc_if->sk_rdata->sk_rx_ring[i].sk_ctl & SK_RXCTL_OWN)) { cur_rx = &sc_if->sk_cdata.sk_rx_chain[i]; rxstat = sc_if->sk_rdata->sk_rx_ring[i].sk_xmac_rxstat; m = cur_rx->sk_mbuf; cur_rx->sk_mbuf = NULL; total_len = SK_RXBYTES(sc_if->sk_rdata->sk_rx_ring[i].sk_ctl); SK_INC(i, SK_RX_RING_CNT); if (rxstat & XM_RXSTAT_ERRFRAME) { ifp->if_ierrors++; sk_newbuf(sc_if, cur_rx, m); continue; } /* * Try to allocate a new jumbo buffer. If that * fails, copy the packet to mbufs and put the * jumbo buffer back in the ring so it can be * re-used. If allocating mbufs fails, then we * have to drop the packet. */ if (sk_newbuf(sc_if, cur_rx, NULL) == ENOBUFS) { struct mbuf *m0; m0 = m_devget(mtod(m, char *) - ETHER_ALIGN, total_len + ETHER_ALIGN, 0, ifp, NULL); sk_newbuf(sc_if, cur_rx, m); if (m0 == NULL) { printf("sk%d: no receive buffers " "available -- packet dropped!\n", sc_if->sk_unit); ifp->if_ierrors++; continue; } m_adj(m0, ETHER_ALIGN); m = m0; } else { m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = total_len; } ifp->if_ipackets++; eh = mtod(m, struct ether_header *); -#if NBPF > 0 +#if NBPFILTER > 0 if (ifp->if_bpf) { bpf_mtap(ifp, m); if (ifp->if_flags & IFF_PROMISC && (bcmp(eh->ether_dhost, sc_if->arpcom.ac_enaddr, ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) { m_freem(m); continue; } } #endif /* Remove header from mbuf and pass it on. */ m_adj(m, sizeof(struct ether_header)); ether_input(ifp, eh, m); } sc_if->sk_cdata.sk_rx_prod = i; return; } static void sk_txeof(sc_if) struct sk_if_softc *sc_if; { struct sk_tx_desc *cur_tx = NULL; struct ifnet *ifp; u_int32_t idx; ifp = &sc_if->arpcom.ac_if; /* * Go through our tx ring and free mbufs for those * frames that have been sent. */ idx = sc_if->sk_cdata.sk_tx_cons; while(idx != sc_if->sk_cdata.sk_tx_prod) { cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx]; if (cur_tx->sk_ctl & SK_TXCTL_OWN) break; if (cur_tx->sk_ctl & SK_TXCTL_LASTFRAG) ifp->if_opackets++; if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) { m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf); sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL; } sc_if->sk_cdata.sk_tx_cnt--; SK_INC(idx, SK_TX_RING_CNT); ifp->if_timer = 0; } sc_if->sk_cdata.sk_tx_cons = idx; if (cur_tx != NULL) ifp->if_flags &= ~IFF_OACTIVE; return; } static void sk_intr_xmac(sc_if) struct sk_if_softc *sc_if; { struct sk_softc *sc; u_int16_t status; u_int16_t bmsr; sc = sc_if->sk_softc; status = SK_XM_READ_2(sc_if, XM_ISR); if (status & XM_ISR_LINKEVENT) { SK_XM_SETBIT_2(sc_if, XM_IMR, XM_IMR_LINKEVENT); if (sc_if->sk_link == 1) { printf("sk%d: gigabit link down\n", sc_if->sk_unit); sc_if->sk_link = 0; } } if (status & XM_ISR_AUTONEG_DONE) { bmsr = sk_phy_readreg(sc_if, XM_PHY_BMSR); if (bmsr & XM_BMSR_LINKSTAT) { sc_if->sk_link = 1; SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_LINKEVENT); printf("sk%d: gigabit link up\n", sc_if->sk_unit); } } if (status & XM_IMR_TX_UNDERRUN) SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_TXFIFO); if (status & XM_IMR_RX_OVERRUN) SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_RXFIFO); return; } static void sk_intr(xsc) void *xsc; { struct sk_softc *sc = xsc; struct sk_if_softc *sc_if0 = NULL, *sc_if1 = NULL; struct ifnet *ifp0 = NULL, *ifp1 = NULL; u_int32_t status; sc_if0 = sc->sk_if[SK_PORT_A]; sc_if1 = sc->sk_if[SK_PORT_B]; if (sc_if0 != NULL) ifp0 = &sc_if0->arpcom.ac_if; if (sc_if1 != NULL) ifp1 = &sc_if0->arpcom.ac_if; for (;;) { status = CSR_READ_4(sc, SK_ISSR); if (!(status & sc->sk_intrmask)) break; /* Handle receive interrupts first. */ if (status & SK_ISR_RX1_EOF) { sk_rxeof(sc_if0); CSR_WRITE_4(sc, SK_BMU_RX_CSR0, SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START); } if (status & SK_ISR_RX2_EOF) { sk_rxeof(sc_if1); CSR_WRITE_4(sc, SK_BMU_RX_CSR1, SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START); } /* Then transmit interrupts. */ if (status & SK_ISR_TX1_S_EOF) { sk_txeof(sc_if0); CSR_WRITE_4(sc, SK_BMU_TXS_CSR0, SK_TXBMU_CLR_IRQ_EOF); } if (status & SK_ISR_TX2_S_EOF) { sk_txeof(sc_if1); CSR_WRITE_4(sc, SK_BMU_TXS_CSR1, SK_TXBMU_CLR_IRQ_EOF); } /* Then MAC interrupts. */ if (status & SK_ISR_MAC1) sk_intr_xmac(sc_if0); if (status & SK_ISR_MAC2) sk_intr_xmac(sc_if1); } CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); return; } static void sk_init_xmac(sc_if) struct sk_if_softc *sc_if; { struct sk_softc *sc; struct ifnet *ifp; sc = sc_if->sk_softc; ifp = &sc_if->arpcom.ac_if; /* Unreset the XMAC. */ SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_UNRESET); DELAY(1000); /* Save the XMAC II revision */ sc_if->sk_xmac_rev = XM_XMAC_REV(SK_XM_READ_4(sc_if, XM_DEVID)); /* Set station address */ SK_XM_WRITE_2(sc_if, XM_PAR0, *(u_int16_t *)(&sc_if->arpcom.ac_enaddr[0])); SK_XM_WRITE_2(sc_if, XM_PAR1, *(u_int16_t *)(&sc_if->arpcom.ac_enaddr[2])); SK_XM_WRITE_2(sc_if, XM_PAR2, *(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4])); SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION); if (ifp->if_flags & IFF_PROMISC) { SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); } else { SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); } if (ifp->if_flags & IFF_BROADCAST) { SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD); } else { SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD); } /* We don't need the FCS appended to the packet. */ SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_STRIPFCS); /* We want short frames padded to 60 bytes. */ SK_XM_SETBIT_2(sc_if, XM_TXCMD, XM_TXCMD_AUTOPAD); /* * Enable the reception of all error frames. This is is * a necessary evil due to the design of the XMAC. The * XMAC's receive FIFO is only 8K in size, however jumbo * frames can be up to 9000 bytes in length. When bad * frame filtering is enabled, the XMAC's RX FIFO operates * in 'store and forward' mode. For this to work, the * entire frame has to fit into the FIFO, but that means * that jumbo frames larger than 8192 bytes will be * truncated. Disabling all bad frame filtering causes * the RX FIFO to operate in streaming mode, in which * case the XMAC will start transfering frames out of the * RX FIFO as soon as the FIFO threshold is reached. */ SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_BADFRAMES| XM_MODE_RX_GIANTS|XM_MODE_RX_RUNTS|XM_MODE_RX_CRCERRS| XM_MODE_RX_INRANGELEN); if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK); else SK_XM_CLRBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK); /* * Bump up the transmit threshold. This helps hold off transmit * underruns when we're blasting traffic from both ports at once. */ SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH); /* Set multicast filter */ sk_setmulti(sc_if); /* Clear and enable interrupts */ SK_XM_READ_2(sc_if, XM_ISR); SK_XM_WRITE_2(sc_if, XM_IMR, XM_INTRS); sc_if->sk_link = 0; /* Configure MAC arbiter */ switch(sc_if->sk_xmac_rev) { case XM_XMAC_REV_B2: sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_B2); sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_B2); sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_B2); sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_B2); sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_B2); sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_B2); sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_B2); sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_B2); sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2); break; case XM_XMAC_REV_C1: sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_C1); sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_C1); sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_C1); sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_C1); sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_C1); sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_C1); sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_C1); sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_C1); sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2); break; default: break; } sk_win_write_2(sc, SK_MACARB_CTL, SK_MACARBCTL_UNRESET|SK_MACARBCTL_FASTOE_OFF); return; } /* * Note that to properly initialize any part of the GEnesis chip, * you first have to take it out of reset mode. */ static void sk_init(xsc) void *xsc; { struct sk_if_softc *sc_if = xsc; struct sk_softc *sc; struct ifnet *ifp; int s; s = splimp(); ifp = &sc_if->arpcom.ac_if; sc = sc_if->sk_softc; /* Cancel pending I/O and free all RX/TX buffers. */ sk_stop(sc_if); /* Configure LINK_SYNC LED */ SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON); SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_ON); /* Configure RX LED */ SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_START); /* Configure TX LED */ SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_START); /* Configure I2C registers */ /* Configure XMAC(s) */ sk_init_xmac(sc_if); /* Configure MAC FIFOs */ SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET); SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END); SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON); SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET); SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END); SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON); /* Configure transmit arbiter(s) */ SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON); /* Configure RAMbuffers */ SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_UNRESET); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_STORENFWD_ON); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_START, sc_if->sk_tx_ramstart); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_WR_PTR, sc_if->sk_tx_ramstart); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_RD_PTR, sc_if->sk_tx_ramstart); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_END, sc_if->sk_tx_ramend); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_ON); /* Configure BMUs */ SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_ONLINE); SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO, vtophys(&sc_if->sk_rdata->sk_rx_ring[0])); SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 0); SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_ONLINE); SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_LO, vtophys(&sc_if->sk_rdata->sk_tx_ring[0])); SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_HI, 0); /* Init descriptors */ if (sk_init_rx_ring(sc_if) == ENOBUFS) { printf("sk%d: initialization failed: no " "memory for rx buffers\n", sc_if->sk_unit); sk_stop(sc_if); (void)splx(s); return; } sk_init_tx_ring(sc_if); /* Configure interrupt handling */ CSR_READ_4(sc, SK_ISSR); if (sc_if->sk_port == SK_PORT_A) sc->sk_intrmask |= SK_INTRS1; else sc->sk_intrmask |= SK_INTRS2; CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); /* Start BMUs. */ SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START); /* Enable XMACs TX and RX state machines */ SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; splx(s); return; } static void sk_stop(sc_if) struct sk_if_softc *sc_if; { int i; struct sk_softc *sc; struct ifnet *ifp; sc = sc_if->sk_softc; ifp = &sc_if->arpcom.ac_if; /* Turn off various components of this interface. */ SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_RESET); SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE); SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); /* Disable interrupts */ if (sc_if->sk_port == SK_PORT_A) sc->sk_intrmask &= ~SK_INTRS1; else sc->sk_intrmask &= ~SK_INTRS2; CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); /* Free RX and TX mbufs still in the queues. */ for (i = 0; i < SK_RX_RING_CNT; i++) { if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) { m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf); sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL; } } for (i = 0; i < SK_TX_RING_CNT; i++) { if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) { m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf); sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL; } } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); return; } + +static struct pci_device sk_device = { + "skc", + sk_probe, + sk_attach, + &skc_count, + NULL +}; +#ifdef COMPAT_PCI_DRIVER +COMPAT_PCI_DRIVER(sk, sk_device); +#else +DATA_SET(pcidevice_set, sk_device); +#endif Index: stable/3/sys/pci/if_skreg.h =================================================================== --- stable/3/sys/pci/if_skreg.h (revision 49544) +++ stable/3/sys/pci/if_skreg.h (revision 49545) @@ -1,1171 +1,1169 @@ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_skreg.h,v 1.5 1999/07/23 02:06:56 wpaul Exp $ + * $Id: if_skreg.h,v 1.33 1999/07/14 21:48:19 wpaul Exp $ */ /* * SysKonnect PCI vendor ID */ #define SK_VENDORID 0x1148 /* * SK-NET gigabit ethernet device ID */ #define SK_DEVICEID_GE 0x4300 /* * GEnesis registers. The GEnesis chip has a 256-byte I/O window * but internally it has a 16K register space. This 16K space is * divided into 128-byte blocks. The first 128 bytes of the I/O * window represent the first block, which is permanently mapped * at the start of the window. The other 127 blocks can be mapped * to the second 128 bytes of the I/O window by setting the desired * block value in the RAP register in block 0. Not all of the 127 * blocks are actually used. Most registers are 32 bits wide, but * there are a few 16-bit and 8-bit ones as well. */ /* Start of remappable register window. */ #define SK_WIN_BASE 0x0080 /* Size of a window */ #define SK_WIN_LEN 0x80 #define SK_WIN_MASK 0x3F80 #define SK_REG_MASK 0x7F /* Compute the window of a given register (for the RAP register) */ #define SK_WIN(reg) (((reg) & SK_WIN_MASK) / SK_WIN_LEN) /* Compute the relative offset of a register within the window */ #define SK_REG(reg) ((reg) & SK_REG_MASK) #define SK_PORT_A 0 #define SK_PORT_B 1 /* * Compute offset of port-specific register. Since there are two * ports, there are two of some GEnesis modules (e.g. two sets of * DMA queues, two sets of FIFO control registers, etc...). Normally, * the block for port 0 is at offset 0x0 and the block for port 1 is * at offset 0x80 (i.e. the next page over). However for the transmit * BMUs and RAMbuffers, there are two blocks for each port: one for * the sync transmit queue and one for the async queue (which we don't * use). However instead of ordering them like this: * TX sync 1 / TX sync 2 / TX async 1 / TX async 2 * SysKonnect has instead ordered them like this: * TX sync 1 / TX async 1 / TX sync 2 / TX async 2 * This means that when referencing the TX BMU and RAMbuffer registers, * we have to double the block offset (0x80 * 2) in order to reach the * second queue. This prevents us from using the same formula * (sk_port * 0x80) to compute the offsets for all of the port-specific * blocks: we need an extra offset for the BMU and RAMbuffer registers. * The simplest thing is to provide an extra argument to these macros: * the 'skip' parameter. The 'skip' value is the number of extra pages * for skip when computing the port0/port1 offsets. For most registers, * the skip value is 0; for the BMU and RAMbuffer registers, it's 1. */ #define SK_IF_READ_4(sc_if, skip, reg) \ sk_win_read_4(sc_if->sk_softc, reg + \ ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) #define SK_IF_READ_2(sc_if, skip, reg) \ sk_win_read_2(sc_if->sk_softc, reg + \ ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) #define SK_IF_READ_1(sc_if, skip, reg) \ sk_win_read_1(sc_if->sk_softc, reg + \ ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) #define SK_IF_WRITE_4(sc_if, skip, reg, val) \ sk_win_write_4(sc_if->sk_softc, \ reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) #define SK_IF_WRITE_2(sc_if, skip, reg, val) \ sk_win_write_2(sc_if->sk_softc, \ reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) #define SK_IF_WRITE_1(sc_if, skip, reg, val) \ sk_win_write_1(sc_if->sk_softc, \ reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) /* Block 0 registers, permanently mapped at iobase. */ #define SK_RAP 0x0000 #define SK_CSR 0x0004 #define SK_LED 0x0006 #define SK_ISR 0x0008 /* interrupt source */ #define SK_IMR 0x000C /* interrupt mask */ #define SK_IESR 0x0010 /* interrupt hardware error source */ #define SK_IEMR 0x0014 /* interrupt hardware error mask */ #define SK_ISSR 0x0018 /* special interrupt source */ #define SK_XM_IMR0 0x0020 #define SK_XM_ISR0 0x0028 #define SK_XM_PHYADDR0 0x0030 #define SK_XM_PHYDATA0 0x0034 #define SK_XM_IMR1 0x0040 #define SK_XM_ISR1 0x0048 #define SK_XM_PHYADDR1 0x0050 #define SK_XM_PHYDATA1 0x0054 #define SK_BMU_RX_CSR0 0x0060 #define SK_BMU_RX_CSR1 0x0064 #define SK_BMU_TXS_CSR0 0x0068 #define SK_BMU_TXA_CSR0 0x006C #define SK_BMU_TXS_CSR1 0x0070 #define SK_BMU_TXA_CSR1 0x0074 /* SK_CSR register */ #define SK_CSR_SW_RESET 0x0001 #define SK_CSR_SW_UNRESET 0x0002 #define SK_CSR_MASTER_RESET 0x0004 #define SK_CSR_MASTER_UNRESET 0x0008 #define SK_CSR_MASTER_STOP 0x0010 #define SK_CSR_MASTER_DONE 0x0020 #define SK_CSR_SW_IRQ_CLEAR 0x0040 #define SK_CSR_SW_IRQ_SET 0x0080 #define SK_CSR_SLOTSIZE 0x0100 /* 1 == 64 bits, 0 == 32 */ #define SK_CSR_BUSCLOCK 0x0200 /* 1 == 33/66 Mhz, = 33 */ /* SK_LED register */ #define SK_LED_GREEN_OFF 0x01 #define SK_LED_GREEN_ON 0x02 /* SK_ISR register */ #define SK_ISR_TX2_AS_CHECK 0x00000001 #define SK_ISR_TX2_AS_EOF 0x00000002 #define SK_ISR_TX2_AS_EOB 0x00000004 #define SK_ISR_TX2_S_CHECK 0x00000008 #define SK_ISR_TX2_S_EOF 0x00000010 #define SK_ISR_TX2_S_EOB 0x00000020 #define SK_ISR_TX1_AS_CHECK 0x00000040 #define SK_ISR_TX1_AS_EOF 0x00000080 #define SK_ISR_TX1_AS_EOB 0x00000100 #define SK_ISR_TX1_S_CHECK 0x00000200 #define SK_ISR_TX1_S_EOF 0x00000400 #define SK_ISR_TX1_S_EOB 0x00000800 #define SK_ISR_RX2_CHECK 0x00001000 #define SK_ISR_RX2_EOF 0x00002000 #define SK_ISR_RX2_EOB 0x00004000 #define SK_ISR_RX1_CHECK 0x00008000 #define SK_ISR_RX1_EOF 0x00010000 #define SK_ISR_RX1_EOB 0x00020000 #define SK_ISR_LINK2_OFLOW 0x00040000 #define SK_ISR_MAC2 0x00080000 #define SK_ISR_LINK1_OFLOW 0x00100000 #define SK_ISR_MAC1 0x00200000 #define SK_ISR_TIMER 0x00400000 #define SK_ISR_EXTERNAL_REG 0x00800000 #define SK_ISR_SW 0x01000000 #define SK_ISR_I2C_RDY 0x02000000 #define SK_ISR_TX2_TIMEO 0x04000000 #define SK_ISR_TX1_TIMEO 0x08000000 #define SK_ISR_RX2_TIMEO 0x10000000 #define SK_ISR_RX1_TIMEO 0x20000000 #define SK_ISR_RSVD 0x40000000 #define SK_ISR_HWERR 0x80000000 /* SK_IMR register */ #define SK_IMR_TX2_AS_CHECK 0x00000001 #define SK_IMR_TX2_AS_EOF 0x00000002 #define SK_IMR_TX2_AS_EOB 0x00000004 #define SK_IMR_TX2_S_CHECK 0x00000008 #define SK_IMR_TX2_S_EOF 0x00000010 #define SK_IMR_TX2_S_EOB 0x00000020 #define SK_IMR_TX1_AS_CHECK 0x00000040 #define SK_IMR_TX1_AS_EOF 0x00000080 #define SK_IMR_TX1_AS_EOB 0x00000100 #define SK_IMR_TX1_S_CHECK 0x00000200 #define SK_IMR_TX1_S_EOF 0x00000400 #define SK_IMR_TX1_S_EOB 0x00000800 #define SK_IMR_RX2_CHECK 0x00001000 #define SK_IMR_RX2_EOF 0x00002000 #define SK_IMR_RX2_EOB 0x00004000 #define SK_IMR_RX1_CHECK 0x00008000 #define SK_IMR_RX1_EOF 0x00010000 #define SK_IMR_RX1_EOB 0x00020000 #define SK_IMR_LINK2_OFLOW 0x00040000 #define SK_IMR_MAC2 0x00080000 #define SK_IMR_LINK1_OFLOW 0x00100000 #define SK_IMR_MAC1 0x00200000 #define SK_IMR_TIMER 0x00400000 #define SK_IMR_EXTERNAL_REG 0x00800000 #define SK_IMR_SW 0x01000000 #define SK_IMR_I2C_RDY 0x02000000 #define SK_IMR_TX2_TIMEO 0x04000000 #define SK_IMR_TX1_TIMEO 0x08000000 #define SK_IMR_RX2_TIMEO 0x10000000 #define SK_IMR_RX1_TIMEO 0x20000000 #define SK_IMR_RSVD 0x40000000 #define SK_IMR_HWERR 0x80000000 #define SK_INTRS1 \ (SK_IMR_RX1_EOF|SK_IMR_TX1_S_EOF|SK_IMR_MAC1) #define SK_INTRS2 \ (SK_IMR_RX2_EOF|SK_IMR_TX2_S_EOF|SK_IMR_MAC2) /* SK_IESR register */ #define SK_IESR_PAR_RX2 0x00000001 #define SK_IESR_PAR_RX1 0x00000002 #define SK_IESR_PAR_MAC2 0x00000004 #define SK_IESR_PAR_MAC1 0x00000008 #define SK_IESR_PAR_WR_RAM 0x00000010 #define SK_IESR_PAR_RD_RAM 0x00000020 #define SK_IESR_NO_TSTAMP_MAC2 0x00000040 #define SK_IESR_NO_TSTAMO_MAC1 0x00000080 #define SK_IESR_NO_STS_MAC2 0x00000100 #define SK_IESR_NO_STS_MAC1 0x00000200 #define SK_IESR_IRQ_STS 0x00000400 #define SK_IESR_MASTERERR 0x00000800 /* SK_IEMR register */ #define SK_IEMR_PAR_RX2 0x00000001 #define SK_IEMR_PAR_RX1 0x00000002 #define SK_IEMR_PAR_MAC2 0x00000004 #define SK_IEMR_PAR_MAC1 0x00000008 #define SK_IEMR_PAR_WR_RAM 0x00000010 #define SK_IEMR_PAR_RD_RAM 0x00000020 #define SK_IEMR_NO_TSTAMP_MAC2 0x00000040 #define SK_IEMR_NO_TSTAMO_MAC1 0x00000080 #define SK_IEMR_NO_STS_MAC2 0x00000100 #define SK_IEMR_NO_STS_MAC1 0x00000200 #define SK_IEMR_IRQ_STS 0x00000400 #define SK_IEMR_MASTERERR 0x00000800 /* Block 2 */ #define SK_MAC0_0 0x0100 #define SK_MAC0_1 0x0104 #define SK_MAC1_0 0x0108 #define SK_MAC1_1 0x010C #define SK_MAC2_0 0x0110 #define SK_MAC2_1 0x0114 #define SK_CONNTYPE 0x0118 #define SK_PMDTYPE 0x0119 #define SK_CONFIG 0x011A #define SK_CHIPVER 0x011B #define SK_EPROM0 0x011C #define SK_EPROM1 0x011D #define SK_EPROM2 0x011E #define SK_EPROM3 0x011F #define SK_EP_ADDR 0x0120 #define SK_EP_DATA 0x0124 #define SK_EP_LOADCTL 0x0128 #define SK_EP_LOADTST 0x0129 #define SK_TIMERINIT 0x0130 #define SK_TIMER 0x0134 #define SK_TIMERCTL 0x0138 #define SK_TIMERTST 0x0139 #define SK_IMTIMERINIT 0x0140 #define SK_IMTIMER 0x0144 #define SK_IMTIMERCTL 0x0148 #define SK_IMTIMERTST 0x0149 #define SK_IMMR 0x014C #define SK_IHWEMR 0x0150 #define SK_TESTCTL1 0x0158 #define SK_TESTCTL2 0x0159 #define SK_GPIO 0x015C #define SK_I2CHWCTL 0x0160 #define SK_I2CHWDATA 0x0164 #define SK_I2CHWIRQ 0x0168 #define SK_I2CSW 0x016C #define SK_BLNKINIT 0x0170 #define SK_BLNKCOUNT 0x0174 #define SK_BLNKCTL 0x0178 #define SK_BLNKSTS 0x0179 #define SK_BLNKTST 0x017A #define SK_IMCTL_STOP 0x02 #define SK_IMCTL_START 0x04 #define SK_IMTIMER_TICKS 54 #define SK_IM_USECS(x) ((x) * SK_IMTIMER_TICKS) /* * The SK_EPROM0 register contains a byte that describes the * amount of SRAM mounted on the NIC. The value also tells if * the chips are 64K or 128K. This affects the RAMbuffer address * offset that we need to use. */ #define SK_RAMSIZE_512K_64 0x1 #define SK_RAMSIZE_1024K_128 0x2 #define SK_RAMSIZE_1024K_64 0x3 #define SK_RAMSIZE_2048K_128 0x4 #define SK_RBOFF_0 0x0 #define SK_RBOFF_80000 0x80000 #define SK_CONFIG_SINGLEMAC 0x01 #define SK_CONFIG_DIS_DSL_CLK 0x02 #define SK_PMD_1000BASELX 0x4C #define SK_PMD_1000BASESX 0x53 #define SK_PMD_1000BASECX 0x43 #define SK_PMD_1000BASETX 0x54 /* Block 3 Ram interface and MAC arbiter registers */ #define SK_RAMADDR 0x0180 #define SK_RAMDATA0 0x0184 #define SK_RAMDATA1 0x0188 #define SK_TO0 0x0190 #define SK_TO1 0x0191 #define SK_TO2 0x0192 #define SK_TO3 0x0193 #define SK_TO4 0x0194 #define SK_TO5 0x0195 #define SK_TO6 0x0196 #define SK_TO7 0x0197 #define SK_TO8 0x0198 #define SK_TO9 0x0199 #define SK_TO10 0x019A #define SK_TO11 0x019B #define SK_RITIMEO_TMR 0x019C #define SK_RAMCTL 0x01A0 #define SK_RITIMER_TST 0x01A2 #define SK_RAMCTL_RESET 0x0001 #define SK_RAMCTL_UNRESET 0x0002 #define SK_RAMCTL_CLR_IRQ_WPAR 0x0100 #define SK_RAMCTL_CLR_IRQ_RPAR 0x0200 /* Mac arbiter registers */ #define SK_MINIT_RX1 0x01B0 #define SK_MINIT_RX2 0x01B1 #define SK_MINIT_TX1 0x01B2 #define SK_MINIT_TX2 0x01B3 #define SK_MTIMEO_RX1 0x01B4 #define SK_MTIMEO_RX2 0x01B5 #define SK_MTIMEO_TX1 0x01B6 #define SK_MTIEMO_TX2 0x01B7 #define SK_MACARB_CTL 0x01B8 #define SK_MTIMER_TST 0x01BA #define SK_RCINIT_RX1 0x01C0 #define SK_RCINIT_RX2 0x01C1 #define SK_RCINIT_TX1 0x01C2 #define SK_RCINIT_TX2 0x01C3 #define SK_RCTIMEO_RX1 0x01C4 #define SK_RCTIMEO_RX2 0x01C5 #define SK_RCTIMEO_TX1 0x01C6 #define SK_RCTIMEO_TX2 0x01C7 #define SK_RECOVERY_CTL 0x01C8 #define SK_RCTIMER_TST 0x01CA /* Packet arbiter registers */ #define SK_RXPA1_TINIT 0x01D0 #define SK_RXPA2_TINIT 0x01D4 #define SK_TXPA1_TINIT 0x01D8 #define SK_TXPA2_TINIT 0x01DC #define SK_RXPA1_TIMEO 0x01E0 #define SK_RXPA2_TIMEO 0x01E4 #define SK_TXPA1_TIMEO 0x01E8 #define SK_TXPA2_TIMEO 0x01EC #define SK_PKTARB_CTL 0x01F0 #define SK_PKTATB_TST 0x01F2 #define SK_PKTARB_TIMEOUT 0x2000 #define SK_PKTARBCTL_RESET 0x0001 #define SK_PKTARBCTL_UNRESET 0x0002 #define SK_PKTARBCTL_RXTO1_OFF 0x0004 #define SK_PKTARBCTL_RXTO1_ON 0x0008 #define SK_PKTARBCTL_RXTO2_OFF 0x0010 #define SK_PKTARBCTL_RXTO2_ON 0x0020 #define SK_PKTARBCTL_TXTO1_OFF 0x0040 #define SK_PKTARBCTL_TXTO1_ON 0x0080 #define SK_PKTARBCTL_TXTO2_OFF 0x0100 #define SK_PKTARBCTL_TXTO2_ON 0x0200 #define SK_PKTARBCTL_CLR_IRQ_RXTO1 0x0400 #define SK_PKTARBCTL_CLR_IRQ_RXTO2 0x0800 #define SK_PKTARBCTL_CLR_IRQ_TXTO1 0x1000 #define SK_PKTARBCTL_CLR_IRQ_TXTO2 0x2000 #define SK_MINIT_XMAC_B2 54 #define SK_MINIT_XMAC_C1 63 #define SK_MACARBCTL_RESET 0x0001 #define SK_MACARBCTL_UNRESET 0x0002 #define SK_MACARBCTL_FASTOE_OFF 0x0004 #define SK_MACARBCRL_FASTOE_ON 0x0008 #define SK_RCINIT_XMAC_B2 54 #define SK_RCINIT_XMAC_C1 0 #define SK_RECOVERYCTL_RX1_OFF 0x0001 #define SK_RECOVERYCTL_RX1_ON 0x0002 #define SK_RECOVERYCTL_RX2_OFF 0x0004 #define SK_RECOVERYCTL_RX2_ON 0x0008 #define SK_RECOVERYCTL_TX1_OFF 0x0010 #define SK_RECOVERYCTL_TX1_ON 0x0020 #define SK_RECOVERYCTL_TX2_OFF 0x0040 #define SK_RECOVERYCTL_TX2_ON 0x0080 #define SK_RECOVERY_XMAC_B2 \ (SK_RECOVERYCTL_RX1_ON|SK_RECOVERYCTL_RX2_ON| \ SK_RECOVERYCTL_TX1_ON|SK_RECOVERYCTL_TX2_ON) #define SK_RECOVERY_XMAC_C1 \ (SK_RECOVERYCTL_RX1_OFF|SK_RECOVERYCTL_RX2_OFF| \ SK_RECOVERYCTL_TX1_OFF|SK_RECOVERYCTL_TX2_OFF) /* Block 4 -- TX Arbiter MAC 1 */ #define SK_TXAR1_TIMERINIT 0x0200 #define SK_TXAR1_TIMERVAL 0x0204 #define SK_TXAR1_LIMITINIT 0x0208 #define SK_TXAR1_LIMITCNT 0x020C #define SK_TXAR1_COUNTERCTL 0x0210 #define SK_TXAR1_COUNTERTST 0x0212 #define SK_TXAR1_COUNTERSTS 0x0212 /* Block 5 -- TX Arbiter MAC 2 */ #define SK_TXAR2_TIMERINIT 0x0280 #define SK_TXAR2_TIMERVAL 0x0284 #define SK_TXAR2_LIMITINIT 0x0288 #define SK_TXAR2_LIMITCNT 0x028C #define SK_TXAR2_COUNTERCTL 0x0290 #define SK_TXAR2_COUNTERTST 0x0291 #define SK_TXAR2_COUNTERSTS 0x0292 #define SK_TXARCTL_OFF 0x01 #define SK_TXARCTL_ON 0x02 #define SK_TXARCTL_RATECTL_OFF 0x04 #define SK_TXARCTL_RATECTL_ON 0x08 #define SK_TXARCTL_ALLOC_OFF 0x10 #define SK_TXARCTL_ALLOC_ON 0x20 #define SK_TXARCTL_FSYNC_OFF 0x40 #define SK_TXARCTL_FSYNC_ON 0x80 /* Block 6 -- External registers */ #define SK_EXTREG_BASE 0x300 #define SK_EXTREG_END 0x37C /* Block 7 -- PCI config registers */ #define SK_PCI_BASE 0x0380 #define SK_PCI_END 0x03FC /* Compute offset of mirrored PCI register */ #define SK_PCI_REG(reg) ((reg) + SK_PCI_BASE) /* Block 8 -- RX queue 1 */ #define SK_RXQ1_BUFCNT 0x0400 #define SK_RXQ1_BUFCTL 0x0402 #define SK_RXQ1_NEXTDESC 0x0404 #define SK_RXQ1_RXBUF_LO 0x0408 #define SK_RXQ1_RXBUF_HI 0x040C #define SK_RXQ1_RXSTAT 0x0410 #define SK_RXQ1_TIMESTAMP 0x0414 #define SK_RXQ1_CSUM1 0x0418 #define SK_RXQ1_CSUM2 0x041A #define SK_RXQ1_CSUM1_START 0x041C #define SK_RXQ1_CSUM2_START 0x041E #define SK_RXQ1_CURADDR_LO 0x0420 #define SK_RXQ1_CURADDR_HI 0x0424 #define SK_RXQ1_CURCNT_LO 0x0428 #define SK_RXQ1_CURCNT_HI 0x042C #define SK_RXQ1_CURBYTES 0x0430 #define SK_RXQ1_BMU_CSR 0x0434 #define SK_RXQ1_WATERMARK 0x0438 #define SK_RXQ1_FLAG 0x043A #define SK_RXQ1_TEST1 0x043C #define SK_RXQ1_TEST2 0x0440 #define SK_RXQ1_TEST3 0x0444 /* Block 9 -- RX queue 2 */ #define SK_RXQ2_BUFCNT 0x0480 #define SK_RXQ2_BUFCTL 0x0482 #define SK_RXQ2_NEXTDESC 0x0484 #define SK_RXQ2_RXBUF_LO 0x0488 #define SK_RXQ2_RXBUF_HI 0x048C #define SK_RXQ2_RXSTAT 0x0490 #define SK_RXQ2_TIMESTAMP 0x0494 #define SK_RXQ2_CSUM1 0x0498 #define SK_RXQ2_CSUM2 0x049A #define SK_RXQ2_CSUM1_START 0x049C #define SK_RXQ2_CSUM2_START 0x049E #define SK_RXQ2_CURADDR_LO 0x04A0 #define SK_RXQ2_CURADDR_HI 0x04A4 #define SK_RXQ2_CURCNT_LO 0x04A8 #define SK_RXQ2_CURCNT_HI 0x04AC #define SK_RXQ2_CURBYTES 0x04B0 #define SK_RXQ2_BMU_CSR 0x04B4 #define SK_RXQ2_WATERMARK 0x04B8 #define SK_RXQ2_FLAG 0x04BA #define SK_RXQ2_TEST1 0x04BC #define SK_RXQ2_TEST2 0x04C0 #define SK_RXQ2_TEST3 0x04C4 #define SK_RXBMU_CLR_IRQ_ERR 0x00000001 #define SK_RXBMU_CLR_IRQ_EOF 0x00000002 #define SK_RXBMU_CLR_IRQ_EOB 0x00000004 #define SK_RXBMU_CLR_IRQ_PAR 0x00000008 #define SK_RXBMU_RX_START 0x00000010 #define SK_RXBMU_RX_STOP 0x00000020 #define SK_RXBMU_POLL_OFF 0x00000040 #define SK_RXBMU_POLL_ON 0x00000080 #define SK_RXBMU_TRANSFER_SM_RESET 0x00000100 #define SK_RXBMU_TRANSFER_SM_UNRESET 0x00000200 #define SK_RXBMU_DESCWR_SM_RESET 0x00000400 #define SK_RXBMU_DESCWR_SM_UNRESET 0x00000800 #define SK_RXBMU_DESCRD_SM_RESET 0x00001000 #define SK_RXBMU_DESCRD_SM_UNRESET 0x00002000 #define SK_RXBMU_SUPERVISOR_SM_RESET 0x00004000 #define SK_RXBMU_SUPERVISOR_SM_UNRESET 0x00008000 #define SK_RXBMU_PFI_SM_RESET 0x00010000 #define SK_RXBMU_PFI_SM_UNRESET 0x00020000 #define SK_RXBMU_FIFO_RESET 0x00040000 #define SK_RXBMU_FIFO_UNRESET 0x00080000 #define SK_RXBMU_DESC_RESET 0x00100000 #define SK_RXBMU_DESC_UNRESET 0x00200000 #define SK_RXBMU_SUPERVISOR_IDLE 0x01000000 #define SK_RXBMU_ONLINE \ (SK_RXBMU_TRANSFER_SM_UNRESET|SK_RXBMU_DESCWR_SM_UNRESET| \ SK_RXBMU_DESCRD_SM_UNRESET|SK_RXBMU_SUPERVISOR_SM_UNRESET| \ SK_RXBMU_PFI_SM_UNRESET|SK_RXBMU_FIFO_UNRESET| \ SK_RXBMU_DESC_UNRESET) #define SK_RXBMU_OFFLINE \ (SK_RXBMU_TRANSFER_SM_RESET|SK_RXBMU_DESCWR_SM_RESET| \ SK_RXBMU_DESCRD_SM_RESET|SK_RXBMU_SUPERVISOR_SM_RESET| \ SK_RXBMU_PFI_SM_RESET|SK_RXBMU_FIFO_RESET| \ SK_RXBMU_DESC_RESET) /* Block 12 -- TX sync queue 1 */ #define SK_TXQS1_BUFCNT 0x0600 #define SK_TXQS1_BUFCTL 0x0602 #define SK_TXQS1_NEXTDESC 0x0604 #define SK_TXQS1_RXBUF_LO 0x0608 #define SK_TXQS1_RXBUF_HI 0x060C #define SK_TXQS1_RXSTAT 0x0610 #define SK_TXQS1_CSUM_STARTVAL 0x0614 #define SK_TXQS1_CSUM_STARTPOS 0x0618 #define SK_TXQS1_CSUM_WRITEPOS 0x061A #define SK_TXQS1_CURADDR_LO 0x0620 #define SK_TXQS1_CURADDR_HI 0x0624 #define SK_TXQS1_CURCNT_LO 0x0628 #define SK_TXQS1_CURCNT_HI 0x062C #define SK_TXQS1_CURBYTES 0x0630 #define SK_TXQS1_BMU_CSR 0x0634 #define SK_TXQS1_WATERMARK 0x0638 #define SK_TXQS1_FLAG 0x063A #define SK_TXQS1_TEST1 0x063C #define SK_TXQS1_TEST2 0x0640 #define SK_TXQS1_TEST3 0x0644 /* Block 13 -- TX async queue 1 */ #define SK_TXQA1_BUFCNT 0x0680 #define SK_TXQA1_BUFCTL 0x0682 #define SK_TXQA1_NEXTDESC 0x0684 #define SK_TXQA1_RXBUF_LO 0x0688 #define SK_TXQA1_RXBUF_HI 0x068C #define SK_TXQA1_RXSTAT 0x0690 #define SK_TXQA1_CSUM_STARTVAL 0x0694 #define SK_TXQA1_CSUM_STARTPOS 0x0698 #define SK_TXQA1_CSUM_WRITEPOS 0x069A #define SK_TXQA1_CURADDR_LO 0x06A0 #define SK_TXQA1_CURADDR_HI 0x06A4 #define SK_TXQA1_CURCNT_LO 0x06A8 #define SK_TXQA1_CURCNT_HI 0x06AC #define SK_TXQA1_CURBYTES 0x06B0 #define SK_TXQA1_BMU_CSR 0x06B4 #define SK_TXQA1_WATERMARK 0x06B8 #define SK_TXQA1_FLAG 0x06BA #define SK_TXQA1_TEST1 0x06BC #define SK_TXQA1_TEST2 0x06C0 #define SK_TXQA1_TEST3 0x06C4 /* Block 14 -- TX sync queue 2 */ #define SK_TXQS2_BUFCNT 0x0700 #define SK_TXQS2_BUFCTL 0x0702 #define SK_TXQS2_NEXTDESC 0x0704 #define SK_TXQS2_RXBUF_LO 0x0708 #define SK_TXQS2_RXBUF_HI 0x070C #define SK_TXQS2_RXSTAT 0x0710 #define SK_TXQS2_CSUM_STARTVAL 0x0714 #define SK_TXQS2_CSUM_STARTPOS 0x0718 #define SK_TXQS2_CSUM_WRITEPOS 0x071A #define SK_TXQS2_CURADDR_LO 0x0720 #define SK_TXQS2_CURADDR_HI 0x0724 #define SK_TXQS2_CURCNT_LO 0x0728 #define SK_TXQS2_CURCNT_HI 0x072C #define SK_TXQS2_CURBYTES 0x0730 #define SK_TXQS2_BMU_CSR 0x0734 #define SK_TXQS2_WATERMARK 0x0738 #define SK_TXQS2_FLAG 0x073A #define SK_TXQS2_TEST1 0x073C #define SK_TXQS2_TEST2 0x0740 #define SK_TXQS2_TEST3 0x0744 /* Block 15 -- TX async queue 2 */ #define SK_TXQA2_BUFCNT 0x0780 #define SK_TXQA2_BUFCTL 0x0782 #define SK_TXQA2_NEXTDESC 0x0784 #define SK_TXQA2_RXBUF_LO 0x0788 #define SK_TXQA2_RXBUF_HI 0x078C #define SK_TXQA2_RXSTAT 0x0790 #define SK_TXQA2_CSUM_STARTVAL 0x0794 #define SK_TXQA2_CSUM_STARTPOS 0x0798 #define SK_TXQA2_CSUM_WRITEPOS 0x079A #define SK_TXQA2_CURADDR_LO 0x07A0 #define SK_TXQA2_CURADDR_HI 0x07A4 #define SK_TXQA2_CURCNT_LO 0x07A8 #define SK_TXQA2_CURCNT_HI 0x07AC #define SK_TXQA2_CURBYTES 0x07B0 #define SK_TXQA2_BMU_CSR 0x07B4 #define SK_TXQA2_WATERMARK 0x07B8 #define SK_TXQA2_FLAG 0x07BA #define SK_TXQA2_TEST1 0x07BC #define SK_TXQA2_TEST2 0x07C0 #define SK_TXQA2_TEST3 0x07C4 #define SK_TXBMU_CLR_IRQ_ERR 0x00000001 #define SK_TXBMU_CLR_IRQ_EOF 0x00000002 #define SK_TXBMU_CLR_IRQ_EOB 0x00000004 #define SK_TXBMU_TX_START 0x00000010 #define SK_TXBMU_TX_STOP 0x00000020 #define SK_TXBMU_POLL_OFF 0x00000040 #define SK_TXBMU_POLL_ON 0x00000080 #define SK_TXBMU_TRANSFER_SM_RESET 0x00000100 #define SK_TXBMU_TRANSFER_SM_UNRESET 0x00000200 #define SK_TXBMU_DESCWR_SM_RESET 0x00000400 #define SK_TXBMU_DESCWR_SM_UNRESET 0x00000800 #define SK_TXBMU_DESCRD_SM_RESET 0x00001000 #define SK_TXBMU_DESCRD_SM_UNRESET 0x00002000 #define SK_TXBMU_SUPERVISOR_SM_RESET 0x00004000 #define SK_TXBMU_SUPERVISOR_SM_UNRESET 0x00008000 #define SK_TXBMU_PFI_SM_RESET 0x00010000 #define SK_TXBMU_PFI_SM_UNRESET 0x00020000 #define SK_TXBMU_FIFO_RESET 0x00040000 #define SK_TXBMU_FIFO_UNRESET 0x00080000 #define SK_TXBMU_DESC_RESET 0x00100000 #define SK_TXBMU_DESC_UNRESET 0x00200000 #define SK_TXBMU_SUPERVISOR_IDLE 0x01000000 #define SK_TXBMU_ONLINE \ (SK_TXBMU_TRANSFER_SM_UNRESET|SK_TXBMU_DESCWR_SM_UNRESET| \ SK_TXBMU_DESCRD_SM_UNRESET|SK_TXBMU_SUPERVISOR_SM_UNRESET| \ SK_TXBMU_PFI_SM_UNRESET|SK_TXBMU_FIFO_UNRESET| \ SK_TXBMU_DESC_UNRESET) #define SK_TXBMU_OFFLINE \ (SK_TXBMU_TRANSFER_SM_RESET|SK_TXBMU_DESCWR_SM_RESET| \ SK_TXBMU_DESCRD_SM_RESET|SK_TXBMU_SUPERVISOR_SM_RESET| \ SK_TXBMU_PFI_SM_RESET|SK_TXBMU_FIFO_RESET| \ SK_TXBMU_DESC_RESET) /* Block 16 -- Receive RAMbuffer 1 */ #define SK_RXRB1_START 0x0800 #define SK_RXRB1_END 0x0804 #define SK_RXRB1_WR_PTR 0x0808 #define SK_RXRB1_RD_PTR 0x080C #define SK_RXRB1_UTHR_PAUSE 0x0810 #define SK_RXRB1_LTHR_PAUSE 0x0814 #define SK_RXRB1_UTHR_HIPRIO 0x0818 #define SK_RXRB1_UTHR_LOPRIO 0x081C #define SK_RXRB1_PKTCNT 0x0820 #define SK_RXRB1_LVL 0x0824 #define SK_RXRB1_CTLTST 0x0828 /* Block 17 -- Receive RAMbuffer 2 */ #define SK_RXRB2_START 0x0880 #define SK_RXRB2_END 0x0884 #define SK_RXRB2_WR_PTR 0x0888 #define SK_RXRB2_RD_PTR 0x088C #define SK_RXRB2_UTHR_PAUSE 0x0890 #define SK_RXRB2_LTHR_PAUSE 0x0894 #define SK_RXRB2_UTHR_HIPRIO 0x0898 #define SK_RXRB2_UTHR_LOPRIO 0x089C #define SK_RXRB2_PKTCNT 0x08A0 #define SK_RXRB2_LVL 0x08A4 #define SK_RXRB2_CTLTST 0x08A8 /* Block 20 -- Sync. Transmit RAMbuffer 1 */ #define SK_TXRBS1_START 0x0A00 #define SK_TXRBS1_END 0x0A04 #define SK_TXRBS1_WR_PTR 0x0A08 #define SK_TXRBS1_RD_PTR 0x0A0C #define SK_TXRBS1_PKTCNT 0x0A20 #define SK_TXRBS1_LVL 0x0A24 #define SK_TXRBS1_CTLTST 0x0A28 /* Block 21 -- Async. Transmit RAMbuffer 1 */ #define SK_TXRBA1_START 0x0A80 #define SK_TXRBA1_END 0x0A84 #define SK_TXRBA1_WR_PTR 0x0A88 #define SK_TXRBA1_RD_PTR 0x0A8C #define SK_TXRBA1_PKTCNT 0x0AA0 #define SK_TXRBA1_LVL 0x0AA4 #define SK_TXRBA1_CTLTST 0x0AA8 /* Block 22 -- Sync. Transmit RAMbuffer 2 */ #define SK_TXRBS2_START 0x0B00 #define SK_TXRBS2_END 0x0B04 #define SK_TXRBS2_WR_PTR 0x0B08 #define SK_TXRBS2_RD_PTR 0x0B0C #define SK_TXRBS2_PKTCNT 0x0B20 #define SK_TXRBS2_LVL 0x0B24 #define SK_TXRBS2_CTLTST 0x0B28 /* Block 23 -- Async. Transmit RAMbuffer 2 */ #define SK_TXRBA2_START 0x0B80 #define SK_TXRBA2_END 0x0B84 #define SK_TXRBA2_WR_PTR 0x0B88 #define SK_TXRBA2_RD_PTR 0x0B8C #define SK_TXRBA2_PKTCNT 0x0BA0 #define SK_TXRBA2_LVL 0x0BA4 #define SK_TXRBA2_CTLTST 0x0BA8 #define SK_RBCTL_RESET 0x00000001 #define SK_RBCTL_UNRESET 0x00000002 #define SK_RBCTL_OFF 0x00000004 #define SK_RBCTL_ON 0x00000008 #define SK_RBCTL_STORENFWD_OFF 0x00000010 #define SK_RBCTL_STORENFWD_ON 0x00000020 /* Block 24 -- RX MAC FIFO 1 regisrers and LINK_SYNC counter */ #define SK_RXF1_END 0x0C00 #define SK_RXF1_WPTR 0x0C04 #define SK_RXF1_RPTR 0x0C0C #define SK_RXF1_PKTCNT 0x0C10 #define SK_RXF1_LVL 0x0C14 #define SK_RXF1_MACCTL 0x0C18 #define SK_RXF1_CTL 0x0C1C #define SK_RXLED1_CNTINIT 0x0C20 #define SK_RXLED1_COUNTER 0x0C24 #define SK_RXLED1_CTL 0x0C28 #define SK_RXLED1_TST 0x0C29 #define SK_LINK_SYNC1_CINIT 0x0C30 #define SK_LINK_SYNC1_COUNTER 0x0C34 #define SK_LINK_SYNC1_CTL 0x0C38 #define SK_LINK_SYNC1_TST 0x0C39 #define SK_LINKLED1_CTL 0x0C3C #define SK_FIFO_END 0x3F /* Block 25 -- RX MAC FIFO 2 regisrers and LINK_SYNC counter */ #define SK_RXF2_END 0x0C80 #define SK_RXF2_WPTR 0x0C84 #define SK_RXF2_RPTR 0x0C8C #define SK_RXF2_PKTCNT 0x0C90 #define SK_RXF2_LVL 0x0C94 #define SK_RXF2_MACCTL 0x0C98 #define SK_RXF2_CTL 0x0C9C #define SK_RXLED2_CNTINIT 0x0CA0 #define SK_RXLED2_COUNTER 0x0CA4 #define SK_RXLED2_CTL 0x0CA8 #define SK_RXLED2_TST 0x0CA9 #define SK_LINK_SYNC2_CINIT 0x0CB0 #define SK_LINK_SYNC2_COUNTER 0x0CB4 #define SK_LINK_SYNC2_CTL 0x0CB8 #define SK_LINK_SYNC2_TST 0x0CB9 #define SK_LINKLED2_CTL 0x0CBC #define SK_RXMACCTL_CLR_IRQ_NOSTS 0x00000001 #define SK_RXMACCTL_CLR_IRQ_NOTSTAMP 0x00000002 #define SK_RXMACCTL_TSTAMP_OFF 0x00000004 #define SK_RXMACCTL_RSTAMP_ON 0x00000008 #define SK_RXMACCTL_FLUSH_OFF 0x00000010 #define SK_RXMACCTL_FLUSH_ON 0x00000020 #define SK_RXMACCTL_PAUSE_OFF 0x00000040 #define SK_RXMACCTL_PAUSE_ON 0x00000080 #define SK_RXMACCTL_AFULL_OFF 0x00000100 #define SK_RXMACCTL_AFULL_ON 0x00000200 #define SK_RXMACCTL_VALIDTIME_PATCH_OFF 0x00000400 #define SK_RXMACCTL_VALIDTIME_PATCH_ON 0x00000800 #define SK_RXMACCTL_RXRDY_PATCH_OFF 0x00001000 #define SK_RXMACCTL_RXRDY_PATCH_ON 0x00002000 #define SK_RXMACCTL_STS_TIMEO 0x00FF0000 #define SK_RXMACCTL_TSTAMP_TIMEO 0xFF000000 #define SK_RXLEDCTL_ENABLE 0x0001 #define SK_RXLEDCTL_COUNTER_STOP 0x0002 #define SK_RXLEDCTL_COUNTER_START 0x0004 #define SK_LINKLED_OFF 0x0001 #define SK_LINKLED_ON 0x0002 #define SK_LINKLED_LINKSYNC_OFF 0x0004 #define SK_LINKLED_LINKSYNC_ON 0x0008 #define SK_LINKLED_BLINK_OFF 0x0010 #define SK_LINKLED_BLINK_ON 0x0020 /* Block 26 -- TX MAC FIFO 1 regisrers */ #define SK_TXF1_END 0x0D00 #define SK_TXF1_WPTR 0x0D04 #define SK_TXF1_RPTR 0x0D0C #define SK_TXF1_PKTCNT 0x0D10 #define SK_TXF1_LVL 0x0D14 #define SK_TXF1_MACCTL 0x0D18 #define SK_TXF1_CTL 0x0D1C #define SK_TXLED1_CNTINIT 0x0D20 #define SK_TXLED1_COUNTER 0x0D24 #define SK_TXLED1_CTL 0x0D28 #define SK_TXLED1_TST 0x0D29 /* Block 27 -- TX MAC FIFO 2 regisrers */ #define SK_TXF2_END 0x0D80 #define SK_TXF2_WPTR 0x0D84 #define SK_TXF2_RPTR 0x0D8C #define SK_TXF2_PKTCNT 0x0D90 #define SK_TXF2_LVL 0x0D94 #define SK_TXF2_MACCTL 0x0D98 #define SK_TXF2_CTL 0x0D9C #define SK_TXLED2_CNTINIT 0x0DA0 #define SK_TXLED2_COUNTER 0x0DA4 #define SK_TXLED2_CTL 0x0DA8 #define SK_TXLED2_TST 0x0DA9 #define SK_TXMACCTL_XMAC_RESET 0x00000001 #define SK_TXMACCTL_XMAC_UNRESET 0x00000002 #define SK_TXMACCTL_LOOP_OFF 0x00000004 #define SK_TXMACCTL_LOOP_ON 0x00000008 #define SK_TXMACCTL_FLUSH_OFF 0x00000010 #define SK_TXMACCTL_FLUSH_ON 0x00000020 #define SK_TXMACCTL_WAITEMPTY_OFF 0x00000040 #define SK_TXMACCTL_WAITEMPTY_ON 0x00000080 #define SK_TXMACCTL_AFULL_OFF 0x00000100 #define SK_TXMACCTL_AFULL_ON 0x00000200 #define SK_TXMACCTL_TXRDY_PATCH_OFF 0x00000400 #define SK_TXMACCTL_RXRDY_PATCH_ON 0x00000800 #define SK_TXMACCTL_PKT_RECOVERY_OFF 0x00001000 #define SK_TXMACCTL_PKT_RECOVERY_ON 0x00002000 #define SK_TXMACCTL_CLR_IRQ_PERR 0x00008000 #define SK_TXMACCTL_WAITAFTERFLUSH 0x00010000 #define SK_TXLEDCTL_ENABLE 0x0001 #define SK_TXLEDCTL_COUNTER_STOP 0x0002 #define SK_TXLEDCTL_COUNTER_START 0x0004 #define SK_FIFO_RESET 0x00000001 #define SK_FIFO_UNRESET 0x00000002 #define SK_FIFO_OFF 0x00000004 #define SK_FIFO_ON 0x00000008 /* Block 0x40 to 0x4F -- XMAC 1 registers */ #define SK_XMAC1_BASE 0x2000 #define SK_XMAC1_END 0x23FF /* Block 0x60 to 0x6F -- XMAC 2 registers */ #define SK_XMAC2_BASE 0x3000 #define SK_XMAC2_END 0x33FF /* Compute relative offset of an XMAC register in the XMAC window(s). */ #define SK_XMAC_REG(reg, mac) (((reg) * 2) + SK_XMAC1_BASE + \ (mac * (SK_XMAC2_BASE - SK_XMAC1_BASE))) #define SK_XM_READ_4(sc, reg) \ (sk_win_read_2(sc->sk_softc, \ SK_XMAC_REG(reg, sc->sk_port)) & 0xFFFF) | \ ((sk_win_read_2(sc->sk_softc, \ SK_XMAC_REG(reg + 2, sc->sk_port)) << 16) & 0xFFFF0000) #define SK_XM_WRITE_4(sc, reg, val) \ sk_win_write_2(sc->sk_softc, \ SK_XMAC_REG(reg, sc->sk_port), ((val) & 0xFFFF)); \ sk_win_write_2(sc->sk_softc, \ SK_XMAC_REG(reg + 2, sc->sk_port), ((val) >> 16) & 0xFFFF); #define SK_XM_READ_2(sc, reg) \ sk_win_read_2(sc->sk_softc, SK_XMAC_REG(reg, sc->sk_port)) #define SK_XM_WRITE_2(sc, reg, val) \ sk_win_write_2(sc->sk_softc, SK_XMAC_REG(reg, sc->sk_port), val) #define SK_XM_SETBIT_4(sc, reg, x) \ SK_XM_WRITE_4(sc, reg, (SK_XM_READ_4(sc, reg)) | (x)) #define SK_XM_CLRBIT_4(sc, reg, x) \ SK_XM_WRITE_4(sc, reg, (SK_XM_READ_4(sc, reg)) & ~(x)) #define SK_XM_SETBIT_2(sc, reg, x) \ SK_XM_WRITE_2(sc, reg, (SK_XM_READ_2(sc, reg)) | (x)) #define SK_XM_CLRBIT_2(sc, reg, x) \ SK_XM_WRITE_2(sc, reg, (SK_XM_READ_2(sc, reg)) & ~(x)) /* * The default FIFO threshold on the XMAC II is 4 bytes. On * dual port NICs, this often leads to transmit underruns, so we * bump the threshold a little. */ #define SK_XM_TX_FIFOTHRESH 512 #define SK_PCI_VENDOR_ID 0x0000 #define SK_PCI_DEVICE_ID 0x0002 #define SK_PCI_COMMAND 0x0004 #define SK_PCI_STATUS 0x0006 #define SK_PCI_REVID 0x0008 #define SK_PCI_CLASSCODE 0x0009 #define SK_PCI_CACHELEN 0x000C #define SK_PCI_LATENCY_TIMER 0x000D #define SK_PCI_HEADER_TYPE 0x000E #define SK_PCI_LOMEM 0x0010 #define SK_PCI_LOIO 0x0014 #define SK_PCI_SUBVEN_ID 0x002C #define SK_PCI_SYBSYS_ID 0x002E #define SK_PCI_BIOSROM 0x0030 #define SK_PCI_INTLINE 0x003C #define SK_PCI_INTPIN 0x003D #define SK_PCI_MINGNT 0x003E #define SK_PCI_MINLAT 0x003F /* device specific PCI registers */ #define SK_PCI_OURREG1 0x0040 #define SK_PCI_OURREG2 0x0044 #define SK_PCI_CAPID 0x0048 /* 8 bits */ #define SK_PCI_NEXTPTR 0x0049 /* 8 bits */ #define SK_PCI_PWRMGMTCAP 0x004A /* 16 bits */ #define SK_PCI_PWRMGMTCTRL 0x004C /* 16 bits */ #define SK_PCI_PME_EVENT 0x004F #define SK_PCI_VPD_CAPID 0x0050 #define SK_PCI_VPD_NEXTPTR 0x0051 #define SK_PCI_VPD_ADDR 0x0052 #define SK_PCI_VPD_DATA 0x0054 #define SK_PSTATE_MASK 0x0003 #define SK_PSTATE_D0 0x0000 #define SK_PSTATE_D1 0x0001 #define SK_PSTATE_D2 0x0002 #define SK_PSTATE_D3 0x0003 #define SK_PME_EN 0x0010 #define SK_PME_STATUS 0x8000 /* * VPD flag bit. Set to 0 to initiate a read, will become 1 when * read is complete. Set to 1 to initiate a write, will become 0 * when write is finished. */ #define SK_VPD_FLAG 0x8000 /* VPD structures */ struct vpd_res { u_int8_t vr_id; u_int8_t vr_len; u_int8_t vr_pad; }; struct vpd_key { char vk_key[2]; u_int8_t vk_len; }; #define VPD_RES_ID 0x82 /* ID string */ #define VPD_RES_READ 0x90 /* start of read only area */ #define VPD_RES_WRITE 0x81 /* start of read/write area */ #define VPD_RES_END 0x78 /* end tag */ #define CSR_WRITE_4(sc, reg, val) \ bus_space_write_4(sc->sk_btag, sc->sk_bhandle, reg, val) #define CSR_WRITE_2(sc, reg, val) \ bus_space_write_2(sc->sk_btag, sc->sk_bhandle, reg, val) #define CSR_WRITE_1(sc, reg, val) \ bus_space_write_1(sc->sk_btag, sc->sk_bhandle, reg, val) #define CSR_READ_4(sc, reg) \ bus_space_read_4(sc->sk_btag, sc->sk_bhandle, reg) #define CSR_READ_2(sc, reg) \ bus_space_read_2(sc->sk_btag, sc->sk_bhandle, reg) #define CSR_READ_1(sc, reg) \ bus_space_read_1(sc->sk_btag, sc->sk_bhandle, reg) struct sk_type { u_int16_t sk_vid; u_int16_t sk_did; char *sk_name; }; /* RX queue descriptor data structure */ struct sk_rx_desc { u_int32_t sk_ctl; u_int32_t sk_next; u_int32_t sk_data_lo; u_int32_t sk_data_hi; u_int32_t sk_xmac_rxstat; u_int32_t sk_timestamp; u_int16_t sk_csum2; u_int16_t sk_csum1; u_int16_t sk_csum2_start; u_int16_t sk_csum1_start; }; #define SK_OPCODE_DEFAULT 0x00550000 #define SK_OPCODE_CSUM 0x00560000 #define SK_RXCTL_LEN 0x0000FFFF #define SK_RXCTL_OPCODE 0x00FF0000 #define SK_RXCTL_TSTAMP_VALID 0x01000000 #define SK_RXCTL_STATUS_VALID 0x02000000 #define SK_RXCTL_DEV0 0x04000000 #define SK_RXCTL_EOF_INTR 0x08000000 #define SK_RXCTL_EOB_INTR 0x10000000 #define SK_RXCTL_LASTFRAG 0x20000000 #define SK_RXCTL_FIRSTFRAG 0x40000000 #define SK_RXCTL_OWN 0x80000000 #define SK_RXSTAT \ (SK_OPCODE_DEFAULT|SK_RXCTL_EOF_INTR|SK_RXCTL_LASTFRAG| \ SK_RXCTL_FIRSTFRAG|SK_RXCTL_OWN) struct sk_tx_desc { u_int32_t sk_ctl; u_int32_t sk_next; u_int32_t sk_data_lo; u_int32_t sk_data_hi; u_int32_t sk_xmac_txstat; u_int16_t sk_rsvd0; u_int16_t sk_csum_startval; u_int16_t sk_csum_startpos; u_int16_t sk_csum_writepos; u_int32_t sk_rsvd1; }; #define SK_TXCTL_LEN 0x0000FFFF #define SK_TXCTL_OPCODE 0x00FF0000 #define SK_TXCTL_SW 0x01000000 #define SK_TXCTL_NOCRC 0x02000000 #define SK_TXCTL_STORENFWD 0x04000000 #define SK_TXCTL_EOF_INTR 0x08000000 #define SK_TXCTL_EOB_INTR 0x10000000 #define SK_TXCTL_LASTFRAG 0x20000000 #define SK_TXCTL_FIRSTFRAG 0x40000000 #define SK_TXCTL_OWN 0x80000000 #define SK_TXSTAT \ (SK_OPCODE_DEFAULT|SK_TXCTL_EOF_INTR|SK_TXCTL_LASTFRAG|SK_TXCTL_OWN) #define SK_RXBYTES(x) (x) & 0x0000FFFF; #define SK_TXBYTES SK_RXBYTES #define SK_TX_RING_CNT 512 #define SK_RX_RING_CNT 256 /* * Jumbo buffer stuff. Note that we must allocate more jumbo * buffers than there are descriptors in the receive ring. This * is because we don't know how long it will take for a packet * to be released after we hand it off to the upper protocol * layers. To be safe, we allocate 1.5 times the number of * receive descriptors. */ #define SK_JUMBO_FRAMELEN 9018 #define SK_JUMBO_MTU (SK_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN) #define SK_JSLOTS 384 #define SK_JRAWLEN (SK_JUMBO_FRAMELEN + ETHER_ALIGN + sizeof(u_int64_t)) #define SK_JLEN (SK_JRAWLEN + (sizeof(u_int64_t) - \ (SK_JRAWLEN % sizeof(u_int64_t)))) #define SK_MCLBYTES (SK_JLEN - sizeof(u_int64_t)) #define SK_JPAGESZ PAGE_SIZE #define SK_RESID (SK_JPAGESZ - (SK_JLEN * SK_JSLOTS) % SK_JPAGESZ) #define SK_JMEM ((SK_JLEN * SK_JSLOTS) + SK_RESID) struct sk_jslot { caddr_t sk_buf; int sk_inuse; }; struct sk_jpool_entry { int slot; SLIST_ENTRY(sk_jpool_entry) jpool_entries; }; struct sk_chain { void *sk_desc; struct mbuf *sk_mbuf; struct sk_chain *sk_next; }; struct sk_chain_data { struct sk_chain sk_tx_chain[SK_TX_RING_CNT]; struct sk_chain sk_rx_chain[SK_RX_RING_CNT]; int sk_tx_prod; int sk_tx_cons; int sk_tx_cnt; int sk_rx_prod; int sk_rx_cons; int sk_rx_cnt; /* Stick the jumbo mem management stuff here too. */ struct sk_jslot sk_jslots[SK_JSLOTS]; void *sk_jumbo_buf; }; struct sk_ring_data { struct sk_tx_desc sk_tx_ring[SK_TX_RING_CNT]; struct sk_rx_desc sk_rx_ring[SK_RX_RING_CNT]; }; #define SK_INC(x, y) (x) = (x + 1) % y /* Forward decl. */ struct sk_if_softc; /* Softc for the GEnesis controller. */ struct sk_softc { bus_space_handle_t sk_bhandle; /* bus space handle */ bus_space_tag_t sk_btag; /* bus space tag */ - void *sk_intrhand; /* irq handler handle */ - struct resource *sk_irq; /* IRQ resource handle */ - struct resource *sk_res; /* I/O or shared mem handle */ u_int8_t sk_unit; /* controller number */ u_int8_t sk_type; char *sk_vpd_prodname; char *sk_vpd_readonly; u_int32_t sk_rboff; /* RAMbuffer offset */ u_int32_t sk_ramsize; /* amount of RAM on NIC */ u_int32_t sk_pmd; /* physical media type */ u_int32_t sk_intrmask; struct sk_if_softc *sk_if[2]; }; /* Softc for each logical interface */ struct sk_if_softc { struct arpcom arpcom; /* interface info */ struct ifmedia ifmedia; /* media info */ u_int8_t sk_unit; /* interface number */ u_int8_t sk_port; /* port # on controller */ u_int8_t sk_xmac_rev; /* XMAC chip rev (B2 or C1) */ u_int8_t sk_link; u_int32_t sk_rx_ramstart; u_int32_t sk_rx_ramend; u_int32_t sk_tx_ramstart; u_int32_t sk_tx_ramend; struct sk_chain_data sk_cdata; struct sk_ring_data *sk_rdata; struct sk_softc *sk_softc; /* parent controller */ int sk_tx_bmu; /* TX BMU register */ int sk_if_flags; SLIST_HEAD(__sk_jfreehead, sk_jpool_entry) sk_jfree_listhead; SLIST_HEAD(__sk_jinusehead, sk_jpool_entry) sk_jinuse_listhead; }; #define SK_TIMEOUT 1000 #define ETHER_ALIGN 2 #ifdef __alpha__ #undef vtophys -#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) +#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \ + + 1*1024*1024*1024) #endif