when we create a PDO, the driver_object associated with it is that
of the parent driver, not the driver we're trying to attach. For
example, if we attach a PCI device, the PDO we pass to the NdisAddDevice()
function should contain a pointer to fake_pci_driver, not to the NDIS
driver itself. For PCI or PCMCIA devices this doesn't matter because
the child never needs to talk to the parent bus driver, but for USB,
the child needs to be able to send IRPs to the parent USB bus driver, and
for that to work the parent USB bus driver has to be hung off the PDO.
This involves modifying windrv_lookup() so that we can search for
bus drivers by name, if necessary. Our fake bus drivers attach themselves
as "PCI Bus," "PCCARD Bus" and "USB Bus," so we can search for them
using those names.
The individual attachment stubs now create and attach PDOs to the
parent bus drivers instead of hanging them off the NDIS driver's
object, and in if_ndis.c, we now search for the correct driver
object depending on the bus type, and use that to find the correct PDO.
With this fix, I can get my sample USB ethernet driver to deliver
an IRP to my fake parent USB bus driver's dispatch routines.
- Add stub modules for USB support: subr_usbd.c, usbd_var.h and
if_ndis_usb.c. The subr_usbd.c module is hooked up the build
but currently doesn't do very much. It provides the stub USB
parent driver object and a dispatch routine for
IRM_MJ_INTERNAL_DEVICE_CONTROL. The only exported function at
the moment is USBD_GetUSBDIVersion(). The if_ndis_usb.c stub
compiles, but is not hooked up to the build yet. I'm putting
these here so I can keep them under source code control as I
flesh them out.
Ville-Pertti Keinonen (will at exomi dot comohmygodnospampleasekthx)
deserves a big thanks for submitting initial patches to make it
work. I have mangled his contributions appropriately.
The main gotcha with Windows/x86-64 is that Microsoft uses a different
calling convention than everyone else. The standard ABI requires using
6 registers for argument passing, with other arguments on the stack.
Microsoft uses only 4 registers, and requires the caller to leave room
on the stack for the register arguments incase the callee needs to
spill them. Unlike x86, where Microsoft uses a mix of _cdecl, _stdcall
and _fastcall, all routines on Windows/x86-64 uses the same convention.
This unfortunately means that all the functions we export to the
driver require an intermediate translation wrapper. Similarly, we have
to wrap all calls back into the driver binary itself.
The original patches provided macros to wrap every single routine at
compile time, providing a secondary jump table with a customized
wrapper for each exported routine. I decided to use a different approach:
the call wrapper for each function is created from a template at
runtime, and the routine to jump to is patched into the wrapper as
it is created. The subr_pe module has been modified to patch in the
wrapped function instead of the original. (On x86, the wrapping
routine is a no-op.)
There are some minor API differences that had to be accounted for:
- KeAcquireSpinLock() is a real function on amd64, not a macro wrapper
around KfAcquireSpinLock()
- NdisFreeBuffer() is actually IoFreeMdl(). I had to change the whole
NDIS_BUFFER API a bit to accomodate this.
Bugs fixed along the way:
- IoAllocateMdl() always returned NULL
- kern_windrv.c:windrv_unload() wasn't releasing private driver object
extensions correctly (found thanks to memguard)
This has only been tested with the driver for the Broadcom 802.11g
chipset, which was the only Windows/x86-64 driver I could find.
and wd80x3 support. Make the obscure ISA cards optional, and add
those options to NOTES on i386 (note: the ifdef around the whole code
is for module building). Tweak pc98 ed support to include wd80x3 too.
Add goo for alpha too.
The affected cards are the 3Com 3C503, HP LAN+ and SIC (whatever that
is). I couldn't find any of these for sale on ebay, so they are
untested. If you have one of these cards, and send it to me, I'll
ensure that you have no future problems with it...
Minor cleanups as well by using functions rather than cut and paste
code for some probing operations (where the function call overhead is
lost in the noise).
Remove use of kvtop, since they aren't required anymore. This driver
needs to get its memory mapped act together, however, and use bus
space. It doesn't right now.
This reduces the size of if_ed.ko from about 51k to 33k on my laptop.
Windows DRIVER_OBJECT and DEVICE_OBJECT mechanism so that we can
simulate driver stacking.
In Windows, each loaded driver image is attached to a DRIVER_OBJECT
structure. Windows uses the registry to match up a given vendor/device
ID combination with a corresponding DRIVER_OBJECT. When a driver image
is first loaded, its DriverEntry() routine is invoked, which sets up
the AddDevice() function pointer in the DRIVER_OBJECT and creates
a dispatch table (based on IRP major codes). When a Windows bus driver
detects a new device, it creates a Physical Device Object (PDO) for
it. This is a DEVICE_OBJECT structure, with semantics analagous to
that of a device_t in FreeBSD. The Windows PNP manager will invoke
the driver's AddDevice() function and pass it pointers to the DRIVER_OBJECT
and the PDO.
The AddDevice() function then creates a new DRIVER_OBJECT structure of
its own. This is known as the Functional Device Object (FDO) and
corresponds roughly to a private softc instance. The driver uses
IoAttachDeviceToDeviceStack() to add this device object to the
driver stack for this PDO. Subsequent drivers (called filter drivers
in Windows-speak) can be loaded which add themselves to the stack.
When someone issues an IRP to a device, it travel along the stack
passing through several possible filter drivers until it reaches
the functional driver (which actually knows how to talk to the hardware)
at which point it will be completed. This is how Windows achieves
driver layering.
Project Evil now simulates most of this. if_ndis now has a modevent
handler which will use MOD_LOAD and MOD_UNLOAD events to drive the
creation and destruction of DRIVER_OBJECTs. (The load event also
does the relocation/dynalinking of the image.) We don't have a registry,
so the DRIVER_OBJECTS are stored in a linked list for now. Eventually,
the list entry will contain the vendor/device ID list extracted from
the .INF file. When ndis_probe() is called and detectes a supported
device, it will create a PDO for the device instance and attach it
to the DRIVER_OBJECT just as in Windows. ndis_attach() will then call
our NdisAddDevice() handler to create the FDO. The NDIS miniport block
is now a device extension hung off the FDO, just as it is in Windows.
The miniport characteristics table is now an extension hung off the
DRIVER_OBJECT as well (the characteristics are the same for all devices
handled by a given driver, so they don't need to be per-instance.)
We also do an IoAttachDeviceToDeviceStack() to put the FDO on the
stack for the PDO. There are a couple of fake bus drivers created
for the PCI and pccard buses. Eventually, there will be one for USB,
which will actually accept USB IRP.s
Things should still work just as before, only now we do things in
the proper order and maintain the correct framework to support passing
IRPs between drivers.
Various changes:
- corrected the comments about IRQL handling in subr_hal.c to more
accurately reflect reality
- update ndiscvt to make the drv_data symbol in ndis_driver_data.h a
global so that if_ndis_pci.o and/or if_ndis_pccard.o can see it.
- Obtain the softc pointer from the miniport block by referencing
the PDO rather than a private pointer of our own (nmb_ifp is no
longer used)
- implement IoAttachDeviceToDeviceStack(), IoDetachDevice(),
IoGetAttachedDevice(), IoAllocateDriverObjectExtension(),
IoGetDriverObjectExtension(), IoCreateDevice(), IoDeleteDevice(),
IoAllocateIrp(), IoReuseIrp(), IoMakeAssociatedIrp(), IoFreeIrp(),
IoInitializeIrp()
- fix a few mistakes in the driver_object and device_object definitions
- add a new module, kern_windrv.c, to handle the driver registration
and relocation/dynalinkign duties (which don't really belong in
kern_ndis.c).
- made ndis_block and ndis_chars in the ndis_softc stucture pointers
and modified all references to it
- fixed NdisMRegisterMiniport() and NdisInitializeWrapper() so they
work correctly with the new driver_object mechanism
- changed ndis_attach() to call NdisAddDevice() instead of ndis_load_driver()
(which is now deprecated)
- used ExAllocatePoolWithTag()/ExFreePool() in lookaside list routines
instead of kludged up alloc/free routines
- added kern_windrv.c to sys/modules/ndis/Makefile and files.i386.
copies arguments into the kernel space and one that operates
completely in the kernel space;
o use kernel-only version of execve(2) to kill another stackgap in
linuxlator/i386.
Obtained from: DragonFlyBSD (partially)
MFC after: 2 weeks
to elide. This is a somewhat more convenient way of specifying in
e.g. make.conf a list of modules you know you will never need.
PR: kern/76225
Submitted by: David Yeske <dyeske@yahoo.com>
MFC after: 2 weeks
the given providers. Without even one of the configured components there
should be no way to get the secret.
Supported by: WHEEL Sp. z o.o.
http://www.wheel.pl
Silence on: net@, current@, hackers@.
No objections: joerg
Requested by: by many (mostly Cronyx) users for a long long time.
MFC after: 10 days
PR: kern/21771, kern/66348
the ISA and CBUS (called isa on pc98) attachments. Eliminate all PC98
ifdefs in the process (the driver in pc98/pc98/mse.c was a copy of the one
in i386/isa/mse.c with PC98 ifdefs). Create a module for this driver.
I've tested this my PC-9821RaS40 with moused. I've not tested this on i386
because I have no InPort cards, or similar such things. NEC standardized
on bus mice very early, long before ps/2 mice ports apeared, so all PC-98
machines supported by FreeBSD/pc98 have bus mice, I believe.
Reviewed by: nyan-san
without ever being changed to actually work with an i8251. Nobody is
working on this either at the moment, so it's not about to change
soon.
When the code necessary to support the i8251 is committed, this can
be reverted again.
- The claim in the commit log of rev. 1.11 of dev/uart/uart_cpu_sparc64.c
etc. that UARTs are the only relevant ISA devices on sparc64 turned out
to be false. While there are sparc64 models where UARTs are the only
devices on the ISA bus there are in fact also low-cost models where all
devices traditionally found on the EBus are hooked up to the ISA bus.
There are also models that use a mix between EBus and ISA devices with
things like an AT keyboard controller and other rather interesting
devices that we might want to support in the futute hook up to the ISA
bus.
In order to not need to add sparc64 specific device_identify methods to
all of the respective ISA drivers and also not add OFW specific code to
the common ISA code make the sparc64 ISA bus code fake up PnP devices so
most ISA drivers probe their devices without further changes.
Unfortunately Sun doesn't adhere to the ISA bindings defined in IEEE
1275-1994 for the properties of most of the ISA devices which would
allow to obtain the vendor and logical IDs from their properties. So we
we just use a simple table which maps the name properties to PnP IDs.
This could be done in a more sophisticated way but I courrently don't
see the need for this. [1]
- Add the children with fully mapped and specified resources (in the OFW
sense) similar to what is done in the EBus code for the IRQ resources
of the children as adjusting the resources and the resource list entries
respectively in isa_alloc_resource() as done perviously causes trouble
with drivers which use rman_get_start(), pass-through or allocate and
release resources multiple times, etc.
Adjusting the resources might be better off in a bus_activate_resource
method but the common ISA code currently doesn't allow for an
isa_activate_resource(). [2]
With this change:
- ppbus(4) and lpt(4) attach and work (modulo ECP mode, which requires
real ISADMA code but it currently only consists of stubs on sparc64).
- atkbdc(4) and atkbdc(4) attach, no further testing done.
- fdc(4) itself attaches but causes a hang while attaching fd0 also
when is DMA disabled, further work in fdc(4) is required here as e.g.
fd0 uses the address of fd1 on sparc64 (not sure if sparc64 supports
more than one floppy drive at all).
All of these drivers previously caused panics in the sparc64 ISA code.
- Minor changes, e.g. use __FBSDID, remove a dupe word in a comment and
declare one global variable which isn't used outside of isa.c static.
o dev/uart/uart_cpu_sparc64.c and modules/uart/Makefile:
- Remove the code for registering the UARTs on the ISA bus from the
sparc64 uart_cpu_identify() again and rely on probing them via PnP.
Original idea by: tmm [1]
No objections by: tmm [1], [2]
i386 to dev/acpi_support. In theory, these devices could be found
other than in i386 machines only as amd64 becomes more popular. These
drivers don't appear to do anything i386 specific, so move them to
dev/acpi_support. Move config lines to files so that those
architectures that don't support kernel modules can build them into
the kernel. At the same time, rename acpi_snc to acpi_sony to follow
the lead of all the other specialty devices.
the tree. Small tweaks were made by myself to eliminate unnecessary
includes and some other minor issues. Last time I asked takawata-san
about this driver, he suggested I commit it.
Submitted by: takawata
on UltraSPARC workstations. The driver is based on OpenBSD's SBus
cs4231 driver and heavily modified to incorporate into sound(4)
infrastructure. Due to the lack of APCDMA documentation, the DMA
code of SBus cs4231 came from OpenBSD's driver.
The driver runs without Giant lock and supports both SBus and EBus
based CS4231 audio controller. Special thanks to marius for providing
feedbacks during the driver writing. His feedback made it possible
to write hiccup free playback code under high system loads.
Approved by: jake (mentor)
Reviewed by: marius (initial version)
Tested by: marius, kwm, Julian C. Dunn(jdunn AT opentrend DOT net)