Commit Graph

777 Commits

Author SHA1 Message Date
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