OS/2, eCS & ArcaOS - Technical > Hardware

Read and Write to driver

(1/2) > >>

Igor:
Hi All!

I am researching how to work with 32-bit drivers.
I need to write to the driver and read characters using the standard DosRead/DosWrite


--- Code: --- 
PBYTE plData = NULL;
plData = (PBYTE)Far16ToFlat(prp->io.ulAddress);

--- End code ---

I am receiving an incorrect address.
Which function should I use?
Help me please!

Martin Iturbide:
Hello Igor

I apologize in advance if this is wrong, since I have no idea. I asked the Gemini AI.


--- Quote ---Working with memory addresses in the OS/2 Warp 16/32-bit "mixed" environment can be a bit of a headache, especially when transitioning between the kernel's 16-bit physical addressing and the 32-bit flat model of a driver or application.

The issue you're likely facing is that `Far16ToFlat` is generally used for converting 16:16 segmented pointers. However, if `prp->io.ulAddress` contains a **physical address** (which is common in Request Packets for I/O operations), you need to map that physical memory into your driver's linear address space before you can touch it.

### The Correct Function: DevHelp_PhysToVirt

In the context of an OS/2 Physical Device Driver (PDD), the standard way to convert a physical address to a usable linear (flat) pointer is using the **PhysToVirt** DevHelp call.

Since you are likely in a 32-bit segment of a 4.52 (Warp CP2) driver, you should use the **Lin** version if you are operating in flat space.

#### Implementation Logic
1.  **Verify the Address Type**: Ensure `prp->io.ulAddress` is actually a 32-bit physical address.
2.  **Call PhysToVirt**: This maps the physical memory to a linear address that your 32-bit code can understand.
3.  **Address Context**: Remember that these addresses are often process-context dependent. If you need to access this memory later (outside the current strategy routine), you may need to "lock" the memory or map it globally.

### Example Code Snippet
If you are using a C wrapper for DevHelps (common in the Watcom or IBM DDK environments), it should look something like this:

```c
APIRET rc;
LIN    linearAddr;

// Convert physical address to a 32-bit flat (linear) address
// 0 indicates the mapping is for the current process context
rc = DevHelp_PhysToVirt(prp->io.ulAddress, prp->io.usLength, &linearAddr);

if (rc == 0) {
    plData = (PBYTE)linearAddr;
    // You can now use plData for DosRead/DosWrite logic
} else {
    // Handle error: Mapping failed
}
```

---

### Important Considerations for Warp 4.52
*   **Segment vs. Flat**: If `Far16ToFlat` was giving you "incorrect" addresses, it’s usually because it was treating a physical address as a `SEL:OFFSET` pair. A physical address `0x000B8000` is very different from a segmented address `0x000B:0x8000`.
*   **The Kernel Helper**: If you are specifically trying to convert a **16:16 pointer** (Selector:Offset) passed from a 16-bit application to your 32-bit driver, use `DevHelp_LinTo24` or ensure your selector is valid in the current LDT/GDT before conversion.
*   **DosRead/DosWrite**: Remember that inside a driver, you aren't usually calling `DosRead`. You are *implementing* the response to a `DosRead` called by an app. You move data from your driver buffer to the user buffer provided in the Request Packet (`prp->io.ulAddress`) using `DevHelp_MoveBytes` or simple pointer assignment once mapped.

**Quick Tip**: Check your `CONFIG.SYS`. If you are doing heavy 32-bit development on 4.52, ensure you have `BASEDEV=OS2DASD.DMD` and related drivers updated, as memory management quirks were often patched in the later Convenience Packages.

Is the address you are receiving coming specifically from a user-space application's buffer, or is it a memory-mapped I/O address from a hardware device?

--- End quote ---

I'm just curios to know how right or wrong the AI is.
I will prefer if someone with more knowledge on this area can comment.

Regards

Roderick Klein:
Does David his 32 bit driver kit not help out ?

drv32
https://88watts.net/software.html

Roderick

Lars:
The driver entry point that is called on a DosWrite/DosRead passes a physical address to read from/write to.
You need to call device driver helpers to convert a physical address to a virtual address. Or, for a 32-bit driver, to a linear address with the DS selector set to the flat selector.
By the way, the Gemini code is wrong. PhysToVirt maps from physical to virtual (16:16 pointer) and not to flat (0:32 pointer).
And it heavily phantasizes on what DevHelp calls are available. Seems there is not enough OS/2 code floating around...

Lars:
By the way: there is no DevHelp "PhysToLin". But there are other DevHelps that are equivalent to that.
I used "PagelistToLin" in my USBMSD.ADD driver.

Navigation

[0] Message Index

[#] Next page

Go to full version