FreeBSD Bugzilla – Attachment 10070 Details for
Bug 20338
Support for PCI multiport cards for sio driver
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 6.65 KB, created by
vak
on 2000-08-01 09:20:03 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
vak
Created:
2000-08-01 09:20:03 UTC
Size:
6.65 KB
patch
obsolete
>--- /dev/null Tue Aug 1 10:55:27 2000 >+++ 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 <vak@cronyx.ru> >+ * >+ * Supports: >+ * Cronyx Omega-PCI adapter, by Serge Vakulenko <vak@cronyx.ru> >+ * >+ * 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 <sys/param.h> >+#include <sys/systm.h> >+#include <sys/kernel.h> >+#include <sys/timepps.h> >+#include <sys/tty.h> >+#include <vm/vm.h> >+#include <vm/pmap.h> >+#include <machine/bus.h> >+#ifndef SMP >+#include <machine/lock.h> >+#endif >+#include <machine/resource.h> >+#include <sys/bus.h> >+#include <sys/rman.h> >+#include <pci/pcivar.h> >+#if __FreeBSD_version >= 400000 >+#include <isa/siovar.h> >+#include <isa/sioreg.h> >+#else >+#include <sys/malloc.h> >+#include <sys/interrupt.h> >+#include <i386/isa/siovar.h> >+#include <i386/isa/sioreg.h> >+#endif >+#include <isa/ic/ns16550.h> >+ >+#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; com<d->com+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; com<d->com+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(); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 20338
: 10070