Commit Graph

868 Commits

Author SHA1 Message Date
Bill Paul
c5d019ec55 I'm a dumbass: the test in the MOD_SHUTDOWN case in ndis_modevent()
that checks to see if any devices are still in the devlist was reversed.
2004-03-22 18:34:37 +00:00
Bill Paul
e34e2a168a The Intel 2200BG NDIS driver does an alloca() of about 5000 bytes
when it associates with a net. Because FreeBSD's kstack size is only
2 pages by default, this blows the stack and causes a double fault.

To deal with this, we now create all our kthreads with 8 stack pages.
Also, we now run all timer callouts in the ndis swi thread (since
they would otherwise run in the clock ithread, whose stack is too
small). It happens that the alloca() in this case was occuring within
the interrupt handler, which was already running in the ndis swi
thread, but I want to deal with the callouts too just to be extra
safe.

NOTE: this will only work if you update vm_machdep.c with the change
I just committed. If you don't include this fix, setting the number
of stack pages with kthread_create() has essentially no effect.
2004-03-22 00:41:41 +00:00
Peter Wemm
95c6291685 Change (yet again, sorry!) the path of the 32 bit ld-elf.so.1. 2004-03-21 01:22:24 +00:00
Bill Paul
f6159e042d - Rewrite the timer and event API routines in subr_ndis.c so that they
are actually layered on top of the KeTimer API in subr_ntoskrnl.c, just
  as it is in Windows. This reduces code duplication and more closely
  imitates the way things are done in Windows.

- Modify ndis_encode_parm() to deal with the case where we have
  a registry key expressed as a hex value ("0x1") which is being
  read via NdisReadConfiguration() as an int. Previously, we tried
  to decode things like "0x1" with strtol() using a base of 10, which
  would always yield 0. This is what was causing problems with the
  Intel 2200BG Centrino 802.11g driver: the .inf file that comes
  with it has a key called RadioEnable with a value of 0x1. We
  incorrectly decoded this value to '0' when it was queried, hence
  the driver thought we wanted the radio turned off.

- In if_ndis.c, most drivers don't accept NDIS_80211_AUTHMODE_AUTO,
  but NDIS_80211_AUTHMODE_SHARED may not be right in some cases,
  so for now always use NDIS_80211_AUTHMODE_OPEN.

NOTE: There is still one problem with the Intel 2200BG driver: it
happens that the kernel stack in Windows is larger than the kernel
stack in FreeBSD. The 2200BG driver sometimes eats up more than 2
pages of stack space, which can lead to a double fault panic.
For the moment, I got things to work by adding the following to
my kernel config file:

options         KSTACK_PAGES=8

I'm pretty sure 8 is too big; I just picked this value out of a hat
as a test, and it happened to work, so I left it. 4 pages might be
enough. Unfortunately, I don't think you can dynamically give a
thread a larger stack, so I'm not sure how to handle this short of
putting a note in the man page about it and dealing with the flood
of mail from people who never read man pages.
2004-03-20 23:39:43 +00:00
John Baldwin
b7e23e826c - Replace wait1() with a kern_wait() function that accepts the pid,
options, status pointer and rusage pointer as arguments.  It is up to
  the caller to copyout the status and rusage to userland if needed.  This
  lets us axe the 'compat' argument and hide all that functionality in
  owait(), by the way.  This also cleans up some locking in kern_wait()
  since it no longer has to drop locks around copyout() since all the
  copyout()'s are deferred.
- Convert owait(), wait4(), and the various ABI compat wait() syscalls to
  use kern_wait() rather than wait1() or wait4().  This removes a bit
  more stackgap usage.

Tested on:	i386
Compiled on:	i386, alpha, amd64
2004-03-17 20:00:00 +00:00
Tim J. Robbins
7b0d017245 Use vfs_nmount() to mount linprocfs filesystems in linux_mount();
linprocfs doesn't support the old mount interface.
2004-03-16 09:05:56 +00:00
Tim J. Robbins
2ba9b76668 Correct size argument passed to copyinstr() in linux_mount(): mntfromname
and mntonname are both MNAMELEN characters long, not MFSNAMELEN.
2004-03-16 08:37:19 +00:00
Bill Paul
f79e9df73b Add vectors for _snprintf() and _vsnprintf() (redirected straight to
snprintf() and vsnprintf() in FreeBSD kernel land).

This is needed by the Intel Centrino 2200BG driver. Unfortunately, this
driver still doesn't work right with Project Evil even with this tweak,
but I'm unable to diagnose the problem since I don't have access to a
sample card.
2004-03-15 16:39:03 +00:00
Peter Wemm
73f3495386 Move the non-MD machine/dvcfg.h and machine/physio_proc.h to a common
MI area before they proliferate more.
2004-03-13 19:46:27 +00:00
Poul-Henning Kamp
651b11eaf2 Remove unused second arg to vfinddev().
Don't call addaliasu() on VBLK nodes.
2004-03-11 16:33:11 +00:00
Bill Paul
0bf7b204e3 Fix mind-o: sanity check in ndis_disable_ndis() is not sane. 2004-03-11 09:50:00 +00:00
Bill Paul
1e35c8564a Fix the problem with the Cisco Aironet 340 PCMCIA card. Most newer drivers
for Windows are deserialized miniports. Such drivers maintain their own
queues and do their own locking. This particular driver is not deserialized
though, and we need special support to handle it correctly.

Typically, in the ndis_rxeof() handler, we pass all incoming packets
directly to (*ifp->if_input)(). This in turn may cause another thread
to run and preempt us, and the packet may actually be processed and
then released before we even exit the ndis_rxeof() routine. The
problem with this is that releasing a packet calls the ndis_return_packet()
function, which hands the packet and its buffers back to the driver.
Calling ndis_return_packet() before ndis_rxeof() returns will screw
up the driver's internal queues since, not being deserialized,
it does no locking.

