diff --git a/sys/dev/pcmcia/esp_pcmcia.c b/sys/dev/pcmcia/esp_pcmcia.c index 67d63c10f826..183d9e5bf148 100644 --- a/sys/dev/pcmcia/esp_pcmcia.c +++ b/sys/dev/pcmcia/esp_pcmcia.c @@ -1,7 +1,7 @@ -/* $NetBSD: esp_pcmcia.c,v 1.17 2004/08/08 23:17:12 mycroft Exp $ */ +/* $NetBSD: esp_pcmcia.c,v 1.18 2004/08/10 07:04:19 mycroft Exp $ */ /*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2004 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: esp_pcmcia.c,v 1.17 2004/08/08 23:17:12 mycroft Exp $"); +__KERNEL_RCSID(0, "$NetBSD: esp_pcmcia.c,v 1.18 2004/08/10 07:04:19 mycroft Exp $"); #include #include @@ -70,19 +70,22 @@ struct esp_pcmcia_softc { size_t *sc_pdmalen; /* PCMCIA-specific goo. */ - struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */ - int sc_io_window; /* our i/o window */ struct pcmcia_function *sc_pf; /* our PCMCIA function */ void *sc_ih; /* interrupt handler */ #ifdef ESP_PCMCIA_POLL struct callout sc_poll_ch; #endif - int sc_flags; -#define ESP_PCMCIA_ATTACHED 1 /* attach completed */ -#define ESP_PCMCIA_ATTACHING 2 /* attach in progress */ + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + int sc_state; +#define ESP_PCMCIA_ATTACH1 1 +#define ESP_PCMCIA_ATTACH2 2 +#define ESP_PCMCIA_ATTACHED 3 }; int esp_pcmcia_match __P((struct device *, struct cfdata *, void *)); +int esp_pcmcia_validate_config __P((struct pcmcia_config_entry *)); void esp_pcmcia_attach __P((struct device *, struct device *, void *)); void esp_pcmcia_init __P((struct esp_pcmcia_softc *)); int esp_pcmcia_detach __P((struct device *, int)); @@ -130,10 +133,10 @@ const struct esp_pcmcia_product { u_int32_t epp_product; /* product ID */ const char *epp_cisinfo[4]; /* CIS information */ } esp_pcmcia_products[] = { - { PCMCIA_STR_PANASONIC_KXLC002, PCMCIA_VENDOR_PANASONIC, + { "", PCMCIA_VENDOR_PANASONIC, PCMCIA_PRODUCT_PANASONIC_KXLC002, PCMCIA_CIS_PANASONIC_KXLC002 }, - { PCMCIA_STR_RATOC_REX_9530, PCMCIA_VENDOR_RATOC, + { "", PCMCIA_VENDOR_RATOC, PCMCIA_PRODUCT_RATOC_REX_9530, PCMCIA_CIS_RATOC_REX_9530 }, { NULL } @@ -179,6 +182,17 @@ esp_pcmcia_match(parent, match, aux) return (0); } +int +esp_pcmcia_validate_config(cfe) + struct pcmcia_config_entry *cfe; +{ + if (cfe->iftype != PCMCIA_IFTYPE_IO || + cfe->num_memspace != 0 || + cfe->num_iospace != 1) + return (EINVAL); + return (0); +} + void esp_pcmcia_attach(parent, self, aux) struct device *parent, *self; @@ -189,71 +203,43 @@ esp_pcmcia_attach(parent, self, aux) struct pcmcia_attach_args *pa = aux; struct pcmcia_config_entry *cfe; struct pcmcia_function *pf = pa->pf; - const struct esp_pcmcia_product *epp; + int error; + aprint_normal("\n"); esc->sc_pf = pf; - SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { - if (cfe->num_memspace != 0 || - cfe->num_iospace != 1) - continue; - - if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start, - cfe->iospace[0].length, 0, &esc->sc_pcioh) == 0) - break; + error = pcmcia_function_configure(pf, esp_pcmcia_validate_config); + if (error) { + aprint_error("%s: configure failed, error=%d\n", self->dv_xname, + error); + return; } - if (cfe == 0) { - printf(": can't alloc i/o space\n"); - goto no_config_entry; - } - - /* Enable the card. */ - pcmcia_function_init(pf, cfe); - if (pcmcia_function_enable(pf)) { - printf(": function enable failed\n"); - goto enable_failed; - } - - /* Map in the I/O space */ - if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, &esc->sc_pcioh, - &esc->sc_io_window)) { - printf(": can't map i/o space\n"); - goto iomap_failed; - } - - epp = esp_pcmcia_lookup(pa); - if (epp == NULL) { - printf("\n"); - panic("esp_pcmcia_attach: impossible"); - } - - printf(": %s", epp->epp_name); - + cfe = pf->cfe; + esc->sc_iot = cfe->iospace[0].handle.iot; + esc->sc_ioh = cfe->iospace[0].handle.ioh; esp_pcmcia_init(esc); - /* - * Initialize nca board itself. - */ - esc->sc_flags |= ESP_PCMCIA_ATTACHING; + error = esp_pcmcia_enable(self, 1); + if (error) { + aprint_error("%s: enable failed, error=%d\n", self->dv_xname, + error); + goto fail; + } + sc->sc_adapter.adapt_minphys = minphys; sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request; sc->sc_adapter.adapt_enable = esp_pcmcia_enable; + + esc->sc_state = ESP_PCMCIA_ATTACH1; ncr53c9x_attach(sc); - esc->sc_flags &= ~ESP_PCMCIA_ATTACHING; - esc->sc_flags |= ESP_PCMCIA_ATTACHED; + if (esc->sc_state == ESP_PCMCIA_ATTACH1) + esp_pcmcia_enable(self, 0); + esc->sc_state = ESP_PCMCIA_ATTACHED; return; -iomap_failed: - /* Disable the device. */ - pcmcia_function_disable(esc->sc_pf); - -enable_failed: - /* Unmap our I/O space. */ - pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh); - -no_config_entry: - return; +fail: + pcmcia_function_unconfigure(pf); } void @@ -261,8 +247,6 @@ esp_pcmcia_init(esc) struct esp_pcmcia_softc *esc; { struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; - bus_space_tag_t iot = esc->sc_pcioh.iot; - bus_space_handle_t ioh = esc->sc_pcioh.ioh; /* id 7, clock 40M, parity ON, sync OFF, fast ON, slow ON */ @@ -287,14 +271,6 @@ esp_pcmcia_init(esc) sc->sc_cfg5 = NCRCFG5_CRS1 | NCRCFG5_AADDR | NCRCFG5_PTRINC; sc->sc_minsync = 0; sc->sc_maxxfer = 64 * 1024; - - bus_space_write_1(iot, ioh, NCR_CFG5, sc->sc_cfg5); - - bus_space_write_1(iot, ioh, NCR_PIOI, 0); - bus_space_write_1(iot, ioh, NCR_PSTAT, 0); - bus_space_write_1(iot, ioh, 0x09, 0x24); - - bus_space_write_1(iot, ioh, NCR_CFG4, sc->sc_cfg4); } int @@ -302,21 +278,17 @@ esp_pcmcia_detach(self, flags) struct device *self; int flags; { - struct esp_pcmcia_softc *esc = (void *)self; + struct esp_pcmcia_softc *sc = (void *)self; int error; - if ((esc->sc_flags & ESP_PCMCIA_ATTACHED) == 0) { - /* Nothing to detach. */ + if (sc->sc_state != ESP_PCMCIA_ATTACHED) return (0); - } - error = ncr53c9x_detach(&esc->sc_ncr53c9x, flags); + error = ncr53c9x_detach(&sc->sc_ncr53c9x, flags); if (error) return (error); - /* Unmap our i/o window and i/o space. */ - pcmcia_io_unmap(esc->sc_pf, esc->sc_io_window); - pcmcia_io_free(esc->sc_pf, &esc->sc_pcioh); + pcmcia_function_unconfigure(sc->sc_pf); return (0); } @@ -326,45 +298,47 @@ esp_pcmcia_enable(arg, onoff) struct device *arg; int onoff; { - struct esp_pcmcia_softc *esc = (void *) arg; + struct esp_pcmcia_softc *sc = (void *)arg; if (onoff) { + /* + * If attach is in progress, we already have the device + * powered up. + */ + if (sc->sc_state == ESP_PCMCIA_ATTACH1) { + sc->sc_state = ESP_PCMCIA_ATTACH2; + } else { #ifdef ESP_PCMCIA_POLL - callout_reset(&esc->sc_poll_ch, 1, esp_pcmcia_poll, esc); + callout_reset(&sc->sc_poll_ch, 1, esp_pcmcia_poll, sc); #else - /* Establish the interrupt handler. */ - esc->sc_ih = pcmcia_intr_establish(esc->sc_pf, IPL_BIO, - ncr53c9x_intr, &esc->sc_ncr53c9x); - if (esc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt handler\n", - esc->sc_ncr53c9x.sc_dev.dv_xname); - return (EIO); - } + /* Establish the interrupt handler. */ + sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_BIO, + ncr53c9x_intr, &sc->sc_ncr53c9x); + if (sc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt handler\n", + sc->sc_ncr53c9x.sc_dev.dv_xname); + return (EIO); + } #endif - /* - * If attach is in progress, we know that card power is - * enabled and chip will be initialized later. - * Otherwise, enable and reset now. - */ - if ((esc->sc_flags & ESP_PCMCIA_ATTACHING) == 0) { - if (pcmcia_function_enable(esc->sc_pf)) { + if (pcmcia_function_enable(sc->sc_pf)) { printf("%s: couldn't enable PCMCIA function\n", - esc->sc_ncr53c9x.sc_dev.dv_xname); - pcmcia_intr_disestablish(esc->sc_pf, - esc->sc_ih); + sc->sc_ncr53c9x.sc_dev.dv_xname); + pcmcia_intr_disestablish(sc->sc_pf, + sc->sc_ih); return (EIO); } /* Initialize only chip. */ - ncr53c9x_init(&esc->sc_ncr53c9x, 0); + ncr53c9x_init(&sc->sc_ncr53c9x, 0); } } else { - pcmcia_function_disable(esc->sc_pf); + pcmcia_function_disable(sc->sc_pf); #ifdef ESP_PCMCIA_POLL - callout_stop(&esc->sc_poll_ch); + callout_stop(&sc->sc_poll_ch); #else - pcmcia_intr_disestablish(esc->sc_pf, esc->sc_ih); + pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih); + sc->sc_ih = 0; #endif } @@ -394,7 +368,7 @@ esp_pcmcia_read_reg(sc, reg) struct esp_pcmcia_softc *esc = (struct esp_pcmcia_softc *)sc; u_char v; - v = bus_space_read_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg); + v = bus_space_read_1(esc->sc_iot, esc->sc_ioh, reg); return v; } @@ -409,7 +383,7 @@ esp_pcmcia_write_reg(sc, reg, val) if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) v = NCRCMD_TRANS; - bus_space_write_1(esc->sc_pcioh.iot, esc->sc_pcioh.ioh, reg, v); + bus_space_write_1(esc->sc_iot, esc->sc_ioh, reg, v); } int