Author Topic: Read and Write to driver  (Read 363 times)

Igor

  • Full Member
  • ***
  • Posts: 143
  • Karma: +17/-0
Read and Write to driver
« on: May 04, 2026, 10:57:09 pm »
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: [Select]
 
PBYTE plData = NULL;
plData = (PBYTE)Far16ToFlat(prp->io.ulAddress);

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

Martin Iturbide

  • OS2World NewsMaster
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 5732
  • Karma: +50/-1
  • Your Friend Wil Declares...
    • Martin's Personal Blog
Re: Read and Write to driver
« Reply #1 on: May 05, 2026, 04:15:18 pm »
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?

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
Martin Iturbide
OS2World NewsMaster
... just share the dream.

Roderick Klein

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +17/-0
Re: Read and Write to driver
« Reply #2 on: May 05, 2026, 09:34:11 pm »
Does David his 32 bit driver kit not help out ?

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

Roderick

Lars

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +77/-0
Re: Read and Write to driver
« Reply #3 on: May 05, 2026, 09:56:29 pm »
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...
« Last Edit: May 06, 2026, 02:39:22 pm by Lars »

Lars

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +77/-0
Re: Read and Write to driver
« Reply #4 on: May 06, 2026, 07:52:47 am »
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.
« Last Edit: May 06, 2026, 02:38:56 pm by Lars »

Igor

  • Full Member
  • ***
  • Posts: 143
  • Karma: +17/-0
Re: Read and Write to driver
« Reply #5 on: May 10, 2026, 12:43:47 am »
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...
Thanks a lot for the physical. That wasn't obvious.
I gues I can use Dev32Help_PhysToLin from Drv32 kit...

Igor

  • Full Member
  • ***
  • Posts: 143
  • Karma: +17/-0
Re: Read and Write to driver
« Reply #6 on: May 10, 2026, 06:08:34 pm »
Hi, Lars!

This realy works with Dev32Help_PhysToLin.
My problem  solved. The driver is accepting data.