From 7602de354fee3a5f1d2c69dfef205930b271a087 Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Sun, 11 Jul 2004 00:19:30 +0000 Subject: [PATCH] Make NdisReadPcmciaAttributeMemory() and NdisWritePcmciaAttributeMemory() actually work. Make the PCI and PCCARD attachments provide a bus_get_resource_list() method so that resource listing for PCCARD works. PCCARD does not have a bus_get_resource_list() method (yet), so I faked up the resource list management in if_ndis_pccard.c, and added bus_get_resource_list() methods to both if_ndis_pccard.c and if_ndis_pci.c. The one in the PCI attechment just hands off to the PCI bus code. The difference is transparent to the NDIS resource handler code. Fixed ndis_open_file() so that opening files which live on NFS filesystems work: pass an actual ucred structure to VOP_GETATTR() (NFS explodes if the ucred structure is NOCRED). Make NdisMMapIoSpace() handle mapping of PCMCIA attribute memory resources correctly. Turn subr_ndis.c:my_strcasecmp() into ndis_strcasecmp() and export it so that if_ndis_pccard.c can use it, and junk the other copy of my_strcasecmp() from if_ndis_pccard.c. --- sys/compat/ndis/kern_ndis.c | 3 +- sys/compat/ndis/ndis_var.h | 2 + sys/compat/ndis/subr_ndis.c | 20 ++++---- sys/dev/if_ndis/if_ndis_pccard.c | 79 +++++++++++++++++++++++--------- sys/dev/if_ndis/if_ndis_pci.c | 16 +++++++ sys/dev/if_ndis/if_ndisvar.h | 2 + 6 files changed, 91 insertions(+), 31 deletions(-) diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index bbfff77651b2..59c9d382233f 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -853,7 +853,8 @@ ndis_convert_res(arg) rl->cprl_count = sc->ndis_rescnt; prd = rl->cprl_partial_descs; - brl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); + brl = BUS_GET_RESOURCE_LIST(dev, dev); + if (brl != NULL) { /* diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h index 2c015a9f9643..2c88b9d87a8f 100644 --- a/sys/compat/ndis/ndis_var.h +++ b/sys/compat/ndis/ndis_var.h @@ -1500,6 +1500,7 @@ extern int ndis_send_packets(void *, ndis_packet **, int); extern int ndis_send_packet(void *, ndis_packet *); extern int ndis_convert_res(void *); extern int ndis_alloc_amem(void *); +extern void ndis_free_amem(void *); extern void ndis_free_packet(ndis_packet *); extern void ndis_free_bufs(ndis_buffer *); extern int ndis_reset_nic(void *); @@ -1520,6 +1521,7 @@ extern int ndis_sched(void (*)(void *), void *, int); extern int ndis_unsched(void (*)(void *), void *, int); extern int ndis_thsuspend(struct proc *, int); extern void ndis_thresume(struct proc *); +extern int ndis_strcasecmp(const char *, const char *); __END_DECLS #endif /* _NDIS_VAR_H_ */ diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 243c9dcca6a5..e85ec7f1b238 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -130,7 +130,6 @@ static ndis_status ndis_encode_parm(ndis_miniport_block *, struct sysctl_oid *, ndis_parm_type, ndis_config_parm **); static ndis_status ndis_decode_parm(ndis_miniport_block *, ndis_config_parm *, char *); -static int my_strcasecmp(const char *, const char *); __stdcall static void ndis_read_cfg(ndis_status *, ndis_config_parm **, ndis_handle, ndis_unicode_string *, ndis_parm_type); __stdcall static void ndis_write_cfg(ndis_status *, ndis_handle, @@ -556,8 +555,8 @@ ndis_encode_parm(block, oid, type, parm) return(NDIS_STATUS_SUCCESS); } -static int -my_strcasecmp(s1, s2) +int +ndis_strcasecmp(s1, s2) const char *s1; const char *s2; { @@ -619,7 +618,7 @@ ndis_read_cfg(status, parm, cfg, key, type) TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) { #endif oidp = e->entry; - if (my_strcasecmp(oidp->oid_name, keystr) == 0) { + if (ndis_strcasecmp(oidp->oid_name, keystr) == 0) { if (strcmp((char *)oidp->oid_arg1, "UNSET") == 0) { free(keystr, M_DEVBUF); *status = NDIS_STATUS_FAILURE; @@ -719,7 +718,7 @@ ndis_write_cfg(status, cfg, key, parm) TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) { #endif oidp = e->entry; - if (my_strcasecmp(oidp->oid_name, keystr) == 0) { + if (ndis_strcasecmp(oidp->oid_name, keystr) == 0) { /* Found it, set the value. */ strcpy((char *)oidp->oid_arg1, val); free(keystr, M_DEVBUF); @@ -885,6 +884,7 @@ ndis_syslog(ndis_handle adapter, ndis_error_code code, uint16_t flags; char msgbuf[ERRMSGLEN]; + block = (ndis_miniport_block *)adapter; error = pe_get_message(block->nmb_img, code, &str, &i, &flags); @@ -1478,6 +1478,9 @@ ndis_map_iospace(vaddr, adapter, paddr, len) else if (sc->ndis_res_altmem != NULL && paddr.np_quad == rman_get_start(sc->ndis_res_altmem)) *vaddr = (void *)rman_get_virtual(sc->ndis_res_altmem); + else if (sc->ndis_res_am != NULL && + paddr.np_quad == rman_get_start(sc->ndis_res_am)) + *vaddr = (void *)rman_get_virtual(sc->ndis_res_am); else return(NDIS_STATUS_FAILURE); @@ -2244,7 +2247,7 @@ ndis_read_pccard_amem(handle, offset, buf, len) bt = rman_get_bustag(sc->ndis_res_am); for (i = 0; i < len; i++) - dest[i] = bus_space_read_1(bt, bh, (offset * 2) + (i * 2)); + dest[i] = bus_space_read_1(bt, bh, (offset + i) * 2); return(i); } @@ -2274,7 +2277,7 @@ ndis_write_pccard_amem(handle, offset, buf, len) bt = rman_get_bustag(sc->ndis_res_am); for (i = 0; i < len; i++) - bus_space_write_1(bt, bh, (offset * 2) + (i * 2), src[i]); + bus_space_write_1(bt, bh, (offset + i) * 2, src[i]); return(i); } @@ -2584,7 +2587,7 @@ ndis_open_file(status, filehandle, filelength, filename, highestaddr) NDFREE(&nd, NDF_ONLY_PNBUF); /* Get the file size. */ - VOP_GETATTR(nd.ni_vp, vap, NOCRED, td); + VOP_GETATTR(nd.ni_vp, vap, td->td_ucred, td); VOP_UNLOCK(nd.ni_vp, 0, td); mtx_unlock(&Giant); @@ -2593,6 +2596,7 @@ ndis_open_file(status, filehandle, filelength, filename, highestaddr) *filehandle = fh; *filelength = fh->nf_maplen = vap->va_size & 0xFFFFFFFF; *status = NDIS_STATUS_SUCCESS; + return; } diff --git a/sys/dev/if_ndis/if_ndis_pccard.c b/sys/dev/if_ndis/if_ndis_pccard.c index 60c1e7b9f651..8f26eaca8552 100644 --- a/sys/dev/if_ndis/if_ndis_pccard.c +++ b/sys/dev/if_ndis/if_ndis_pccard.c @@ -85,14 +85,14 @@ static struct ndis_pccard_type ndis_devs[] = { static int ndis_probe_pccard (device_t); static int ndis_attach_pccard (device_t); +static struct resource_list *ndis_get_resource_list + (device_t, device_t); extern int ndis_attach (device_t); extern int ndis_shutdown (device_t); extern int ndis_detach (device_t); extern int ndis_suspend (device_t); extern int ndis_resume (device_t); -static int my_strcasecmp (const char *, const char *, int); - extern struct mtx_pool *ndis_mtxpool; static device_method_t ndis_methods[] = { @@ -104,6 +104,15 @@ static device_method_t ndis_methods[] = { DEVMETHOD(device_suspend, ndis_suspend), DEVMETHOD(device_resume, ndis_resume), + /* Bus interface. */ + + /* + * This is an awful kludge, but we need it becase pccard + * does not implement a bus_get_resource_list() method. + */ + + DEVMETHOD(bus_get_resource_list, ndis_get_resource_list), + { 0, 0 } }; @@ -127,22 +136,6 @@ NDIS_MODNAME_OVERRIDE_PCMCIA(NDIS_MODNAME); DRIVER_MODULE(ndis, pccard, ndis_driver, ndis_devclass, 0, 0); #endif -static int my_strcasecmp(s1, s2, len) - const char *s1; - const char *s2; - int len; -{ - int i; - - for (i = 0; i < len; i++) { - if (toupper(s1[i]) != toupper(s2[i])) - return(0); - } - - return(1); -} - - /* * Probe for an NDIS device. Check the PCI vendor and device * IDs against our list and return a device name if we find a match. @@ -165,8 +158,8 @@ ndis_probe_pccard(dev) return(error); while(t->ndis_name != NULL) { - if (my_strcasecmp(vendstr, t->ndis_vid, strlen(vendstr)) && - my_strcasecmp(prodstr, t->ndis_did, strlen(prodstr))) { + if (ndis_strcasecmp(vendstr, t->ndis_vid) == 0 && + ndis_strcasecmp(prodstr, t->ndis_did) == 0) { device_set_desc(dev, t->ndis_name); return(0); } @@ -193,6 +186,7 @@ ndis_attach_pccard(dev) sc = device_get_softc(dev); unit = device_get_unit(dev); sc->ndis_dev = dev; + resource_list_init(&sc->ndis_rl); sc->ndis_io_rid = 0; sc->ndis_res_io = bus_alloc_resource(dev, @@ -205,6 +199,9 @@ ndis_attach_pccard(dev) goto fail; } sc->ndis_rescnt++; + resource_list_add(&sc->ndis_rl, SYS_RES_IOPORT, rid, + rman_get_start(sc->ndis_res_io), rman_get_end(sc->ndis_res_io), + rman_get_size(sc->ndis_res_io)); rid = 0; sc->ndis_irq = bus_alloc_resource(dev, @@ -217,6 +214,8 @@ ndis_attach_pccard(dev) goto fail; } sc->ndis_rescnt++; + resource_list_add(&sc->ndis_rl, SYS_RES_IRQ, rid, + rman_get_start(sc->ndis_irq), rman_get_start(sc->ndis_irq), 1); sc->ndis_iftype = PCMCIABus; @@ -232,8 +231,8 @@ ndis_attach_pccard(dev) return(error); while(t->ndis_name != NULL) { - if (my_strcasecmp(vendstr, t->ndis_vid, strlen(vendstr)) && - my_strcasecmp(prodstr, t->ndis_did, strlen(prodstr))) + if (ndis_strcasecmp(vendstr, t->ndis_vid) == 0 && + ndis_strcasecmp(prodstr, t->ndis_did) == 0) break; t++; devidx++; @@ -247,6 +246,17 @@ fail: return(error); } +static struct resource_list * +ndis_get_resource_list(dev, child) + device_t dev; + device_t child; +{ + struct ndis_softc *sc; + + sc = device_get_softc(dev); + return (&sc->ndis_rl); +} + #endif /* NDIS_PCI_DEV_TABLE */ #define NDIS_AM_RID 3 @@ -271,6 +281,10 @@ ndis_alloc_amem(arg) "failed to allocate attribute memory\n"); return(ENXIO); } + sc->ndis_rescnt++; + resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid, + rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am), + rman_get_size(sc->ndis_res_am)); error = CARD_SET_MEMORY_OFFSET(device_get_parent(sc->ndis_dev), sc->ndis_dev, rid, 0, NULL); @@ -290,5 +304,26 @@ ndis_alloc_amem(arg) return(error); } + sc->ndis_am_rid = rid; + return(0); } + +void +ndis_free_amem(arg) + void *arg; +{ + struct ndis_softc *sc; + + if (arg == NULL) + return; + + sc = arg; + + if (sc->ndis_res_am != NULL) + bus_release_resource(sc->ndis_dev, SYS_RES_MEMORY, + sc->ndis_am_rid, sc->ndis_res_am); + resource_list_free(&sc->ndis_rl); + + return; +} diff --git a/sys/dev/if_ndis/if_ndis_pci.c b/sys/dev/if_ndis/if_ndis_pci.c index 7602dd16b28b..47c2f699ee40 100644 --- a/sys/dev/if_ndis/if_ndis_pci.c +++ b/sys/dev/if_ndis/if_ndis_pci.c @@ -84,6 +84,8 @@ static struct ndis_pci_type ndis_devs[] = { static int ndis_probe_pci (device_t); static int ndis_attach_pci (device_t); +static struct resource_list *ndis_get_resource_list + (device_t, device_t); extern int ndis_attach (device_t); extern int ndis_shutdown (device_t); extern int ndis_detach (device_t); @@ -101,6 +103,9 @@ static device_method_t ndis_methods[] = { DEVMETHOD(device_suspend, ndis_suspend), DEVMETHOD(device_resume, ndis_resume), + /* Bus interface */ + DEVMETHOD(bus_get_resource_list, ndis_get_resource_list), + { 0, 0 } }; @@ -321,4 +326,15 @@ fail: return(error); } +static struct resource_list * +ndis_get_resource_list(dev, child) + device_t dev; + device_t child; +{ + struct ndis_softc *sc; + + sc = device_get_softc(dev); + return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev)); +} + #endif /* NDIS_PCI_DEV_TABLE */ diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index 4560e34d9fe7..0e6074426322 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -90,7 +90,9 @@ struct ndis_softc { struct resource *ndis_res_altmem; int ndis_altmem_rid; struct resource *ndis_res_am; /* attribute mem (pccard) */ + int ndis_am_rid; struct resource *ndis_res_cm; /* common mem (pccard) */ + struct resource_list ndis_rl; int ndis_rescnt; struct mtx ndis_mtx; struct mtx ndis_intrmtx;