From owner-freebsd-bugs Tue Aug 1 5:40:28 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 8BC1C37BBCA for ; Tue, 1 Aug 2000 05:40:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id FAA13006; Tue, 1 Aug 2000 05:40:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from hanoi.cronyx.ru (hanoi.cronyx.ru [144.206.181.53]) by hub.freebsd.org (Postfix) with ESMTP id 81FA137B692 for ; Tue, 1 Aug 2000 05:32:51 -0700 (PDT) (envelope-from root@crox.cronyx.ru) Received: from crox.cronyx.ru by hanoi.cronyx.ru with ESMTP id QAA02219; (8.9.3/vak/2.1) Tue, 1 Aug 2000 16:37:04 +0400 (MSD) Received: by crox.cronyx.ru id QAA00323; (8.9.3/vak/2.1) Tue, 1 Aug 2000 16:26:01 +0400 (MSD) Message-Id: <200008011226.QAA00323@crox.cronyx.ru> Date: Tue, 1 Aug 2000 16:26:01 +0400 (MSD) From: vak@cronyx.ru To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/20341: [patch] sio driver, support for PCI multiport cards Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 20341 >Category: kern >Synopsis: Support for PCI multiport cards for sio driver >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Aug 01 05:40:01 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Serge Vakulenko >Release: FreeBSD 4.0-RELEASE i386 >Organization: Cronyx Engineering Ltd. >Environment: FreeBSD 4.0, Cronyx-Omega-PCI serial multiport adapters. >Description: To handle non-intelligent multiport async adapters, the sio driver lacks the PCI detection and attachment routines. Some rearrangment of the sio.c is also required. The patch consists of four parts: 1) sys/isa/siovar.h (new file) 2) sys/isa/sio.c (patch) 3) sys/pci/sio_pci.c (new file) 4) sys/conf/files.i386 (patch) >How-To-Repeat: >Fix: --- siovar40.h Thu Jul 27 11:46:05 2000 +++ isa/siovar.h Fri Jul 28 14:01:20 2000 @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 1991 The Regents of the University of California. + * 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 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. + * + * $FreeBSD: src/sys/isa/sio.c,v 1.291 2000/03/11 20:22:09 imp Exp $ + * from: @(#)com.c 7.5 (Berkeley) 5/16/91 + * from: i386/isa sio.c,v 1.234 + */ +#define SIO_MAXUNITS 64 /* max sio ports */ +#define CE_NTYPES 3 + +/* types. XXX - should be elsewhere */ +typedef u_int Port_t; /* hardware port */ +typedef u_char bool_t; /* boolean */ + +/* queue of linear buffers */ +struct lbq { + u_char *l_head; /* next char to process */ + u_char *l_tail; /* one past the last char to process */ + struct lbq *l_next; /* next in queue */ + bool_t l_queued; /* nonzero if queued */ +}; + +/* com device structure */ +struct com_s { + u_int flags; /* Copy isa device flags */ + u_char state; /* miscellaneous flag bits */ + bool_t active_out; /* nonzero if the callout device is open */ + u_char cfcr_image; /* copy of value written to CFCR */ +#ifdef COM_ESP + bool_t esp; /* is this unit a hayes esp board? */ +#endif + u_char extra_state; /* more flag bits, separate for order trick */ + u_char fifo_image; /* copy of value written to FIFO */ + bool_t hasfifo; /* nonzero for 16550 UARTs */ + bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */ + bool_t loses_outints; /* nonzero if device loses output interrupts */ + u_char mcr_image; /* copy of value written to MCR */ +#ifdef COM_MULTIPORT + bool_t multiport; /* is this unit part of a multiport device? */ +#endif /* COM_MULTIPORT */ + bool_t no_irq; /* nonzero if irq is not attached */ + bool_t gone; /* hardware disappeared */ + bool_t poll; /* nonzero if polling is required */ + bool_t poll_output; /* nonzero if polling for output is required */ + int unit; /* unit number */ + int dtr_wait; /* time to hold DTR down on close (* 1/hz) */ + u_int tx_fifo_size; + u_int wopeners; /* # processes waiting for DCD in open() */ + + /* + * The high level of the driver never reads status registers directly + * because there would be too many side effects to handle conveniently. + * Instead, it reads copies of the registers stored here by the + * interrupt handler. + */ + u_char last_modem_status; /* last MSR read by intr handler */ + u_char prev_modem_status; /* last MSR handled by high level */ + + u_char hotchar; /* ldisc-specific char to be handled ASAP */ + u_char *ibuf; /* start of input buffer */ + u_char *ibufend; /* end of input buffer */ + u_char *ibufold; /* old input buffer, to be freed */ + u_char *ihighwater; /* threshold in input buffer */ + u_char *iptr; /* next free spot in input buffer */ + int ibufsize; /* size of ibuf (not include error bytes) */ + int ierroff; /* offset of error bytes in ibuf */ + + struct lbq obufq; /* head of queue of output buffers */ + struct lbq obufs[2]; /* output buffers */ + + Port_t data_port; /* i/o ports */ +#ifdef COM_ESP + Port_t esp_port; +#endif + Port_t int_id_port; + Port_t iobase; + Port_t modem_ctl_port; + Port_t line_status_port; + Port_t modem_status_port; + Port_t intr_ctl_port; /* Ports of IIR register */ + + struct tty *tp; /* cross reference */ + + /* Initial state. */ + struct termios it_in; /* should be in struct tty */ + struct termios it_out; + + /* Lock state. */ + struct termios lt_in; /* should be in struct tty */ + struct termios lt_out; + + bool_t do_timestamp; + bool_t do_dcd_timestamp; + struct timeval timestamp; + struct timeval dcd_timestamp; + struct pps_state pps; + + u_long bytes_in; /* statistics */ + u_long bytes_out; + u_int delta_error_counts[CE_NTYPES]; + u_long error_counts[CE_NTYPES]; + + struct resource *irqres; + struct resource *ioportres; + void *cookie; + + /* + * Data area for output buffers. Someday we should build the output + * buffer queue without copying data. + */ + u_char obuf1[256]; + u_char obuf2[256]; +}; + +int sio_attach_unit (struct com_s *com, int unit, Port_t iobase, + u_int flags, bool_t no_irq); +void siointr1 (struct com_s *com); 1) Move the struct com_s definition to separate file siovar.h. 2) Split the sioattach() routine. Leave the isa-dependent part in sioattach(), and build the (public) bus-independent attachment function sio_attach_unit(). 3) Make siointr1 public. --- sio40.c Wed Jul 26 17:32:07 2000 +++ isa/sio.c Fri Jul 28 14:01:54 2000 @@ -82,6 +82,7 @@ #include #include +#include #ifdef COM_ESP #include @@ -167,113 +168,8 @@ "tty-level buffer overflow", }; -#define CE_NTYPES 3 #define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum]) -/* types. XXX - should be elsewhere */ -typedef u_int Port_t; /* hardware port */ -typedef u_char bool_t; /* boolean */ - -/* queue of linear buffers */ -struct lbq { - u_char *l_head; /* next char to process */ - u_char *l_tail; /* one past the last char to process */ - struct lbq *l_next; /* next in queue */ - bool_t l_queued; /* nonzero if queued */ -}; - -/* com device structure */ -struct com_s { - u_int flags; /* Copy isa device flags */ - u_char state; /* miscellaneous flag bits */ - bool_t active_out; /* nonzero if the callout device is open */ - u_char cfcr_image; /* copy of value written to CFCR */ -#ifdef COM_ESP - bool_t esp; /* is this unit a hayes esp board? */ -#endif - u_char extra_state; /* more flag bits, separate for order trick */ - u_char fifo_image; /* copy of value written to FIFO */ - bool_t hasfifo; /* nonzero for 16550 UARTs */ - bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */ - bool_t loses_outints; /* nonzero if device loses output interrupts */ - u_char mcr_image; /* copy of value written to MCR */ -#ifdef COM_MULTIPORT - bool_t multiport; /* is this unit part of a multiport device? */ -#endif /* COM_MULTIPORT */ - bool_t no_irq; /* nonzero if irq is not attached */ - bool_t gone; /* hardware disappeared */ - bool_t poll; /* nonzero if polling is required */ - bool_t poll_output; /* nonzero if polling for output is required */ - int unit; /* unit number */ - int dtr_wait; /* time to hold DTR down on close (* 1/hz) */ - u_int tx_fifo_size; - u_int wopeners; /* # processes waiting for DCD in open() */ - - /* - * The high level of the driver never reads status registers directly - * because there would be too many side effects to handle conveniently. - * Instead, it reads copies of the registers stored here by the - * interrupt handler. - */ - u_char last_modem_status; /* last MSR read by intr handler */ - u_char prev_modem_status; /* last MSR handled by high level */ - - u_char hotchar; /* ldisc-specific char to be handled ASAP */ - u_char *ibuf; /* start of input buffer */ - u_char *ibufend; /* end of input buffer */ - u_char *ibufold; /* old input buffer, to be freed */ - u_char *ihighwater; /* threshold in input buffer */ - u_char *iptr; /* next free spot in input buffer */ - int ibufsize; /* size of ibuf (not include error bytes) */ - int ierroff; /* offset of error bytes in ibuf */ - - struct lbq obufq; /* head of queue of output buffers */ - struct lbq obufs[2]; /* output buffers */ - - Port_t data_port; /* i/o ports */ -#ifdef COM_ESP - Port_t esp_port; -#endif - Port_t int_id_port; - Port_t iobase; - Port_t modem_ctl_port; - Port_t line_status_port; - Port_t modem_status_port; - Port_t intr_ctl_port; /* Ports of IIR register */ - - struct tty *tp; /* cross reference */ - - /* Initial state. */ - struct termios it_in; /* should be in struct tty */ - struct termios it_out; - - /* Lock state. */ - struct termios lt_in; /* should be in struct tty */ - struct termios lt_out; - - bool_t do_timestamp; - bool_t do_dcd_timestamp; - struct timeval timestamp; - struct timeval dcd_timestamp; - struct pps_state pps; - - u_long bytes_in; /* statistics */ - u_long bytes_out; - u_int delta_error_counts[CE_NTYPES]; - u_long error_counts[CE_NTYPES]; - - struct resource *irqres; - struct resource *ioportres; - void *cookie; - - /* - * Data area for output buffers. Someday we should build the output - * buffer queue without copying data. - */ - u_char obuf1[256]; - u_char obuf2[256]; -}; - #ifdef COM_ESP static int espattach __P((struct com_s *com, Port_t esp_port)); #endif @@ -284,7 +180,6 @@ static timeout_t siodtrwakeup; static void comhardclose __P((struct com_s *com)); static void sioinput __P((struct com_s *com)); -static void siointr1 __P((struct com_s *com)); static void siointr __P((void *arg)); static int commctl __P((struct com_s *com, int bits, int how)); static int comparam __P((struct tty *tp, struct termios *t)); @@ -309,8 +204,8 @@ /* table and macro for fast conversion from a unit number to its com struct */ static devclass_t sio_devclass; -#define com_addr(unit) ((struct com_s *) \ - devclass_get_softc(sio_devclass, unit)) +static struct com_s *p_com_addr[SIO_MAXUNITS]; +#define com_addr(unit) (p_com_addr[unit]) static device_method_t sio_isa_methods[] = { /* Device interface */ @@ -969,32 +864,19 @@ return (sioattach(dev)); } -static int -sioattach(dev) - device_t dev; -{ +int +sio_attach_unit(com, unit, iobase, flags, no_irq) struct com_s *com; + int unit; + Port_t iobase; + u_int flags; + bool_t no_irq; +{ #ifdef COM_ESP Port_t *espp; #endif - Port_t iobase; - int unit; - u_int flags; - int rid; - struct resource *port; - int ret; - - rid = 0; - port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, IO_COMSIZE, RF_ACTIVE); - if (!port) - return (ENXIO); - - iobase = rman_get_start(port); - unit = device_get_unit(dev); - com = device_get_softc(dev); - flags = device_get_flags(dev); - + if (unit >= SIO_MAXUNITS) + return ENXIO; if (unit >= sio_numunits) sio_numunits = unit + 1; /* @@ -1011,11 +893,10 @@ */ bzero(com, sizeof *com); com->unit = unit; - com->ioportres = port; com->cfcr_image = CFCR_8BITS; com->dtr_wait = 3 * hz; com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; + com->no_irq = no_irq; com->tx_fifo_size = 1; com->obufs[0].l_head = com->obuf1; com->obufs[1].l_head = com->obuf2; @@ -1052,12 +933,6 @@ com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; if (siosetwater(com, com->it_in.c_ispeed) != 0) { enable_intr(); - /* - * Leave i/o resources allocated if this is a `cn'-level - * console, so that other devices can't snarf them. - */ - if (iobase != siocniobase) - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); return (ENOMEM); } enable_intr(); @@ -1164,17 +1039,11 @@ #ifdef COM_MULTIPORT if (COM_ISMULTIPORT(flags)) { - device_t masterdev; - com->multiport = TRUE; printf(" (multiport"); if (unit == COM_MPMASTER(flags)) printf(" master"); printf(")"); - masterdev = devclass_get_device(sio_devclass, - COM_MPMASTER(flags)); - com->no_irq = (masterdev == NULL || bus_get_resource(masterdev, - SYS_RES_IRQ, 0, NULL, NULL) != 0); } #endif /* COM_MULTIPORT */ if (unit == comconsole) @@ -1183,6 +1052,8 @@ printf(" with a bogus IIR_TXRDY register"); printf("\n"); + com_addr(unit) = com; + if (!sio_registered) { register_swi(SWI_TTY, siopoll); sio_registered = TRUE; @@ -1203,6 +1074,50 @@ com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&com->pps); + return (0); +} + +static int +sioattach(dev) + device_t dev; +{ + int rid, ret, no_irq; + struct resource *port; + struct com_s *com; + Port_t iobase; + u_int flags; + + rid = 0; + port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0, ~0, IO_COMSIZE, RF_ACTIVE); + if (!port) + return (ENXIO); + + iobase = rman_get_start(port); + com = device_get_softc(dev); + flags = device_get_flags(dev); + +#ifdef COM_MULTIPORT + if (COM_ISMULTIPORT(flags)) { + device_t masterdev; + + masterdev = devclass_get_device(sio_devclass, + COM_MPMASTER(flags)); + no_irq = (masterdev == NULL || bus_get_resource(masterdev, + SYS_RES_IRQ, 0, NULL, NULL) != 0); + } else +#endif /* COM_MULTIPORT */ + no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; + + ret = sio_attach_unit(com, device_get_unit(dev), iobase, flags, no_irq); + if (ret != 0) { + /* Leave i/o resources allocated if this is a `cn'-level + * console, so that other devices can't snarf them. */ + if (iobase != siocniobase) + bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + return ret; + } + rid = 0; com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_ACTIVE); @@ -1220,8 +1135,8 @@ if (ret) device_printf(dev, "could not activate interrupt\n"); } - - return (0); + com->ioportres = port; + return 0; } static int @@ -1713,7 +1628,7 @@ #endif /* COM_MULTIPORT */ } -static void +void siointr1(com) struct com_s *com; { --- /dev/null Tue Aug 1 10:55:27 2000 +++ pci/sio_pci.c Tue Aug 1 11:38:12 2000 @@ -0,0 +1,277 @@ +/* + * Serial driver for non-intelligent PCI multiport adapters. + * Implements the probe, attach and interrupt dispatcher, + * and uses sio.c for the most part of work. + * The PCI ports get unit numbers _after_ the ISA sio ports. + * Option COM_MULTIPORT is not necessary. + * + * Copyright (C) 2000 Cronyx Engineering Ltd. + * Author: Serge Vakulenko + * + * Supports: + * Cronyx Omega-PCI adapter, by Serge Vakulenko + * + * This software is distributed with NO WARRANTIES, not even the implied + * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Authors grant any other persons or organisations permission to use + * or modify this software as long as this message is kept with the software, + * all derivative works or modified versions. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef SMP +#include +#endif +#include +#include +#include +#include +#if __FreeBSD_version >= 400000 +#include +#include +#else +#include +#include +#include +#include +#endif +#include + +#include "sio.h" + +#define MAXCHAN 8 + +#ifndef __i386__ +#define disable_intr() +#define enable_intr() +#endif + +#ifdef SMP +#define disable_intr() COM_DISABLE_INTR() +#define enable_intr() COM_ENABLE_INTR() +#endif /* SMP */ + +typedef struct _sio_pci_t { + int nchan; + int fifo_size; + int base_reg; + int hw_rts_cts; + Port_t iobase; + Port_t iostep; + struct resource *res; + struct resource *irq; + void *intrhand; + struct com_s com [MAXCHAN]; +} sio_pci_t; + +static void sio_pci_intr __P((void *arg)); + +static int sio_pci_numunits = NSIO; + +#if __FreeBSD_version >= 400000 +/* + * FreeBSD version 4.x + */ +static int sio_pci_probe __P((device_t)); +static int sio_pci_attach __P((device_t)); + +static devclass_t siopci_devclass; + +static device_method_t sio_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sio_pci_probe), + DEVMETHOD(device_attach, sio_pci_attach), + { 0, 0 } +}; + +static driver_t sio_pci_driver = { + "siopci", + sio_pci_methods, + sizeof(sio_pci_t) +}; +DRIVER_MODULE(sio_pci, pci, sio_pci_driver, siopci_devclass, 0, 0); + +#else +/* + * FreeBSD version 3.x + */ +static const char *sio_pci_probe __P((pcici_t, pcidi_t)); +static void sio_pci_attach __P((pcici_t, int)); + +static u_long sio_pci_count; + +static struct pci_device sio_pci_device = { + "siopci", + sio_pci_probe, + sio_pci_attach, + &sio_pci_count, + NULL +}; +DATA_SET(pcidevice_set, sio_pci_device); + +#endif /* __FreeBSD_version >= 400000 */ + +#if __FreeBSD_version >= 400000 +static int +sio_pci_probe(dev) + device_t dev; +{ + u_long device_id = pci_get_vendor(dev) | pci_get_device(dev) << 16; +#else +static const char * +sio_pci_probe(config_id, device_id) + pcici_t config_id; + pcidi_t device_id; +{ +#endif + const char *desc = 0; + + if (device_id == 0xc00110b5) + desc = "Cronyx-Omega-PCI Serial Adapter"; +#ifdef notyet + /* Add your device here. */ + else if (device_id == 0xXXXXXXXX) + desc = "XXX"; +#endif + +#if __FreeBSD_version >= 400000 + if (! desc) + return ENXIO; + device_set_desc(dev, desc); + return 0; +#else + return desc; +#endif +} + +#if __FreeBSD_version >= 400000 +static int +sio_pci_attach(dev) + device_t dev; +{ + u_long device_id = pci_get_vendor(dev) | + pci_get_device(dev) << 16; + sio_pci_t *d = device_get_softc(dev); + int rid; +#define PCI_READ_CONFIG(reg) pci_read_config(dev, reg, 4) +#else +static void +sio_pci_attach(config_id, unit) + pcici_t config_id; + int unit; +{ + u_long device_id = config_id->vendor | config_id->device << 16; + sio_pci_t *d = malloc(sizeof *d, M_DEVBUF, M_WAITOK); +#define PCI_READ_CONFIG(reg) pci_conf_read(config_id, reg) +#endif + struct com_s *com; + int s, err = 0; + + bzero((char*)d, sizeof(*d)); + s = splimp(); + + /* Default values. */ + d->nchan = 8; /* channels per adapter */ + d->iostep = 8; /* addresses per channel */ + d->base_reg = 0x18; /* pci register: base addr2 */ + + /* Device dependent values. */ + if (device_id == 0xc00110b5) { + d->fifo_size = 64; /* fifo size in bytes */ + d->hw_rts_cts = 1; /* hardware rts/cts support */ + } +#ifdef notyet + else if (device_id == 0xXXXXXXXX) { + /* Add your device here. */ + } +#endif + +#if __FreeBSD_version >= 400000 + /* Allocate i/o region. */ + rid = d->base_reg; + d->res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, + RF_ACTIVE); + if (! d->res) { + printf("sio%d: couldn't map ports/memory\n", sio_pci_numunits); + err = ENXIO; + goto fail; + } + + /* Allocate interrupt. */ + rid = 0; + d->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (! d->irq) { + printf("sio%d: couldn't map interrupt\n", sio_pci_numunits); + err = ENXIO; + goto fail; + } + + /* Register the interrupt handler. */ + err = bus_setup_intr(dev, d->irq, INTR_TYPE_TTY | INTR_TYPE_FAST, + sio_pci_intr, d, &d->intrhand); +#else + err = ! pci_map_int_right(config_id, sio_pci_intr, d, &tty_imask, + INTR_FAST); +#endif + if (err) { + printf("sio%d: couldn't set up irq\n", sio_pci_numunits); +#if __FreeBSD_version >= 400000 +fail: if (d->res) + bus_release_resource(dev, SYS_RES_IOPORT, + d->base_reg, d->res); + if (d->irq) + bus_release_resource(dev, SYS_RES_IRQ, 0, d->irq); +#endif + goto done; + } + + /* Attach sio ports. */ + d->iobase = PCI_READ_CONFIG (d->base_reg) & ~3; + for (com=d->com; comcom+d->nchan; ++com) { + com->iobase = d->iobase + (com - d->com) * d->iostep; + + /* Interrupt enable, do it _before_ sio_attach_unit. */ + outb(com->iobase + com_mcr, MCR_IENABLE); + + if (sio_attach_unit(com, sio_pci_numunits++, com->iobase, + d->fifo_size << 24, 0) != 0) + printf("sio%d: cannot attach\n", sio_pci_numunits); + + /* Must do this _after_ sio_attach_unit. */ + com->st16650a = d->hw_rts_cts; + } +done: + splx (s); +#if __FreeBSD_version >= 400000 + return err; +#endif +} + +static void +sio_pci_intr(arg) + void *arg; +{ + sio_pci_t *d = arg; + struct com_s *com; + bool_t possibly_more_intrs; + + disable_intr(); + do { + possibly_more_intrs = FALSE; + for (com=d->com; comcom+d->nchan; ++com) { + if ((inb(com->int_id_port) & IIR_IMASK) != IIR_NOPEND) { + siointr1(com); + possibly_more_intrs = TRUE; + } + } + } while (possibly_more_intrs); + enable_intr(); +} --- files40.i386 Fri Jul 28 17:11:26 2000 +++ conf/files.i386 Fri Jul 28 17:12:17 2000 @@ -389,6 +389,7 @@ isa/ppc.c optional ppc isa/psm.c optional psm isa/sio.c optional sio +pci/sio_pci.c optional sio pci isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/subr_diskmbr.c standard >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message