Implement NdisOpenFile()/NdisCloseFile()/NdisMapFile()/NdisUnmapFile().

By default, we search for files in /compat/ndis. This can be changed with
a systcl. These routines are used by some drivers which need to download
firmware or microcode into their respective devices during initialization.

Also, remove extraneous newlines from the 'built-in' sysctl/registry
variables.
This commit is contained in:
Bill Paul 2004-01-09 03:57:00 +00:00
parent bbd6d60a85
commit 431b5bd6e7
3 changed files with 124 additions and 9 deletions

View File

@ -305,17 +305,17 @@ ndis_create_sysctls(arg)
"NDIS API Version", "0x00050001", CTLFLAG_RD);
/* Bus type (PCI, PCMCIA, etc...) */
sprintf(buf, "%d\n", (int)sc->ndis_iftype);
sprintf(buf, "%d", (int)sc->ndis_iftype);
ndis_add_sysctl(sc, "BusType", "Bus Type", buf, CTLFLAG_RD);
if (sc->ndis_res_io != NULL) {
sprintf(buf, "0x%lx\n", rman_get_start(sc->ndis_res_io));
sprintf(buf, "0x%lx", rman_get_start(sc->ndis_res_io));
ndis_add_sysctl(sc, "IOBaseAddress",
"Base I/O Address", buf, CTLFLAG_RD);
}
if (sc->ndis_irq != NULL) {
sprintf(buf, "%lu\n", rman_get_start(sc->ndis_irq));
sprintf(buf, "%lu", rman_get_start(sc->ndis_irq));
ndis_add_sysctl(sc, "InterruptNumber",
"Interrupt Number", buf, CTLFLAG_RD);
}

View File

@ -65,6 +65,10 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <net/if.h>
#include <net/if_arp.h>
@ -100,6 +104,10 @@ __FBSDID("$FreeBSD$");
#define FUNC void(*)(void)
static struct mtx ndis_interlock;
static char ndis_filepath[MAXPATHLEN];
SYSCTL_STRING(_hw, OID_AUTO, ndis_filepath, CTLFLAG_RW, ndis_filepath,
MAXPATHLEN, "Path used by NdisOpenFile() to search for files");
__stdcall static void ndis_initwrap(ndis_handle,
ndis_driver_object *, void *, void *);
@ -272,6 +280,7 @@ ndis_libinit()
{
mtx_init(&ndis_interlock, "ndislock", MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE | MTX_DUPOK);
strcpy(ndis_filepath, "/compat/ndis");
return(0);
}
@ -2323,12 +2332,50 @@ ndis_open_file(status, filehandle, filelength, filename, highestaddr)
ndis_physaddr highestaddr;
{
char *afilename = NULL;
struct thread *td = curthread;
struct nameidata nd;
int flags, error;
struct vattr vat;
struct vattr *vap = &vat;
ndis_fh *fh;
char path[MAXPATHLEN];
ndis_unicode_to_ascii(filename->nus_buf, filename->nus_len, &afilename);
printf("ndis_open_file(\"%s\", %ju)\n", afilename,
highestaddr.np_quad);
ndis_unicode_to_ascii(filename->nus_buf,
filename->nus_len, &afilename);
sprintf(path, "%s/%s", ndis_filepath, afilename);
free(afilename, M_DEVBUF);
*status = NDIS_STATUS_FILE_NOT_FOUND;
fh = malloc(sizeof(ndis_fh), M_TEMP, M_NOWAIT);
if (fh == NULL) {
*status = NDIS_STATUS_RESOURCES;
return;
}
mtx_lock(&Giant);
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, td);
flags = FREAD;
error = vn_open(&nd, &flags, 0, -1);
if (error) {
mtx_unlock(&Giant);
*status = NDIS_STATUS_FILE_NOT_FOUND;
free(fh, M_TEMP);
return;
}
NDFREE(&nd, NDF_ONLY_PNBUF);
/* Get the file size. */
VOP_GETATTR(nd.ni_vp, vap, NOCRED, td);
VOP_UNLOCK(nd.ni_vp, 0, td);
mtx_unlock(&Giant);
fh->nf_vp = nd.ni_vp;
fh->nf_map = NULL;
*filehandle = fh;
*filelength = fh->nf_maplen = vap->va_size & 0xFFFFFFFF;
*status = NDIS_STATUS_SUCCESS;
return;
}
@ -2338,8 +2385,46 @@ ndis_map_file(status, mappedbuffer, filehandle)
void **mappedbuffer;
ndis_handle filehandle;
{
ndis_fh *fh;
struct thread *td = curthread;
int error, resid;
if (filehandle == NULL) {
*status = NDIS_STATUS_FAILURE;
return;
}
fh = (ndis_fh *)filehandle;
if (fh->nf_vp == NULL) {
*status = NDIS_STATUS_FAILURE;
return;
}
if (fh->nf_map != NULL) {
*status = NDIS_STATUS_ALREADY_MAPPED;
return;
}
fh->nf_map = malloc(fh->nf_maplen, M_DEVBUF, M_NOWAIT);
if (fh->nf_map == NULL) {
*status = NDIS_STATUS_RESOURCES;
return;
}
mtx_lock(&Giant);
error = vn_rdwr(UIO_READ, fh->nf_vp, fh->nf_map, fh->nf_maplen, 0,
UIO_SYSSPACE, 0, td->td_ucred, NOCRED, &resid, td);
mtx_unlock(&Giant);
if (error)
*status = NDIS_STATUS_FAILURE;
else {
*status = NDIS_STATUS_SUCCESS;
*mappedbuffer = fh->nf_map;
}
*status = NDIS_STATUS_ALREADY_MAPPED;
return;
}
@ -2347,6 +2432,14 @@ __stdcall static void
ndis_unmap_file(filehandle)
ndis_handle filehandle;
{
ndis_fh *fh;
fh = (ndis_fh *)filehandle;
if (fh->nf_map == NULL)
return;
free(fh->nf_map, M_DEVBUF);
fh->nf_map = NULL;
return;
}
@ -2354,6 +2447,28 @@ __stdcall static void
ndis_close_file(filehandle)
ndis_handle filehandle;
{
struct thread *td = curthread;
ndis_fh *fh;
if (filehandle == NULL)
return;
fh = (ndis_fh *)filehandle;
if (fh->nf_map != NULL) {
free(fh->nf_map, M_DEVBUF);
fh->nf_map = NULL;
}
if (fh->nf_vp == NULL)
return;
mtx_lock(&Giant);
vn_close(fh->nf_vp, FREAD, td->td_ucred, td);
mtx_unlock(&Giant);
fh->nf_vp = NULL;
free(fh, M_DEVBUF);
return;
}

View File

@ -4,6 +4,6 @@
KMOD= ndis
SRCS= subr_pe.c subr_ndis.c subr_hal.c subr_ntoskrnl.c kern_ndis.c
SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h card_if.h
SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h card_if.h vnode_if.h
.include <bsd.kmod.mk>