From owner-freebsd-drivers@FreeBSD.ORG Wed Feb 27 22:14:51 2013 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id EC36721D for ; Wed, 27 Feb 2013 22:14:51 +0000 (UTC) (envelope-from star_one_2k@hotmail.com) Received: from blu0-omc1-s18.blu0.hotmail.com (blu0-omc1-s18.blu0.hotmail.com [65.55.116.29]) by mx1.freebsd.org (Postfix) with ESMTP id B30BD676 for ; Wed, 27 Feb 2013 22:14:51 +0000 (UTC) Received: from BLU167-W49 ([65.55.116.8]) by blu0-omc1-s18.blu0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 27 Feb 2013 14:14:45 -0800 X-EIP: [23b7mAnybHggKggyLxh+8gzYxGwd5Iwk] X-Originating-Email: [star_one_2k@hotmail.com] Message-ID: From: david hodges To: , Subject: ISA device driver and IRQs Date: Wed, 27 Feb 2013 22:14:45 +0000 Importance: Normal In-Reply-To: <033249A9-9C77-426F-BCA2-3A22CC4F9391@cyclaero.com> References: , <033249A9-9C77-426F-BCA2-3A22CC4F9391@cyclaero.com> MIME-Version: 1.0 X-OriginalArrivalTime: 27 Feb 2013 22:14:45.0552 (UTC) FILETIME=[D96D3300:01CE1537] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Feb 2013 22:14:52 -0000 I need to write a simple device driver for the ISA bus that uses one IRQ an= d a few reads and writes to I/O Ports 0x300 +. I don't know even where to s= tart with FreeBSD. I've done drivers before in other OS systems and have a = book for Linux but FreeBSD seems MUCH differnt. Are there any examples I ca= n get? I thought about modifying the serial driver but I'm not een sure if= that's a good idea. Any help would be great. ThanksDave = From owner-freebsd-drivers@FreeBSD.ORG Wed Feb 27 22:17:48 2013 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3E175468 for ; Wed, 27 Feb 2013 22:17:48 +0000 (UTC) (envelope-from star-one@tx.rr.com) Received: from cdptpa-omtalb.mail.rr.com (cdptpa-omtalb.mail.rr.com [75.180.132.120]) by mx1.freebsd.org (Postfix) with ESMTP id 03FB16AF for ; Wed, 27 Feb 2013 22:17:47 +0000 (UTC) Authentication-Results: cdptpa-omtalb.mail.rr.com smtp.user=star-one@tx.rr.com; auth=pass (LOGIN) X-Authority-Analysis: v=2.0 cv=cYNQXw/M c=1 sm=0 a=05ChyHeVI94A:10 a=IkcTkHD0fZMA:10 a=ayC55rCoAAAA:8 a=JB2LoAwMthoA:10 a=DcQT9IBcLh-TVIZ_8DsA:9 a=QEXdDO2ut3YA:10 a=CQF4i00vSUz2ObnoQb8mdg==:117 X-Cloudmark-Score: 0 X-Authenticated-User: star-one@tx.rr.com Received: from [10.127.132.177] ([10.127.132.177:33371] helo=cdptpa-web26-z02) by cdptpa-oedge03.mail.rr.com (envelope-from ) (ecelerity 2.2.3.46 r()) with ESMTPA id 6E/A6-11869-9C58E215; Wed, 27 Feb 2013 22:16:41 +0000 Message-ID: <20130227221641.B3CSW.38128.root@cdptpa-web26-z02> Date: Wed, 27 Feb 2013 17:16:41 -0500 From: To: freebsd-drivers@freebsd.org Subject: ISA driver for IRQ and PortIO MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) Sensitivity: Normal X-Originating-IP: X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Feb 2013 22:17:48 -0000 I need to write a simple device driver for the ISA bus that uses one IRQ and a few reads and writes to I/O Ports 0x300 +. I don't know even where to start with FreeBSD. I've done drivers before in other OS systems and have a book for Linux but FreeBSD seems MUCH differnt. Are there any examples I can get? I thought about modifying the serial driver but I'm not een sure if that's a good idea. Any help would be great. Thanks Dave From owner-freebsd-drivers@FreeBSD.ORG Thu Feb 28 17:09:51 2013 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id DD685C09 for ; Thu, 28 Feb 2013 17:09:51 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id B5CEB27A for ; Thu, 28 Feb 2013 17:09:51 +0000 (UTC) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 1C8DFB9A4; Thu, 28 Feb 2013 12:09:51 -0500 (EST) From: John Baldwin To: freebsd-drivers@freebsd.org Subject: Re: ISA driver for IRQ and PortIO Date: Thu, 28 Feb 2013 10:39:41 -0500 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p25; KDE/4.5.5; amd64; ; ) References: <20130227221641.B3CSW.38128.root@cdptpa-web26-z02> In-Reply-To: <20130227221641.B3CSW.38128.root@cdptpa-web26-z02> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201302281039.41919.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Thu, 28 Feb 2013 12:09:51 -0500 (EST) X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Feb 2013 17:09:51 -0000 On Wednesday, February 27, 2013 5:16:41 pm star-one@tx.rr.com wrote: > I need to write a simple device driver for the ISA bus that uses one IRQ and a few reads and writes to I/O Ports 0x300 +. > > > I don't know even where to start with FreeBSD. I've done drivers before in other OS systems and have a book for Linux but FreeBSD seems MUCH differnt. > > > Are there any examples I can get? I thought about modifying the serial driver but I'm not een sure if that's a good idea. > > > Any help would be great. There is a FreeBSD Device Driver book. You will need to allocate 'struct resource' objects for your IRQ and I/O port and then use the bus_space API with your I/O port resource to do inb/outb operations. That is, you would need something like this: In /boot/device.hints: hint.foo.0.at="isa0" hint.foo.0.irq=X hint.foo.0.port=0x300 Then a sketch of your driver would be: #define NPORTS 4 /* How many I/O ports you need starting at 0x300 */ /* Sample only of names for the 4 ports via relative offsets to the start */ #define CONTROL_REG 0 #define DATA_REG 1 struct foo_softc { device_t dev; struct resource *io; struct resource *irq; void *intr_cookie; }; /* Interrupt handler. */ static void foo_int(void *arg) { struct foo_softc *sc; sc = arg; device_printf(sc->dev, "got an interrupt\n"); } static int foo_probe(device_t dev) { /* Ignore PNP devices. */ if (isa_get_logicalid(dev) != 0) return (ENXIO); /* Require IRQ and port hints. */ if (isa_get_port(dev) == -1 || isa_get_irq(dev) == -1) return (ENXIO); device_set_desc(dev, "My foo device"); return (BUS_PROBE_GENERIC); } static int foo_attach(device_t dev) { struct foo_softc *sc; int error, rid; sc = device_get_softc(dev); sc->dev = dev; /* Allocate resources. */ rid = 0; sc->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, NPORTS, RF_ACTIVE); if (sc->io == NULL) { device_printf(dev, "Failed to allocate I/O ports\n"); error = ENXIO; goto out; rid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->irq == NULL) { device_printf(dev, "Failed to allocate IRQ\n"); error = ENXIO; goto out; } /* Read a byte from port 0x300 */ device_printf(dev, "Current control value = %x\n", bus_read_1(sc->io, CONTROL_REG)); /* Read a byte from port 0x301 */ device_printf(dev, "Current data value = %x\n", bus_read_1(sc->io, DATA_REG)); /* Write a byte to the control reg at 0x300 */ bus_write_1(sc->io, CONTROL_REG, 0xff); /* Setup interrupt handler. */ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL, foo_intr, sc, &sc->intr_cookie); if (error != 0) { device_printf(dev, "Failed to setup interrupt handler\n"); goto out; } return (0); out: if (sc->irq != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); if (sc->io != NULL) bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io); return (error); } static int foo_detach(device_t dev) { struct foo_softc *sc; sc = device_get_softc(dev); bus_teardown_intr(dev, sc->irq, sc->intr_cookie); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io); return (0); } static device_method_t foo_methods[] = { DEVMETHOD(device_probe, foo_probe), DEVMETHOD(device_attach, foo_attach), DEVMETHOD(device_detach, foo_detach), DEVMETHOD_END }; static driver_t foo_driver = { "foo", foo_methods, sizeof(struct foo_softc); }; static devclass_t foo_devclass; DRIVER_MODULE(foo, isa, foo_driver, foo_devclass, NULL, NULL); That should get you up and running, but to do something useful with the device you'll probably want to create a cdev or some such. -- John Baldwin From owner-freebsd-drivers@FreeBSD.ORG Thu Feb 28 17:22:14 2013 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 9B1DE73B for ; Thu, 28 Feb 2013 17:22:14 +0000 (UTC) (envelope-from star-one@tx.rr.com) Received: from cdptpa-omtalb.mail.rr.com (cdptpa-omtalb.mail.rr.com [75.180.132.120]) by mx1.freebsd.org (Postfix) with ESMTP id 5AC0536C for ; Thu, 28 Feb 2013 17:22:14 +0000 (UTC) Authentication-Results: cdptpa-omtalb.mail.rr.com smtp.user=star-one@tx.rr.com; auth=pass (LOGIN) X-Authority-Analysis: v=2.0 cv=cYNQXw/M c=1 sm=0 a=_-dPGZQ6cu4A:10 a=05ChyHeVI94A:10 a=IkcTkHD0fZMA:10 a=ayC55rCoAAAA:8 a=ZO-uyplj7cEA:10 a=6I5d2MoRAAAA:8 a=ZHvs9RVKRzM5wJDJj-wA:9 a=QEXdDO2ut3YA:10 a=SV7veod9ZcQA:10 a=8g97u3uHHZxdf5iFaGgFAA==:117 X-Cloudmark-Score: 0 X-Authenticated-User: star-one@tx.rr.com Received: from [10.127.132.170] ([10.127.132.170:32782] helo=cdptpa-web19-z02) by cdptpa-oedge03.mail.rr.com (envelope-from ) (ecelerity 2.2.3.46 r()) with ESMTPA id DB/DE-11869-5429F215; Thu, 28 Feb 2013 17:22:13 +0000 Message-ID: <20130228172213.GI7H4.29745.root@cdptpa-web19-z02> Date: Thu, 28 Feb 2013 12:22:13 -0500 From: To: freebsd-drivers@freebsd.org, John Baldwin Subject: Re: ISA driver for IRQ and PortIO In-Reply-To: <201302281039.41919.jhb@freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) Sensitivity: Normal X-Originating-IP: X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Feb 2013 17:22:14 -0000 Thank you. I'll try that today. Dave ---- John Baldwin wrote: > On Wednesday, February 27, 2013 5:16:41 pm star-one@tx.rr.com wrote: > > I need to write a simple device driver for the ISA bus that uses one IRQ and > a few reads and writes to I/O Ports 0x300 +. > > > > > > I don't know even where to start with FreeBSD. I've done drivers before in > other OS systems and have a book for Linux but FreeBSD seems MUCH differnt. > > > > > > Are there any examples I can get? I thought about modifying the serial > driver but I'm not een sure if that's a good idea. > > > > > > Any help would be great. > > There is a FreeBSD Device Driver book. You will need to allocate 'struct > resource' objects for your IRQ and I/O port and then use the bus_space API > with your I/O port resource to do inb/outb operations. That is, you would > need something like this: > > In /boot/device.hints: > > hint.foo.0.at="isa0" > hint.foo.0.irq=X > hint.foo.0.port=0x300 > > Then a sketch of your driver would be: > > #define NPORTS 4 /* How many I/O ports you need starting at 0x300 */ > > /* Sample only of names for the 4 ports via relative offsets to the start */ > #define CONTROL_REG 0 > #define DATA_REG 1 > > struct foo_softc { > device_t dev; > struct resource *io; > struct resource *irq; > void *intr_cookie; > }; > > /* Interrupt handler. */ > static void > foo_int(void *arg) > { > struct foo_softc *sc; > > sc = arg; > device_printf(sc->dev, "got an interrupt\n"); > } > > static int > foo_probe(device_t dev) > { > /* Ignore PNP devices. */ > if (isa_get_logicalid(dev) != 0) > return (ENXIO); > > /* Require IRQ and port hints. */ > if (isa_get_port(dev) == -1 || > isa_get_irq(dev) == -1) > return (ENXIO); > > device_set_desc(dev, "My foo device"); > return (BUS_PROBE_GENERIC); > } > > static int > foo_attach(device_t dev) > { > struct foo_softc *sc; > int error, rid; > > sc = device_get_softc(dev); > sc->dev = dev; > > /* Allocate resources. */ > rid = 0; > sc->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, NPORTS, > RF_ACTIVE); > if (sc->io == NULL) { > device_printf(dev, "Failed to allocate I/O ports\n"); > error = ENXIO; > goto out; > rid = 0; > sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); > if (sc->irq == NULL) { > device_printf(dev, "Failed to allocate IRQ\n"); > error = ENXIO; > goto out; > } > > /* Read a byte from port 0x300 */ > device_printf(dev, "Current control value = %x\n", > bus_read_1(sc->io, CONTROL_REG)); > /* Read a byte from port 0x301 */ > device_printf(dev, "Current data value = %x\n", > bus_read_1(sc->io, DATA_REG)); > /* Write a byte to the control reg at 0x300 */ > bus_write_1(sc->io, CONTROL_REG, 0xff); > > /* Setup interrupt handler. */ > error = bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL, > foo_intr, sc, &sc->intr_cookie); > if (error != 0) { > device_printf(dev, "Failed to setup interrupt handler\n"); > goto out; > } > return (0); > > out: > if (sc->irq != NULL) > bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); > if (sc->io != NULL) > bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io); > return (error); > } > > static int > foo_detach(device_t dev) > { > struct foo_softc *sc; > > sc = device_get_softc(dev); > bus_teardown_intr(dev, sc->irq, sc->intr_cookie); > bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); > bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io); > return (0); > } > > static device_method_t foo_methods[] = { > DEVMETHOD(device_probe, foo_probe), > DEVMETHOD(device_attach, foo_attach), > DEVMETHOD(device_detach, foo_detach), > DEVMETHOD_END > }; > > static driver_t foo_driver = { > "foo", > foo_methods, > sizeof(struct foo_softc); > }; > > static devclass_t foo_devclass; > > DRIVER_MODULE(foo, isa, foo_driver, foo_devclass, NULL, NULL); > > That should get you up and running, but to do something useful with the device > you'll probably want to create a cdev or some such. > > -- > John Baldwin