1/* $NecBSD: nsp_pisa.c,v 1.4 1999/04/15 01:35:54 kmatsuda Exp $ */ 2/* $NetBSD$ */ 3 4/* 5 * [Ported for FreeBSD] 6 * Copyright (c) 2000 7 * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. 8 * All rights reserved. 9 * [NetBSD for NEC PC-98 series] 10 * Copyright (c) 1998 11 * NetBSD/pc98 porting staff. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37#include <sys/cdefs.h>
| 1/* $NecBSD: nsp_pisa.c,v 1.4 1999/04/15 01:35:54 kmatsuda Exp $ */ 2/* $NetBSD$ */ 3 4/* 5 * [Ported for FreeBSD] 6 * Copyright (c) 2000 7 * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. 8 * All rights reserved. 9 * [NetBSD for NEC PC-98 series] 10 * Copyright (c) 1998 11 * NetBSD/pc98 porting staff. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37#include <sys/cdefs.h>
|
70 71#define PIO_MODE 0x100 /* pd_flags */ 72 73static int nspprobe(DEVPORT_PDEVICE devi); 74static int nspattach(DEVPORT_PDEVICE devi); 75 76static void nsp_card_unload (DEVPORT_PDEVICE); 77 78const struct pccard_product nsp_products[] = { 79 PCMCIA_CARD(IODATA3, CBSC16, 0), 80 PCMCIA_CARD(PANASONIC, KME, 0), 81 PCMCIA_CARD(WORKBIT2, NINJA_SCSI3, 0), 82 PCMCIA_CARD(WORKBIT, ULTRA_NINJA_16, 0), 83 { NULL } 84}; 85 86/* 87 * Additional code for FreeBSD new-bus PCCard frontend 88 */ 89 90static void 91nsp_pccard_intr(void * arg) 92{ 93 nspintr(arg); 94} 95 96static void 97nsp_release_resource(DEVPORT_PDEVICE dev) 98{ 99 struct nsp_softc *sc = device_get_softc(dev); 100 101 if (sc->nsp_intrhand) { 102 bus_teardown_intr(dev, sc->irq_res, sc->nsp_intrhand); 103 } 104 105 if (sc->port_res) { 106 bus_release_resource(dev, SYS_RES_IOPORT, 107 sc->port_rid, sc->port_res); 108 } 109 110 if (sc->irq_res) { 111 bus_release_resource(dev, SYS_RES_IRQ, 112 sc->irq_rid, sc->irq_res); 113 } 114 115 if (sc->mem_res) { 116 bus_release_resource(dev, SYS_RES_MEMORY, 117 sc->mem_rid, sc->mem_res); 118 } 119} 120 121static int 122nsp_alloc_resource(DEVPORT_PDEVICE dev) 123{ 124 struct nsp_softc *sc = device_get_softc(dev); 125 u_long ioaddr, iosize, maddr, msize; 126 int error; 127 128 error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize); 129 if (error || iosize < NSP_IOSIZE) 130 return(ENOMEM); 131 132 sc->port_rid = 0; 133 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, 134 0, ~0, NSP_IOSIZE, RF_ACTIVE); 135 if (sc->port_res == NULL) { 136 nsp_release_resource(dev); 137 return(ENOMEM); 138 } 139 140 sc->irq_rid = 0; 141 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 142 RF_ACTIVE); 143 if (sc->irq_res == NULL) { 144 nsp_release_resource(dev); 145 return(ENOMEM); 146 } 147 148 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); 149 if (error) { 150 return(0); /* XXX */ 151 } 152 153 /* No need to allocate memory if not configured and it's in PIO mode */ 154 if (maddr == 0 || msize == 0) { 155 if ((DEVPORT_PDEVFLAGS(dev) & PIO_MODE) == 0) { 156 printf("Memory window was not configured. Configure or use in PIO mode."); 157 nsp_release_resource(dev); 158 return(ENOMEM); 159 } 160 /* no need to allocate memory if PIO mode */ 161 return(0); 162 } 163 164 sc->mem_rid = 0; 165 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 166 RF_ACTIVE); 167 if (sc->mem_res == NULL) { 168 nsp_release_resource(dev); 169 return(ENOMEM); 170 } 171 172 return(0); 173} 174 175static int nsp_pccard_match(device_t dev) 176{ 177 const struct pccard_product *pp; 178 179 if ((pp = pccard_product_lookup(dev, nsp_products, 180 sizeof(nsp_products[0]), NULL)) != NULL) { 181 device_set_desc(dev, pp->pp_name); 182 return(0); 183 } 184 return(EIO); 185} 186 187static int 188nsp_pccard_probe(DEVPORT_PDEVICE dev) 189{ 190 struct nsp_softc *sc = device_get_softc(dev); 191 int error; 192 193 bzero(sc, sizeof(struct nsp_softc)); 194 195 error = nsp_alloc_resource(dev); 196 if (error) { 197 return(error); 198 } 199 200 if (nspprobe(dev) == 0) { 201 nsp_release_resource(dev); 202 return(ENXIO); 203 } 204 205 nsp_release_resource(dev); 206 207 return(0); 208} 209 210static int 211nsp_pccard_attach(DEVPORT_PDEVICE dev) 212{ 213 struct nsp_softc *sc = device_get_softc(dev); 214 int error; 215 216 error = nsp_alloc_resource(dev); 217 if (error) { 218 return(error); 219 } 220 221 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, 222 nsp_pccard_intr, (void *)sc, &sc->nsp_intrhand); 223 if (error) { 224 nsp_release_resource(dev); 225 return(error); 226 } 227 228 if (nspattach(dev) == 0) { 229 nsp_release_resource(dev); 230 return(ENXIO); 231 } 232 233 return(0); 234} 235 236static void 237nsp_pccard_detach(DEVPORT_PDEVICE dev) 238{ 239 nsp_card_unload(dev); 240 nsp_release_resource(dev); 241} 242 243static device_method_t nsp_pccard_methods[] = { 244 /* Device interface */ 245 DEVMETHOD(device_probe, pccard_compat_probe), 246 DEVMETHOD(device_attach, pccard_compat_attach), 247 DEVMETHOD(device_detach, nsp_pccard_detach), 248 249 /* Card interface */ 250 DEVMETHOD(card_compat_match, nsp_pccard_match), 251 DEVMETHOD(card_compat_probe, nsp_pccard_probe), 252 DEVMETHOD(card_compat_attach, nsp_pccard_attach), 253 254 { 0, 0 } 255}; 256 257static driver_t nsp_pccard_driver = { 258 "nsp", 259 nsp_pccard_methods, 260 sizeof(struct nsp_softc), 261}; 262 263static devclass_t nsp_devclass; 264 265MODULE_DEPEND(nsp, scsi_low, 1, 1, 1); 266DRIVER_MODULE(nsp, pccard, nsp_pccard_driver, nsp_devclass, 0, 0); 267 268static void 269nsp_card_unload(DEVPORT_PDEVICE devi) 270{ 271 struct nsp_softc *sc = DEVPORT_PDEVGET_SOFTC(devi); 272 intrmask_t s; 273 274 printf("%s: unload\n",sc->sc_sclow.sl_xname); 275 s = splcam(); 276 scsi_low_deactivate((struct scsi_low_softc *)sc); 277 scsi_low_dettach(&sc->sc_sclow); 278 splx(s); 279} 280 281static int 282nspprobe(DEVPORT_PDEVICE devi) 283{ 284 int rv; 285 struct nsp_softc *sc = device_get_softc(devi); 286 287 rv = nspprobesubr(rman_get_bustag(sc->port_res), 288 rman_get_bushandle(sc->port_res), 289 DEVPORT_PDEVFLAGS(devi)); 290 291 return rv; 292} 293 294static int 295nspattach(DEVPORT_PDEVICE devi) 296{ 297 struct nsp_softc *sc; 298 struct scsi_low_softc *slp; 299 u_int32_t flags = DEVPORT_PDEVFLAGS(devi); 300 u_int iobase = DEVPORT_PDEVIOBASE(devi); 301 intrmask_t s; 302 char dvname[16]; 303 304 strcpy(dvname,"nsp"); 305 306 if (iobase == 0) 307 { 308 printf("%s: no ioaddr is given\n", dvname); 309 return (0); 310 } 311 312 sc = DEVPORT_PDEVALLOC_SOFTC(devi); 313 if (sc == NULL) { 314 return (0); 315 } 316 317 slp = &sc->sc_sclow; 318 slp->sl_dev = devi; 319 sc->sc_iot = rman_get_bustag(sc->port_res); 320 sc->sc_ioh = rman_get_bushandle(sc->port_res); 321 322 if(sc->mem_res == NULL){ 323 printf("WARNING: CANNOT GET Memory RESOURCE going PIO mode"); 324 flags |= PIO_MODE; 325 } 326 327 if((flags & PIO_MODE) == 0) { 328 sc->sc_memt = rman_get_bustag(sc->mem_res); 329 sc->sc_memh = rman_get_bushandle(sc->mem_res); 330 } else { 331 sc->sc_memh = 0; 332 } 333 /* slp->sl_irq = devi->pd_irq; */ 334 sc->sc_iclkdiv = CLKDIVR_20M; 335 sc->sc_clkdiv = CLKDIVR_40M; 336 337 slp->sl_hostid = NSP_HOSTID; 338 slp->sl_cfgflags = flags; 339 340 s = splcam(); 341 nspattachsubr(sc); 342 splx(s); 343 344 return(NSP_IOSIZE); 345}
| 65 66#define PIO_MODE 0x100 /* pd_flags */ 67 68static int nspprobe(DEVPORT_PDEVICE devi); 69static int nspattach(DEVPORT_PDEVICE devi); 70 71static void nsp_card_unload (DEVPORT_PDEVICE); 72 73const struct pccard_product nsp_products[] = { 74 PCMCIA_CARD(IODATA3, CBSC16, 0), 75 PCMCIA_CARD(PANASONIC, KME, 0), 76 PCMCIA_CARD(WORKBIT2, NINJA_SCSI3, 0), 77 PCMCIA_CARD(WORKBIT, ULTRA_NINJA_16, 0), 78 { NULL } 79}; 80 81/* 82 * Additional code for FreeBSD new-bus PCCard frontend 83 */ 84 85static void 86nsp_pccard_intr(void * arg) 87{ 88 nspintr(arg); 89} 90 91static void 92nsp_release_resource(DEVPORT_PDEVICE dev) 93{ 94 struct nsp_softc *sc = device_get_softc(dev); 95 96 if (sc->nsp_intrhand) { 97 bus_teardown_intr(dev, sc->irq_res, sc->nsp_intrhand); 98 } 99 100 if (sc->port_res) { 101 bus_release_resource(dev, SYS_RES_IOPORT, 102 sc->port_rid, sc->port_res); 103 } 104 105 if (sc->irq_res) { 106 bus_release_resource(dev, SYS_RES_IRQ, 107 sc->irq_rid, sc->irq_res); 108 } 109 110 if (sc->mem_res) { 111 bus_release_resource(dev, SYS_RES_MEMORY, 112 sc->mem_rid, sc->mem_res); 113 } 114} 115 116static int 117nsp_alloc_resource(DEVPORT_PDEVICE dev) 118{ 119 struct nsp_softc *sc = device_get_softc(dev); 120 u_long ioaddr, iosize, maddr, msize; 121 int error; 122 123 error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize); 124 if (error || iosize < NSP_IOSIZE) 125 return(ENOMEM); 126 127 sc->port_rid = 0; 128 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, 129 0, ~0, NSP_IOSIZE, RF_ACTIVE); 130 if (sc->port_res == NULL) { 131 nsp_release_resource(dev); 132 return(ENOMEM); 133 } 134 135 sc->irq_rid = 0; 136 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 137 RF_ACTIVE); 138 if (sc->irq_res == NULL) { 139 nsp_release_resource(dev); 140 return(ENOMEM); 141 } 142 143 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); 144 if (error) { 145 return(0); /* XXX */ 146 } 147 148 /* No need to allocate memory if not configured and it's in PIO mode */ 149 if (maddr == 0 || msize == 0) { 150 if ((DEVPORT_PDEVFLAGS(dev) & PIO_MODE) == 0) { 151 printf("Memory window was not configured. Configure or use in PIO mode."); 152 nsp_release_resource(dev); 153 return(ENOMEM); 154 } 155 /* no need to allocate memory if PIO mode */ 156 return(0); 157 } 158 159 sc->mem_rid = 0; 160 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 161 RF_ACTIVE); 162 if (sc->mem_res == NULL) { 163 nsp_release_resource(dev); 164 return(ENOMEM); 165 } 166 167 return(0); 168} 169 170static int nsp_pccard_match(device_t dev) 171{ 172 const struct pccard_product *pp; 173 174 if ((pp = pccard_product_lookup(dev, nsp_products, 175 sizeof(nsp_products[0]), NULL)) != NULL) { 176 device_set_desc(dev, pp->pp_name); 177 return(0); 178 } 179 return(EIO); 180} 181 182static int 183nsp_pccard_probe(DEVPORT_PDEVICE dev) 184{ 185 struct nsp_softc *sc = device_get_softc(dev); 186 int error; 187 188 bzero(sc, sizeof(struct nsp_softc)); 189 190 error = nsp_alloc_resource(dev); 191 if (error) { 192 return(error); 193 } 194 195 if (nspprobe(dev) == 0) { 196 nsp_release_resource(dev); 197 return(ENXIO); 198 } 199 200 nsp_release_resource(dev); 201 202 return(0); 203} 204 205static int 206nsp_pccard_attach(DEVPORT_PDEVICE dev) 207{ 208 struct nsp_softc *sc = device_get_softc(dev); 209 int error; 210 211 error = nsp_alloc_resource(dev); 212 if (error) { 213 return(error); 214 } 215 216 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, 217 nsp_pccard_intr, (void *)sc, &sc->nsp_intrhand); 218 if (error) { 219 nsp_release_resource(dev); 220 return(error); 221 } 222 223 if (nspattach(dev) == 0) { 224 nsp_release_resource(dev); 225 return(ENXIO); 226 } 227 228 return(0); 229} 230 231static void 232nsp_pccard_detach(DEVPORT_PDEVICE dev) 233{ 234 nsp_card_unload(dev); 235 nsp_release_resource(dev); 236} 237 238static device_method_t nsp_pccard_methods[] = { 239 /* Device interface */ 240 DEVMETHOD(device_probe, pccard_compat_probe), 241 DEVMETHOD(device_attach, pccard_compat_attach), 242 DEVMETHOD(device_detach, nsp_pccard_detach), 243 244 /* Card interface */ 245 DEVMETHOD(card_compat_match, nsp_pccard_match), 246 DEVMETHOD(card_compat_probe, nsp_pccard_probe), 247 DEVMETHOD(card_compat_attach, nsp_pccard_attach), 248 249 { 0, 0 } 250}; 251 252static driver_t nsp_pccard_driver = { 253 "nsp", 254 nsp_pccard_methods, 255 sizeof(struct nsp_softc), 256}; 257 258static devclass_t nsp_devclass; 259 260MODULE_DEPEND(nsp, scsi_low, 1, 1, 1); 261DRIVER_MODULE(nsp, pccard, nsp_pccard_driver, nsp_devclass, 0, 0); 262 263static void 264nsp_card_unload(DEVPORT_PDEVICE devi) 265{ 266 struct nsp_softc *sc = DEVPORT_PDEVGET_SOFTC(devi); 267 intrmask_t s; 268 269 printf("%s: unload\n",sc->sc_sclow.sl_xname); 270 s = splcam(); 271 scsi_low_deactivate((struct scsi_low_softc *)sc); 272 scsi_low_dettach(&sc->sc_sclow); 273 splx(s); 274} 275 276static int 277nspprobe(DEVPORT_PDEVICE devi) 278{ 279 int rv; 280 struct nsp_softc *sc = device_get_softc(devi); 281 282 rv = nspprobesubr(rman_get_bustag(sc->port_res), 283 rman_get_bushandle(sc->port_res), 284 DEVPORT_PDEVFLAGS(devi)); 285 286 return rv; 287} 288 289static int 290nspattach(DEVPORT_PDEVICE devi) 291{ 292 struct nsp_softc *sc; 293 struct scsi_low_softc *slp; 294 u_int32_t flags = DEVPORT_PDEVFLAGS(devi); 295 u_int iobase = DEVPORT_PDEVIOBASE(devi); 296 intrmask_t s; 297 char dvname[16]; 298 299 strcpy(dvname,"nsp"); 300 301 if (iobase == 0) 302 { 303 printf("%s: no ioaddr is given\n", dvname); 304 return (0); 305 } 306 307 sc = DEVPORT_PDEVALLOC_SOFTC(devi); 308 if (sc == NULL) { 309 return (0); 310 } 311 312 slp = &sc->sc_sclow; 313 slp->sl_dev = devi; 314 sc->sc_iot = rman_get_bustag(sc->port_res); 315 sc->sc_ioh = rman_get_bushandle(sc->port_res); 316 317 if(sc->mem_res == NULL){ 318 printf("WARNING: CANNOT GET Memory RESOURCE going PIO mode"); 319 flags |= PIO_MODE; 320 } 321 322 if((flags & PIO_MODE) == 0) { 323 sc->sc_memt = rman_get_bustag(sc->mem_res); 324 sc->sc_memh = rman_get_bushandle(sc->mem_res); 325 } else { 326 sc->sc_memh = 0; 327 } 328 /* slp->sl_irq = devi->pd_irq; */ 329 sc->sc_iclkdiv = CLKDIVR_20M; 330 sc->sc_clkdiv = CLKDIVR_40M; 331 332 slp->sl_hostid = NSP_HOSTID; 333 slp->sl_cfgflags = flags; 334 335 s = splcam(); 336 nspattachsubr(sc); 337 splx(s); 338 339 return(NSP_IOSIZE); 340}
|