To avoid this problem, if we detect a serialized driver (by checking
the attribute flags passed to NdisSetAttributesEx(), we use an alternate
ndis_rxeof() handler, ndis_rxeof_serial(), which puts the call to
(*ifp->if_input)() on the NDIS SWI work queue. This guarantees the
packet won't be processed until after ndis_rxeof_serial() returns.

Note that another approach is to always copy the packet data into
another mbuf and just let the driver retain ownership of the ndis_packet
structure (ndis_return_packet() never needs to be called in this
case). I'm not sure which method is faster.
2004-03-11 09:40:00 +00:00
Bill Paul
a24cc63af9 Fix several issues related to the KeInitializeTimer() etc... API stuff
that I added recently:

- When a periodic timer fires, it's automatically re-armed. We must
  make sure to re-arm the timer _before_ invoking any caller-supplied
  defered procedure call: the DPC may choose to call KeCancelTimer(),
  and re-arming the timer after the DPC un-does the effect of the
  cancel.

- Fix similar issue with periodic timers in subr_ndis.c.

- When calling KeSetTimer() or KeSetTimerEx(), if the timer is
  already pending, untimeout() it first before timeout()ing
  it again.

- The old Atheros driver for the 5211 seems to use KeSetTimerEx()
  incorrectly, or at the very least in a very strange way that
  doesn't quite follow the Microsoft documentation. In one case,
  it calls KeSetTimerEx() with a duetime of 0 and a period of 5000.
  The Microsoft documentation says that negative duetime values
  are relative to the current time and positive values are absolute.
  But it doesn't say what's supposed to happen with positive values
  that less than the current time, i.e. absolute values that are
  in the past.

  Lacking any further information, I have decided that timers with
  positive duetimes that are in the past should fire right away (or
  in our case, after only 1 tick). This also takes care of the other
  strange usage in the Atheros driver, where the duetime is
  specified as 500000 and the period is 50. I think someone may
  have meant to use -500000 and misinterpreted the documentation.

- Also modified KeWaitForSingleObject() and KeWaitForMultipleObjects()
  to make the same duetime adjustment, since they have the same rules
  regarding timeout values.

- Cosmetic: change name of 'timeout' variable in KeWaitForSingleObject()
  and KeWaitForMultipleObjects() to 'duetime' to avoid senseless
  (though harmless) overlap with timeout() function name.

With these fixes, I can get the 5211 card to associate properly with
my adhoc net using driver AR5211.SYS version 2.4.1.6.
2004-03-10 07:43:11 +00:00
Bill Paul
d329ad6035 Add preliminary support for PCMCIA devices in addition to PCI/cardbus.
if_ndis.c has been split into if_ndis_pci.c and if_ndis_pccard.c.
The ndiscvt(8) utility should be able to parse device info for PCMCIA
devices now. The ndis_alloc_amem() has moved from kern_ndis.c to
if_ndis_pccard.c so that kern_ndis.c no longer depends on pccard.

NOTE: this stuff is not guaranteed to work 100% correctly yet. So
far I have been able to load/init my PCMCIA Cisco Aironet 340 card,
but it crashes in the interrupt handler. The existing support for
PCI/cardbus devices should still work as before.
2004-03-07 02:49:06 +00:00
John Baldwin
6074439965 kthread_exit() no longer requires Giant, so don't force callers to acquire
Giant just to call kthread_exit().

Requested by:	many
2004-03-05 22:42:17 +00:00
Bill Paul
51d22ccf42 - Some older Atheros drivers want KeInitializeTimer(), so implement it,
along with KeInitializeTimerEx(), KeSetTimer(), KeSetTimerEx(),
  KeCancelTimer(), KeReadStateTimer() and KeInitializeDpc(). I don't
  know for certain that these will make the Atheros driver happy since
  I don't have the card/driver combo needed to test it, but these are
  fairly independent so they shouldn't break anything else.

- Debugger() is present even in kernels without options DDB, so no
  conditional compilation is necessary (pointed out by bde).

- Remove the extra km_acquirecnt member that I added to struct kmutant
  and embed it within an unused portion of the structure instead, so that
  we don't make the structure larger than it's defined to be in Windows.
  I don't know what crack I was smoking when I decided it was ok to do
  this, but it's worn off now.
2004-03-04 23:04:02 +00:00
Bill Paul
a787e5ecf8 Add sanity checks to the ndis_packet and ndis_buffer pool handling
routines to guard against problems caused by (possibly) buggy drivers.

The RealTek 8180 wireless driver calls NdisFreeBuffer() to release
some of its buffers _after_ it's already called NdisFreeBufferPool()
to destroy the pool to which the buffers belong. In our implementation,
this error causes NdisFreeBuffer() to touch stale heap memory.

If you are running a release kernel, and hence have INVARIANTS et al
turned off, it turns out nothing happens. But if you're using a
development kernel config with INVARIANTS on, the malloc()/free()
sanity checks will scribble over the pool memory with 0xdeadc0de
once it's released so that any attempts to touch it will cause a
trap, and indeed this is what happens. It happens that I run 5.2-RELEASE
on my laptop, so when I tested the rtl8180.sys driver, it worked fine
for me, but people trying to run it with development systems checked
out or cvsupped from -current would get a page fault on driver load.

I can't find any reason why the NDISulator would cause the RealTek
driver to do the NdisFreeBufferPool() prematurely, and the same driver
obviously works with Windows -- or at least, it doesn't cause a crash:
the Microsoft documentation for NdisFreeBufferPool() says that failing
to return all buffers to the pool before calling  NdisFreeBufferPool()
causes a memory leak.

I've written to my contacts at RealTek asking them to check if this
is indeed a bug in their driver. In the meantime, these new sanity checks
will catch this problem and issue a warning rather than causing a trap.
The trick is to keep a count of outstanding buffers for each buffer pool,
and if the driver tries to call NdisFreeBufferPool() while there are still
buffers outstanding, we mark the pool for deletion and then defer
destroying it until after the last buffer has been reclaimed.
2004-03-04 00:17:14 +00:00
Bill Paul
db2585fd12 Add proper support for DbgPrint(): only print messages if bootverbose
is set, since some drivers with debug info can be very chatty.

Also implement DbgBreakPoint(), which is the Windows equivalent of
Debugger(). Unfortunately, this forces subr_ntoskrnl.c to include
opt_ddb.h.
2004-03-03 17:57:05 +00:00
Peter Wemm
fffaaed41a Regen (FWIW) 2004-02-21 23:38:58 +00:00
Peter Wemm
cdee486c65 Try and make the compat sigreturn prototypes closer to reality. 2004-02-21 23:37:33 +00:00
Peter Wemm
61aeb6a14d Add a note about the landmine in the middle of struct ia32_sigframe. 2004-02-21 23:36:31 +00:00
Peter Wemm
666dfc3f37 DOH!!! Fix signals for freebsd-4.x/i386 binaries. The ucontext has
different alignments due to the sse fxsave dump area.
2004-02-21 23:35:56 +00:00
Poul-Henning Kamp
816d62bbb9 Device megapatch 5/6:
Remove the unused second argument from udev2dev().

Convert all remaining users of makedev() to use udev2dev().  The
semantic difference is that udev2dev() will only locate a pre-existing
dev_t, it will not line makedev() create a new one.

Apart from the tiny well controlled windown in D_PSEUDO drivers,
there should no longer be any "anonymous" dev_t's in the system
now, only dev_t's created with make_dev() and make_dev_alias()
2004-02-21 21:32:15 +00:00
Bruce M Simpson
a1166f2439 Add BSD compatibility tty ioctls LINUX_TIOCSBRK and LINUX_TIOCCBRK. This
addition appears to allow VMware 3 Workstation to operate with nmdm(4)
as a virtual COM device.

Tested by:	Guido van Rooij
2004-02-19 12:38:12 +00:00
Bill Paul
18b59e2d02 Add vector for memmove() (currently aliased to memcpy()) a implement
ExInterlockedAddLargeStatistic().
2004-02-17 21:50:39 +00:00
Bill Paul
eaecffb942 More cleanups/fixes for the AMD Am1771 driver:
- When adding new waiting threads to the waitlist for an object,
  use INSERT_LIST_TAIL() instead of INSERT_LIST_HEAD() so that new
  waiters go at the end of the list instead of the beginning. When we
  wake up a synchronization object, only the first waiter is awakened,
  and this needs to be the first thread that actually waited on the object.

- Correct missing semicolon in INSERT_LIST_TAIL() macro.

- Implement lookaside lists correctly. Note that the Am1771 driver
  uses lookaside lists to manage shared memory (i.e. DMAable) buffers
  by specifying its own alloc and free routines. The Microsoft documentation
  says you should avoid doing this, but apparently this did not deter
  the developers at AMD from doing it anyway.

With these changes (which are the result of two straight days of almost
non-stop debugging), I think I finally have the object/thread handling
semantics implemented correctly. The Am1771 driver no longer crashes
unexpectedly during association or bringing the interface up.
2004-02-16 02:50:03 +00:00
Bill Paul
134164f8d3 Fix a problem with the way we schedule work on the NDIS worker threads.
The Am1771 driver will sometimes do the following:

- Some thread-> NdisScheduleWorkItem(some work)
- Worker thread -> do some work, KeWaitForSingleObject(some event)
- Some other thread -> NdisScheduleWorkItem(some other work)

When the second call to NdisScheduleWorkItem() occurs, the NDIS worker
thread (in our case ndis taskqueue) is suspended in KeWaitForSingleObject()
and waiting for an event to be signaled. This is different from when
the worker thread is idle and waiting on NdisScheduleWorkItem() to
send it more jobs. However, the ndis_sched() function in kern_ndis.c
always calls kthread_resume() when queueing a new job. Normally this
would be ok, but here this causes KeWaitForSingleObject() to return
prematurely, which is not what we want.

To fix this, the NDIS threads created by kern_ndis.c maintain a state
variable to indicate whether they are running (scanning the job list
and executing jobs) or sleeping (blocked on kthread_suspend() in
ndis_runq()), and ndis_sched() will only call kthread_resume() if
the thread is in the sleeping state.

Note that we can't just check to see if the thread is on the run queue:
in both cases, the thread is sleeping, but it's sleeping for different
reasons.

This stops the Am1771 driver from emitting various "NDIS ERROR" messages
and fixes some cases where it crashes.
2004-02-14 20:57:32 +00:00
Bill Paul
c7a61a03e8 Correct instance of *timeout that should have been timeout.
Noticed by: mlaier
2004-02-11 23:11:12 +00:00
Bill Paul
31d5c7fd4d Add yet more bulletproofing. This is to guard against the case that
ndis_init_nic() works one during attach, but fails later. Many things
will blow up if ndis_init_nic() fails and we aren't careful.
2004-02-11 21:53:40 +00:00
Bill Paul
eae7237c29 Add some bulletproofing: don't allow the ndis_get_info() or ndis_set_info()
routines to do anything except return error if the miniport adapter context
is not set (meaning we either having init'ed the driver yet, or the
initialization failed).

Also, be sure to NULL out the adapter context along with the
miniport characteristics pointers if calling the MiniportInitialize()
method fails.
2004-02-10 23:01:53 +00:00
Dag-Erling Smørgrav
38efe50cbd Remove VFS_STATFS() call which violated the lock order and wasn't
really required anyway.

PR:		kern/61994
Submitted by:	Bjoern Groenvall <bg@sics.se>
2004-02-09 20:33:42 +00:00
Bill Paul
59137ea864 Add stub implementations of KfLowerIrql() and KfRaiseIrql() (both of
which are _fastcall).
2004-02-09 19:13:58 +00:00
Bill Paul
ff853f37b7 Make NdisMMapIoSpace() guard against NULL/uninitialized resource pointers too. 2004-02-08 20:39:35 +00:00
Bill Paul
4dfa77161a Make NdisMMapIoSpace() handle the case where a device has both mem
and altmem ranges mapped.
2004-02-08 20:32:41 +00:00
Bill Paul
e21ffdf2ef Argh. kthread_suspend() when in P_KTHREAD context, tsleep() when not,
not the other way around.
2004-02-07 23:47:10 +00:00
Bill Paul
5a57707840 Correct an intance of mtx_pool_lock() that should have been mtx_pool_unlock(). 2004-02-07 22:19:20 +00:00
Poul-Henning Kamp
36095f4a2b I guess nobody has needed to use the SVR4olator to create device
nodes, or if they did, they're now locked away on the Kurt Gdel
memorial home for the numerically confused:

Don't cast a kernel pointer (from makedev(9)) to an integer (maj+minor combo).
2004-02-07 18:54:34 +00:00
Bill Paul
9ec5585585 Add a whole bunch of new stuff to make the driver for the AMD Am1771/Am1772
802.11b chipset work. This chip is present on the SMC2602W version 3
NIC, which is what was used for testing. This driver creates kernel
threads (12 of them!) for various purposes, and required the following
routines:

PsCreateSystemThread()
PsTerminateSystemThread()
KeInitializeEvent()
KeSetEvent()
KeResetEvent()
KeInitializeMutex()
KeReleaseMutex()
KeWaitForSingleObject()
KeWaitForMultipleObjects()
IoGetDeviceProperty()

and several more. Also, this driver abuses the fact that NDIS events
and timers are actually Windows events and timers, and uses NDIS events
with KeWaitForSingleObject(). The NDIS event routines have been rewritten
to interface with the ntoskrnl module. Many routines with incorrect
prototypes have been cleaned up.

Also, this driver puts jobs on the NDIS taskqueue (via NdisScheduleWorkItem())
which block on events, and this interferes with the operation of
NdisMAllocateSharedMemoryAsync(), which was also being put on the
NDIS taskqueue. To avoid the deadlock, NdisMAllocateSharedMemoryAsync()
is now performed in the NDIS SWI thread instead.

There's still room for some cleanups here, and I really should implement
KeInitializeTimer() and friends.
2004-02-07 06:44:13 +00:00
John Baldwin
28596eb0ea Regen. 2004-02-06 20:21:18 +00:00
John Baldwin
23816cc365 Sync up MP safe flags with global syscalls.master. This includes read(),
write(), close(), getpid(), setuid(), getuid(), svr4_sys_pause(),
svr4_sys_nice(), svr4_sys_kill(), svr4_sys_pgrpsys(), dup(), pipe(),
setgid(), getgid(), svr4_sys_signal(), umask(), getgroups(), setgroups(),
svr4_sys_sigprocmask(), svr4_sys_sigsuspend(), svr4_sys_sigaltstack(),
svr4_sys_sigaction(), svr4_sys_sigpending(), mprotect(), munmap(),
setegid(), seteuid(), setreuid(), setregid().
2004-02-06 20:07:33 +00:00
John Baldwin
0804ed5acc Regen. 2004-02-04 22:00:44 +00:00
John Baldwin
c3b612d935 The following compat syscalls are now mpsafe: linux_getrlimit(),
linux_setrlimit(), linux_old_getrlimit(), osf1_getrlimit(),
osf1_setrlimit(), svr4_sys_ulimit(), svr4_sys_setrlimit(),
svr4_sys_getrlimit(), svr4_sys_setrlimit64(), svr4_sys_getrlimit64(),
ibcs2_sysconf(), and ibcs2_ulimit().
2004-02-04 21:57:00 +00:00
John Baldwin
91d5354a2c Locking for the per-process resource limits structure.
- struct plimit includes a mutex to protect a reference count.  The plimit
  structure is treated similarly to struct ucred in that is is always copy
  on write, so having a reference to a structure is sufficient to read from
  it without needing a further lock.
- The proc lock protects the p_limit pointer and must be held while reading
  limits from a process to keep the limit structure from changing out from
  under you while reading from it.
- Various global limits that are ints are not protected by a lock since
  int writes are atomic on all the archs we support and thus a lock
  wouldn't buy us anything.
- All accesses to individual resource limits from a process are abstracted
  behind a simple lim_rlimit(), lim_max(), and lim_cur() API that return
  either an rlimit, or the current or max individual limit of the specified
  resource from a process.
- dosetrlimit() was renamed to kern_setrlimit() to match existing style of
  other similar syscall helper functions.
- The alpha OSF/1 compat layer no longer calls getrlimit() and setrlimit()
  (it didn't used the stackgap when it should have) but uses lim_rlimit()
  and kern_setrlimit() instead.
- The svr4 compat no longer uses the stackgap for resource limits calls,
  but uses lim_rlimit() and kern_setrlimit() instead.
- The ibcs2 compat no longer uses the stackgap for resource limits.  It
  also no longer uses the stackgap for accessing sysctl's for the
  ibcs2_sysconf() syscall but uses kernel_sysctl() instead.  As a result,
  ibcs2_sysconf() no longer needs Giant.
- The p_rlimit macro no longer exists.

Submitted by:	mtm (mostly, I only did a few cleanups and catchups)
Tested on:	i386
Compiled on:	alpha, amd64
2004-02-04 21:52:57 +00:00
Bill Paul
b783c5e972 Correct/improve the implementation of NdisMAllocateSharedMemoryAsync().
Since we have a worker thread now, we can actually do the allocation
asynchronously in that thread's context. Also, we need to return a
status value: if we're unable to queue up the async allocation, we
return NDIS_STATUS_FAILURE, otherwise we return NDIS_STATUS_PENDING
to indicate the allocation has been queued and will occur later.

This replaces the kludge where we just invoked the callback routine
right away in the current context.
2004-02-04 04:44:16 +00:00
Bill Paul
cea179a3fe Implement support for single packet sends. The Intel Centrino driver
that Asus provides on its CDs has both a MiniportSend() routine
and a MiniportSendPackets() function. The Microsoft NDIS docs say
that if a driver has both, only the MiniportSendPackets() routine
will be used. Although I think I implemented the support correctly,
calling the MiniportSend() routine seems to result in no packets going
out on the air, even though no error status is returned. The
MiniportSendPackets() function does work though, so at least in
this case it doesn't matter.

In if_ndis.c:ndis_getstate_80211(), if ndis_get_assoc() returns
an error, don't bother trying to obtain any other state since the
calls may fail, or worse cause the underlying driver to crash.

(The above two changes make the Asus-supplied Centrino work.)

Also, when calling the OID_802_11_CONFIGURATION OID, remember
to initialize the structure lengths correctly.

In subr_ndis.c:ndis_open_file(), set the current working directory
to rootvnode if we're in a thread that doesn't have a current
working directory set.
2004-02-03 07:39:23 +00:00
Daniel Eischen
51305c403f Regen. 2004-02-03 05:20:28 +00:00
Daniel Eischen
12ef052ac2 Sync with kern/syscalls.master. 2004-02-03 05:18:48 +00:00
Peter Wemm
996a568eda Regen 2004-01-28 23:45:48 +00:00
Peter Wemm
0e3a9619ad Add getitimer swab stub 2004-01-28 23:45:37 +00:00
Bill Paul
3f7266edd6 Implement NdisVirtualBufferAddress() and NdisVirtualBufferAddressSafe().
The RealTek 8180 driver seems to need this.
2004-01-27 08:10:34 +00:00
Bill Paul
581b0a24bc Reorganize the timer code a little and implement NdisInitializeTimer()
and NdisCancelTimer(). NdisInitializeTimer() doesn't accept an NDIS
miniport context argument, so we have to derive it from the timer
function context (which is supposed to be the adapter private context).
NdisCancelTimer is now an alias for NdisMCancelTimer().

Also add stubs for NdisMRegisterDevice() and NdisMDeregisterDevice().
These are no-ops for now, but will likely get fleshed in once I start
working on the Am1771/Am1772 wireless driver.
2004-01-26 21:21:53 +00:00
Bill Paul
6c272c0241 Avoid possible panic on shutdown: if there are still some devices
attached when shutting down, kill our kthreads, but don't destroy
the mutex pool and uma zone resources since the driver shutdown
routine may need them later.
2004-01-26 08:36:18 +00:00
Bill Paul
71a14876e1 Add structures and definitions for task offload (TCP/IP checksum,
IPSec, TCP large send).
2004-01-21 21:09:09 +00:00
Bill Paul
dda13ca0ef Make sure to trap failures correctly in ndis_get_info() and ndis_set_info(). 2004-01-21 19:14:52 +00:00
Robert Watson
679365e7b9 Reduce gratuitous includes: don't include jail.h if it's not needed.
Presumably, at some point, you had to include jail.h if you included
proc.h, but that is no longer required.

Result of:	self injury involving adding something to struct prison
2004-01-21 17:10:47 +00:00
Bill Paul
40e22f3c3f Add WDM major/minor #defines. 2004-01-19 20:45:27 +00:00
Bill Paul
4f7a266b2f Implement IofCompleteRequest() and IoIsWdmVersionAvailable().
Correct IofCallDriver(): it's fastcall, not stdcall.
Add vector to vsprintf().
2004-01-19 19:57:00 +00:00
Bill Paul
259c9c6054 Implement atoi() and atol(). Some drivers appear to need these. Note
that like most C library routines, these appear to be _cdecl in Windows.
2004-01-19 19:21:25 +00:00
Bill Paul
35f5524920 Eliminate some code duplication: since ndis_runq() and ndis_intq() were
basically the same function, compact them into a single loop which can
be used for both threads.
2004-01-19 18:56:31 +00:00
Bill Paul
ed880bb60f Convert from using taskqueue_swi to using private kernel threads. The
problem with using taskqueue_swi is that some of the things we defer
into threads might block for up to several seconds. This is an unfriendly
thing to do to taskqueue_swi, since it is assumed the taskqueue threads
will execute fairly quickly once a task is submitted. Reorganized the
locking in if_ndis.c in the process.

Cleaned up ndis_write_cfg() and ndis_decode_parm() a little.
2004-01-18 22:57:11 +00:00
David E. O'Brien
a971a19262 The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
According to the Windows DDK header files, KSPIN_LOCK is defined like this:
	typedef ULONG_PTR KSPIN_LOCK;

From basetsd.h (SDK, Feb. 2003):
	typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
	typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
	typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;

The keyword __int3264 specifies an integral type that has the following
properties:
 + It is 32-bit on 32-bit platforms
 + It is 64-bit on 64-bit platforms
 + It is 32-bit on the wire for backward compatibility.
   It gets truncated on the sending side and extended appropriately
   (signed or unsigned) on the receiving side.

Thus register_t seems the proper mapping onto FreeBSD for spin locks.
2004-01-16 02:07:04 +00:00
Bill Paul
ece759a4da The definition for __stdcall logically belongs in pe_var.h, but
the definitions for NDIS_BUS_SPACE_IO and NDIS_BUS_SPACE_MEM logically
belong in hal_var.h. At least, that's my story, and I'm sticking to it.

Also, remove definition of __stdcall from if_ndis.c now that it's pulled
in from pe_var.h.
2004-01-15 21:31:49 +00:00
David E. O'Brien
75280cae75 Create NDIS_BUS_SPACE_{IO,MEM} to abstract MD BUS_SPACE macros.
Provide appropriate definitions for i386 and AMD64.
2004-01-15 19:34:56 +00:00
Bill Paul
70e8088cde Implement NdisCopyFromPacketToPacket() and NdisCopyFromPacketToPacketSafe().
I only have one driver that references this routine (for the 3Com 3cR990)
and it never gets called, but just in case, here it is.
2004-01-15 07:42:26 +00:00
Don Lewis
ff5f695e78 VOP_GETATTR() wants the vnode passed to it to be locked. Instead
of adding the code to lock and unlock the vnodes and taking care
to avoid deadlock, simplify linux_emul_convpath() by comparing the
vnode pointers directly instead of comparing their va_fsid and
va_fileid attributes.  This allows the removal of the calls to
VOP_GETATTR().
2004-01-14 22:38:03 +00:00
Bill Paul
fb1ad3a85a mp_ncpus is always defined now, so no need to do an #ifdef SMP in
ndis_cpu_cnt().
2004-01-14 01:16:14 +00:00
David E. O'Brien
a4464dd7ea AMD64 has a single MS-Win calling convention, so provide an empty __stdcall.
Centralize the definition to make it easier to change.
2004-01-13 22:49:45 +00:00
David E. O'Brien
c4f7bbcfa9 Use 'vm_offset_t' rather than 'u_int32_t'.
Tested on:	AMD64
Reviewed by:	wpaul
2004-01-13 22:26:37 +00:00
David E. O'Brien
77346fe71a AMD64 has a single MS-Win calling convention, so provide an empty __stdcall. 2004-01-13 22:23:47 +00:00
Bill Paul
fef7cebe7b Implement some more unicode handling routines. This will hopefully bring
us closer to being able to run the Intel PRO/Wireless 5000 driver.
2004-01-13 09:12:47 +00:00
Bill Paul
2333afc31e Loosen up the range test in ndis_register_ioport(). Allow drivers to
map ranges that are smaller than what our resource manager code knows
is available, rather than requiring that they match exactly. This
fixes a problem with the Intel PRO/1000 gigE driver: it wants to map
a range of 32 I/O ports, even though some chips appear set up to
decode a range of 64. With this fix, it loads and runs correctly.
2004-01-13 01:12:28 +00:00
Bill Paul
22c48a5f23 Ugh. I am not having a good day. Remove debugging #ifdef that accidentally
crept into the last commit.
2004-01-12 21:40:05 +00:00
Bill Paul
716b5b3580 Ugh. Last commit went horribly wrong. Back out changes to subr_ntoskrnl.c,
make sure if_ndis.c really gets checked in this time.
2004-01-12 21:04:43 +00:00
Bill Paul
958e09f637 In if_ndis.c:ndis_intr(), be a bit more intelligent about squelching
unexpected interrupts. If an interrupt is triggered and we're not
finished initializing yet, bail. If we have finished initializing,
but IFF_UP isn't set yet, drain the interrupt with ndis_intr() or
ndis_disable_intr() as appropriate, then return _without_ scheduling
ndis_intrtask().

In kern_ndis.c:ndis_load_driver() only relocate/dynalink a given driver
image once. Trying to relocate an image that's already been relocated
will trash the image. We poison a part of the image header that we
don't otherwise need with a magic value to indicate it's already been
fixed up. This fixes the case where there are multiple units of the
same kind of device.
2004-01-12 21:00:48 +00:00
Bill Paul
60a9ef3d9c Merge in some changes submitted by Brian Feldman. Among other things,
these add support for listing BSSIDs via wicontrol -l. I added code
to call OID_802_11_BSSID_LIST_SCAN to allow scanning for any nearby
wirelsss nets.

Convert from using individual mutexes to a mutex pool, created in
subr_ndis.c. This deals with the problem of drivers creating locks
in their DriverEntry() routines which might get trashed later.

Put some messages under IFF_DEBUG.
2004-01-12 03:49:20 +00:00
Robert Watson
09dbf7a214 Correct for proper vn_fullpath() failure mode: "== -1" -> "!= 0"
Discussed with:	des
2004-01-12 03:14:37 +00:00
Bill Paul
e6003d0862 The private data section of ndis_packets has a 'packet flags' byte
which has two important flags in it: the 'allocated by NDIS' flag
and the 'media specific info present' flag. There are two Windows macros
for getting/setting media specific info fields within the ndis_packet
structure which can behave improperly if these flags are not initialized
correctly when a packet is allocated. It seems the correct thing
to do is always set the NDIS_PACKET_ALLOCATED_BY_NDIS flag on
all newly allocated packets.

This fixes the crashes with the Intel Centrino wireless driver.
My sample card now seems to work correctly.

Also, fix a potential LOR involving ndis_txeof() in if_ndis.c.
2004-01-09 06:53:49 +00:00
Bill Paul
431b5bd6e7 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.
2004-01-09 03:57:00 +00:00
Bill Paul
3e1b0c31a1 Correct the definition of the ndis_miniport_interrupt structure:
the ni_dpccountlock member is an ndis_kspin_lock, not an
ndis_spin_lock (the latter is too big).

Run if_ndis.c:ndis_tick() via taskqueue_schedule(). Also run
ndis_start() via taskqueue in certain circumstances.

Using these tweaks, I can now get the Broadcom BCM5701 NDIS
driver to load and run. Unfortunately, the version I have seems
to suffer from the same bug as the SMC 83820 driver, which is
that it creates a spinlock during its DriverEntry() routine.
I'm still debating the right way to deal with this.
2004-01-08 10:44:37 +00:00
Bill Paul
0fba60013b Correct and simplify the implementation of RtlEqualUnicodeString(). 2004-01-07 20:31:51 +00:00
Bill Paul
9163fadb70 It appears drivers may call NdisWriteErrorLogEntry() with locks
held. However, if we need to translate a unicode message table message,
ndis_unicode_to_ascii() might malloc() some memory, which causes
a warning from witness. Avoid this by using some stack space to hold
the translated message. (Also bounds check to make sure we don't
overrun the stack buffer.)
2004-01-07 19:26:47 +00:00
Bill Paul
e157128762 Use atomic ops for the interlocked increment and decrement routines
in subr_ndis and subr_ntoskrnl. This is faster and avoids potential
LOR whinage from witness (an LOR couldn't happen with the old code
since the interlocked inc/dec routines could not sleep with a lock
held, but this will keep witness happy and it's more efficient
anyway. I think.)
2004-01-07 07:29:27 +00:00
Bill Paul
e3c8d8194c In subr_ndis.c: correct ndis_interlock_inc() and ndis_interlock_dec()
so we increment the right thing. (All work and not enough parens
make Bill something something...) This makes the RealTek 8139C+
driver work correctly.

Also fix some mtx_lock_spin()s and mtx_unlock_spin()s that should
have been just plain mtx_lock()s and mtx_unlock()s.

In kern_ndis.c: remove duplicate code from ndis_send_packets() and
just call the senddone handler (ndis_txeof()).
2004-01-07 06:15:56 +00:00
Bill Paul
1cfaf27e2b Clean up pe_get_message(). Allow the caller to obtain the resource
flag so that it can see if the message string is unicode or not and
do the conversion itself rather than doing it in subr_pe.c. This
prevents subr_pe.c from being dependent on subr_ndis.c.
2004-01-06 18:06:54 +00:00
Bill Paul
09bebfadee - Add pe_get_message() and pe_get_messagetable() for processing
the RT_MESSAGETABLE resources that some driver binaries have.
  This allows us to print error messages in ndis_syslog().

- Correct the implementation of InterlockedIncrement() and
  InterlockedDecrement() -- they return uint32_t, not void.

- Correct the declarations of the 64-bit arithmetic shift
  routines in subr_ntoskrnl.c (_allshr, allshl, etc...). These
  do not follow the _stdcall convention: instead, they appear
  to be __attribute__((regparm(3)).

- Change the implementation of KeInitializeSpinLock(). There is
  no complementary KeFreeSpinLock() function, so creating a new
  mutex on each call to KeInitializeSpinLock() leaks resources
  when a driver is unloaded. For now, KeInitializeSpinLock()
  returns a handle to the ntoskrnl interlock mutex.

- Use a driver's MiniportDisableInterrupt() and MiniportEnableInterrupt()
  routines if they exist. I'm not sure if I'm doing this right
  yet, but at the very least this shouldn't break any currently
  working drivers, and it makes the Intel PRO/1000 driver work.

- In ndis_register_intr(), save some state that might be needed
  later, and save a pointer to the driver's interrupt structure
  in the ndis_miniport_block.

- Save a pointer to the driver image for use by ndis_syslog()
  when it calls pe_get_message().
2004-01-06 07:09:26 +00:00
Bill Paul
137bcec3f9 Modify if_ndis.c so that the MiniportISR function runs in ndis_intr()
and MiniportHandleInterrupt() is fired off later via a task queue in
ndis_intrtask(). This more accurately follows the NDIS interrupt handling
model, where the ISR does a minimal amount of work in interrupt context
and the handler is defered and run at a lower priority.

Create a separate ndis_intrmtx mutex just for the guarding the ISR.

Modify NdisSynchronizeWithInterrupt() to aquire the ndis_intrmtx
mutex before invoking the synchronized procedure. (The purpose of
this function is to provide mutual exclusion for code that shares
variables with the ISR.)

Modify NdisMRegisterInterrupt() to save a pointer to the miniport
block in the ndis_miniport_interrupt structure so that
NdisSynchronizeWithInterrupt() can grab it later and derive
ndis_intrmtx from it.
2004-01-04 21:22:25 +00:00
Bill Paul
209dd08745 Implement NdisScheduleWorkItem() and RtlCompareMemory().
Also, call the libinit and libfini routines from the modevent
handler in kern_ndis.c. This simplifies the initialization a little.
2004-01-04 07:47:33 +00:00
Bill Paul
8bf6313448 In ndis_attach(), report the NDIS API level that the Windows miniport
driver was compiled with.

Remove debug printf from ndis_assicn_pcirsc(). It doesn't serve
much purpose.

Implement NdisMIndicateStatus() and NdisMIndicateStatusComplete()
as functions in subr_ndis.c. In NDIS 4.0, they were functions. In
NDIS 5.0 and later, they're just macros.

Allocate a few extra packets/buffers beyond what the driver asks
for since sometimes it seems they can lie about how many they really
need, and some extra stupid ones don't check to see if NdisAllocatePacket()
and/or NdisAllocateBuffer() actually succeed.
2004-01-04 03:00:21 +00:00
Bill Paul
3f4ea6aea4 In if_ndis.c:ndis_attach(), temporarily set the IFF_UP flag while
calling the haltfunc. If an interrupt is triggered by the init
or halt func, the IFF_UP flag must be set in order for us to be able
to service it.

In kern_ndis.c: implement a handler for NdisMSendResourcesAvailable()
(currently does nothing since we don't really need it).

In subr_ndis.c:
	- Correct ndis_init_string() and ndis_unicode_to_ansi(),
	  which were both horribly broken.
        - Implement NdisImmediateReadPciSlotInformation() and
	  NdisImmediateWritePciSlotInformation().
	- Implement NdisBufferLength().
	- Work around my first confirmed NDIS driver bug.
	  The SMC 9462 gigE driver (natsemi 83820-based copper)
	  incorrectly creates a spinlock in its DriverEntry()
	  routine and then destroys it in its MiniportHalt()
	  handler. This is wrong: spinlocks should be created
	  in MiniportInit(). In a Windows environment, this is
	  often not a problem because DriverEntry()/MiniportInit()
	  are called once when the system boots and MiniportHalt()
	  or the shutdown handler is called when the system halts.

With this stuff in place, this driver now seems to work:

ndis0: <SMC EZ Card 1000> port 0xe000-0xe0ff mem 0xda000000-0xda000fff irq 10 at device 9.0 on pci0
ndis0: assign PCI resources...
ndis_open_file("FLASH9.hex", 18446744073709551615)
ndis0: Ethernet address: 00:04:e2:0e:d3:f0
2004-01-03 13:20:30 +00:00
Bill Paul
6fc4b10f58 subr_hal.c: implement WRITE_PORT_BUFFER_xxx() and READ_PORT_BUFFER_xxx()
subr_ndis.c: implement NdisDprAllocatePacket() and NdisDprFreePacket()
(which are aliased to NdisAllocatePacket() and NdisFreePacket()), and
bump the value we return in ndis_mapreg_cnt() to something ridiculously
large, since some drivers apparently expect to be able to allocate
way more than just 64.

These changes allow the Level 1 1000baseSX driver to work for
the following card:

ndis0: <SMC TigerCard 1000 Adapter> port 0xe000-0xe0ff mem 0xda004000-0xda0043ff irq 10 at device 9.0 on pci0
ndis0: Ethernet address: 00:e0:29:6f:cc:04

This is already supported by the lge(4) driver, but I decided
to take a try at making the Windows driver that came with it work too,
since I still had the floppy diskette for it lying around.
2004-01-03 09:20:48 +00:00
Bill Paul
0a9e1a08a1 Tweak ndiscvt to support yet another flavor of .INF files (look for
the NTx86 section decoration).

subr_ndis.c: correct the behavior of ndis_query_resources(): if the
caller doesn't provide enough space to return the resources, tell it
how much it needs to provide and return an error.

subr_hal.c & subr_ntoskrnl.c: implement/stub a bunch of new routines;

ntoskrnl:

KefAcquireSpinLockAtDpcLevel
KefReleaseSpinLockFromDpcLevel
MmMapLockedPages
InterlockedDecrement
InterlockedIncrement
IoFreeMdl
KeInitializeSpinLock

HAL:

KfReleaseSpinLock
KeGetCurrentIrql
KfAcquireSpinLock

Lastly, correct spelling of "_aullshr" in the ntoskrnl functable.
2004-01-03 02:25:21 +00:00
Alan Cox
277b62040d Lock the traversal of the vm object list. Use TAILQ_FOREACH consistently. 2004-01-02 19:29:31 +00:00
Bill Paul
f07cc658a4 Clean up ndiscvt a bit (leaving out the -i flag didn't work) and add
copyrights to the inf parser files.

Add a -n flag to ndiscvt to allow the user to override the default
device name of NDIS devices. Instead of "ndis0, ndis1, etc..."
you can have "foo0, foo1, etc..." This allows you to have more than
one kind of NDIS device in the kernel at the same time.

Convert from printf() to device_printf() in if_ndis.c, kern_ndis.c
and subr_ndis.c.

Create UMA zones for ndis_packet and ndis_buffer structs allocated
on transmit. The zones are created and destroyed in the modevent
handler in kern_ndis.c.

printf() and UMA changes submitted by green@freebsd.org
2004-01-02 04:31:06 +00:00
Bill Paul
835e1e84d2 - subr_ntoskrnl.c: improve the _fastcall hack based on suggestions from
peter and jhb: use __volatile__ to prevent gcc from possibly reordering
  code, use a null inline instruction instead of a no-op movl (I would
  have done this myself if I knew it was allowed) and combine two register
  assignments into a single asm statement.
- if_ndis.c: set the NDIS_STATUS_PENDING flag on all outgoing packets
  in ndis_start(), make the resource allocation code a little smarter
  about how it selects the altmem range, correct a lock order reversal
  in ndis_tick().
2003-12-31 04:12:57 +00:00
Bill Paul
8695252e67 - Add new 802.11 OID information obtained from NDIS 5.1 update to
ndis_var.h
- In kern_ndis.c:ndis_send_packets(), avoid dereferencing NULL pointers
  created when the driver's send routine immediately calls the txeof
  handler (which releases the packets for us anyway).
- In if_ndis.c:ndis_80211_setstate(), implement WEP support.
2003-12-30 21:33:26 +00:00
Bill Paul
265745a5bf Rework resource allocation. Replace the "feel around like a blind man"
method with something a little more intelligent: use BUS_GET_RESOURCE_LIST()
to run through all resources allocated to us and map them as needed. This
way we know exactly what resources need to be mapped and what their RIDs
are without having to guess. This simplifies both ndis_attach() and
ndis_convert_res(), and eliminates the unfriendly "ndisX: couldn't map
<foo>" messages that are sometimes emitted during driver load.
2003-12-29 23:51:59 +00:00
Bill Paul
6162a5f91a Implement NdisInitUnicodeString(). 2003-12-28 21:36:03 +00:00
Bill Paul
f123dd84fb Remove the sanity test in ndis_adjust_buflen(). I'm not sure what the
nb_size field in an ndis_buffer is meant to represent, but it does not
represent the original allocation size, so the sanity check doesn't
make any sense now that we're using the Windows-mandated initialization
method.

Among other things, this makes the following card work with the
NDISulator:

ndis0: <NETGEAR PA301 Phoneline10X PCI Adapter> mem 0xda004000-0xda004fff irq 10 at device 9.0 on pci0

This is that notoriously undocumented 10Mbps HomePNA Broadcom chipset
that people wanted support for many moons ago. Sadly, the only other
HomePNA NIC I have handy is a 1Mbps device, so I can't actually do
any 10Mbps performance tests, but it talks to my 1Mbps ADMtek card
just fine.
2003-12-28 21:28:36 +00:00
Bill Paul
ca989c99d0 Attempt to handle the status field in the ndis_packet oob area correctly.
For received packets, an status of NDIS_STATUS_RESOURCES means we need
to copy the packet data and return the ndis_packet to the driver immediatel.
NDIS_STATUS_SUCCESS means we get to hold onto the packet, but we have
to set the status to NDIS_STATUS_PENDING so the driver knows we're
going to hang onto it for a while.

For transmit packets, NDIS_STATUS_PENDING means the driver will
asynchronously return the packet to us via the ndis_txeof() routine,
and NDIS_STATUS_SUCCESS means the driver sent the frame, and NDIS
(i.e. the OS) retains ownership of the packet and can free it
right away.
2003-12-26 07:01:05 +00:00
Bill Paul
1e642180fe Back out the last batch of changes until I have a chance to properly
evaluate them. Whatever they're meant to do, they're doing it wrong.

Also:

- Clean up last bits of NULL fallout in subr_pe
- Don't let ndis_ifmedia_sts() do anything if the IFF_UP flag isn't set
- Implement NdisSystemProcessorCount() and NdisQueryMapRegisterCount().
2003-12-26 03:31:34 +00:00