Index: trunk/src/idctest/Makefile
===================================================================
--- trunk/src/idctest/Makefile	(revision 133)
+++ trunk/src/idctest/Makefile	(revision 133)
@@ -0,0 +1,118 @@
+###############################################################################
+# Makefile - makefile for IDCTEST driver, c600 tool chain
+#
+# Copyright (c) 2011 thi.guten Software Development
+# Copyright (c) 2011 Mensys B.V.
+#
+# Authors: Christian Mueller, Markus Thielen
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+###############################################################################
+# Tool Chain
+#
+
+AS         = $(DDK)\tools\alp.exe
+CC         = cl
+LD         = $(DDK)\base\tools\link.exe
+MAPSYM     = $(DDK)\base\tools\mapsym.exe
+BLDLEVEL   = cmd.exe /c ..\..\tools\bldlvl.cmd
+BLDDATE    = cmd.exe /c ..\..\tools\blddate.cmd
+
+AFLAGS     = -Mb
+CFLAGS     = -c -nologo -Asnw -W2 -G2ms -Zlpd -Fc -Zi -DECS_BUILD
+LFLAGS     = /noe /nod /packd /a:16 /batch /map /line
+
+###############################################################################
+# Environment
+
+# main path to OS/2 DDK; this needs to be set before this makefile will work
+!ifndef DDK
+DDK          = i:\ddk
+!endif
+
+# main path to 16 bit C compiler
+!ifndef CC16
+CC16         = i:\c600
+!endif
+
+CC_INCLUDE   = -I..\include \
+               -I$(DDK)\base\h \
+               -I$(DDK)\base\ibmh \
+	       -I$(DDK)\base\src\dev\dasd\diskh \
+               -I$(DDK)\base\src\dev\thinkpad\dockii\apmcalls \
+               -I$(CC16)\include
+
+AS_INCLUDE   = -I:$(DDK)\base\inc \
+               -I:$(DDK)\base\src\dev\dasd\diskinc
+
+LIB_DIRS     = $(DDK)\base\lib\ \
+	       $(DDK)\base\src\dev\dasd\devhlp\ \
+               $(DDK)\base\src\dev\thinkpad\dockii\apmcalls\ \
+               $(CC16)\lib\ \
+
+
+###############################################################################
+# Main dependencies
+
+TARGET   = idctest.sys
+
+LIBS     = dhcalls doscalls slibcep
+
+SRCS     = init.asm idctest.c
+
+OBJS     = init.obj idctest.obj
+
+INCS     = idctest.h ..\include\ahci-idc.h
+
+
+all: $(TARGET)
+
+clean:
+	rm -f $(OBJS) $(TARGET) *.cod *.lst
+
+
+###############################################################################
+# Object/source dependencies
+
+init.obj:     init.asm   Makefile
+
+idctest.obj:  idctest.c  Makefile $(INCS)
+
+
+###############################################################################
+# Action definitions (compile/link commands)
+
+# emacs TAGS file creation
+# NOTE: OS/2 emacs etags.exe expects an empty file named c:\dev\null...
+tags:	$(SRCS) $(INCS) Makefile
+	etags.exe $(SRCS) $(INCS) $(DDK)\base\src\dev\dasd\diskh\dhcalls.h \
+	$(DDK)\base\src\dev\dasd\diskh\iorb.h \
+	$(DDK)\base\h\bsedos16.h \
+	$(DDK)\base\h\devcmd.h \
+	$(DDK)\base\h\reqpkt.h
+
+.asm.obj:
+	$(AS) $(AFLAGS) $(AS_INCLUDE) $*.asm
+
+.c.obj:
+	$(CC) $(CFLAGS) $(CC_INCLUDE) $*.c
+
+$(TARGET): $(OBJS) idctest.def Makefile
+	$(LD) $(LFLAGS) $(OBJS),$(TARGET),$*.map,$(LIB_DIRS) $(LIBS),$*.def
+	$(MAPSYM) idctest
+
+
Index: trunk/src/idctest/idctest.c
===================================================================
--- trunk/src/idctest/idctest.c	(revision 133)
+++ trunk/src/idctest/idctest.c	(revision 133)
@@ -0,0 +1,224 @@
+/******************************************************************************
+ * idctest.c - main and only source file for the OS2AHCI IDC test driver
+ *
+ * This driver is used to test the ring 0 IDC interface of OS2AHCI.
+ * When this driver is opened by a Ring 3 process, it uses OS2AHCI's
+ * IDC interface to send it a test IOCTL that does nothing but beep.
+ *
+ * Authors: Christian Mueller, Markus Thielen
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*---- includes --------------------------------------------------------------*/
+
+#define INCL_NOPMAPI
+#define INCL_DOSINFOSEG
+#define INCL_NO_SCB
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <dos.h>
+#include <bseerr.h>
+#include <dskinit.h>
+#include <scb.h>
+
+#include <devhdr.h>
+#include <iorb.h>
+#include <strat2.h>
+#include <reqpkt.h>
+
+#include <dhcalls.h>
+
+#include <addcalls.h>
+#include <rmcalls.h>
+#include <devclass.h>
+#include <devcmd.h>
+#include <rmbase.h>
+#include "ahci-idc.h"
+
+
+/*---- function proEtotypes ---------------------------------------------------*/
+
+extern APIRET APIENTRY DosPutMessage           (USHORT hf,
+                                                USHORT cbMsg,
+                                                PCHAR pchMsg);
+
+static unsigned int    strlen                  (PSZ s);
+
+static void            memset                  (void _far *p,
+                                                unsigned int cb,
+                                                unsigned char byte);
+
+int                    init                    (RPINITIN _far *req);
+
+int                    c_strat                 (RPH _far *req);
+
+void                   drv_open                (void);
+
+
+/*---- global data -----------------------------------------------------------*/
+
+char init_msg[] = "\r\nOS2AHCI IDC Test Driver\r\n";
+char init_fail[] = "Failed to attach to OS2AHCI$";
+char init_ok[] = "up and running...\r\n";
+
+PFN Device_Help = 0;
+
+AHCI_ATTACH_AREA attach_data;
+int last_cmd;
+
+extern char _cdecl       end_of_data;   /* label at the end of all data segments */
+extern void _cdecl _near end_of_code(); /* label at the end of all code segments */
+
+/******************************************************************************
+ * c_strat_idc - IDC test driver entry point
+ */
+int c_strat_idc(RPH _far *req)
+
+{
+  USHORT result = STDON;
+  last_cmd = req->Cmd;
+
+  switch (last_cmd) {
+
+  case CMDInit:
+    return (init((RPINITIN _far *) req));
+
+  case CMDOpen:
+    drv_open();
+    return(STDON);
+
+  case CMDGenIOCTL:
+    drv_open();
+    return(STDON);
+
+  case CMDClose:
+    return(STDON);
+
+  default:
+    break;
+
+  }
+
+  return  STDON | STERR | ERROR_BAD_COMMAND;
+}
+
+/******************************************************************************
+ * init
+ */
+int init(RPINITIN _far *req)
+{
+
+  char *ahci_name = "OS2AHCI$ ";
+  RPINITOUT _far *rsp = (RPINITOUT _far *) req;
+  int ret = STDON;
+
+  /* store DevHelp entry point */
+  Device_Help = req->DevHlpEP;
+
+  DosPutMessage(1, strlen(init_msg), init_msg);
+
+  /* attach to OS2AHCI.ADD */
+  if (DevHelp_AttachDD(ahci_name, (NPBYTE) &attach_data)) {
+    /* failed to attach */
+    DosPutMessage(1, strlen(init_fail), init_fail);
+    rsp->CodeEnd = 0;
+    rsp->DataEnd = 0;
+    ret = STDON | ERROR_I24_QUIET_INIT_FAIL; 
+
+  } else {
+    /* successfully attached */
+    DosPutMessage(1, strlen(init_ok), init_ok);
+    rsp->CodeEnd = (USHORT) end_of_code;
+    rsp->DataEnd = (USHORT) &end_of_data;
+    ret = STDON;
+  }
+
+  return ret;
+}
+
+/******************************************************************************
+ * drv_open() - this is called when a ring 3 process opens us with DosOpen.
+ * We then call into OS2AHCI's IDC interface with a test IOCTL that causes
+ * OS2AHCI to beep.
+ */
+void drv_open(void)
+{
+  RP_GENIOCTL rp_ioctl;
+  unsigned short target_ds = attach_data.prot_ds;
+  PFN_AHCI_IDC_ENTRY func = attach_data.prot_entry_point;
+  
+  memset((void _far*) &rp_ioctl, sizeof(rp_ioctl), 0x00);
+  
+  /* prepare request packet */
+  rp_ioctl.rph.Len  = (UCHAR) sizeof(rp_ioctl);
+  rp_ioctl.rph.Cmd  = CMDGenIOCTL;
+  rp_ioctl.Category = OS2AHCI_IDC_CATEGORY;
+  rp_ioctl.Function = OS2AHCI_IDC_BEEP;
+
+  /* call IDC entry point in Assembler;
+   * IDC calling convention is to set DS to the data segment of
+   * the target driver and ES to the segment of the request packet.
+   */
+  _asm {
+    push ds
+    push es
+    push bx
+    push si
+    push di
+
+    push ss
+    pop  es
+    lea  bx, rp_ioctl
+    mov  ds, target_ds
+    call dword ptr [func]
+
+    pop  di
+    pop  si
+    pop  bx
+    pop  es
+    pop  ds
+  }
+
+  
+}
+
+
+/******************************************************************************
+ * strlen
+ */
+static unsigned int strlen(PSZ s)
+{
+  int i = 0;
+  while (*s++) {
+    i++;
+  }
+  
+  return (i);
+}
+
+/******************************************************************************
+ * memset
+ */
+static void memset(void _far *d, unsigned int cb, unsigned char byte)
+{
+  unsigned int i;
+  unsigned char _far *p = (unsigned char _far*) d;
+
+  for (i = 0; i < cb; i++) {
+    p[i] = byte;
+  }
+
+}
Index: trunk/src/idctest/idctest.def
===================================================================
--- trunk/src/idctest/idctest.def	(revision 133)
+++ trunk/src/idctest/idctest.def	(revision 133)
@@ -0,0 +1,17 @@
+library idctest
+Description '$@#thi.guten:1.0.0#@##1## 2012/05/09 13:48:27      ECSINTEL::::00::@@AHCI IDC Test Driver'
+protmode
+
+segments
+  DEVHDR        CLASS 'DATA'
+  _DATA         CLASS 'DATA'
+  CONST         CLASS 'CONST'
+  _BSS          CLASS 'BSS'
+  c_common      CLASS 'BSS'
+  _z_data       CLASS 'BSS'
+  _TEXT         CLASS 'CODE' IOPL
+  'CODE'        CLASS 'CODE' IOPL
+  RMCode        CLASS 'CODE' IOPL
+  LIBCODE       CLASS 'CODE' IOPL
+  _z_text       CLASS 'CODE' IOPL
+
Index: trunk/src/idctest/idctest.h
===================================================================
--- trunk/src/idctest/idctest.h	(revision 133)
+++ trunk/src/idctest/idctest.h	(revision 133)
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * idctest.h - definitions for IDCTEST.SYS
+ *
+ * This driver is used to test the ring 0 IDC interface of OS2AHCI.s
+ *
+ * Author: Markus Thielen, thi.guten Software Development
+ *
+ */
+
+/*---- includes --------------------------------------------------------------*/
+
+#define INCL_NOPMAPI
+#define INCL_DOSINFOSEG
+#define INCL_NO_SCB
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <dos.h>
+#include <bseerr.h>
+#include <dskinit.h>
+#include <scb.h>
+
+#include <devhdr.h>
+#include <iorb.h>
+#include <strat2.h>
+#include <reqpkt.h>
+
+#include <dhcalls.h>
+
+#include <devclass.h>
+#include <devcmd.h>
+
+
+/*---- types -----------------------------------------------------------------*/
+
+typedef struct AttachArea {
+  VOID     (FAR *realEntryPoint)(SEG realDS,
+                                     PASPI_SRB_HEADER pSRB);
+  SEG      realDS;
+  VOID     (FAR *protectedEntryPoint)(SEL protectedDS,
+                                          PASPI_SRB_HEADER pSRB);
+  SEL      protectedDS;
+  } ATTACHAREA;
+
+typedef ATTACHAREA near *PATTACHAREA;
Index: trunk/src/idctest/init.asm
===================================================================
--- trunk/src/idctest/init.asm	(revision 133)
+++ trunk/src/idctest/init.asm	(revision 133)
@@ -0,0 +1,107 @@
+; ----------------------------------------------------------------------------
+; Initialization routines and segment mappings for idctest driver.
+;
+; This is a stripped down version of os2ahci's init.asm.
+
+include devhdr.inc
+
+; -----------------------------------------------------------------------------
+; Public symbols
+
+                PUBLIC  _asm_strat           ; low-level strategy routine
+                PUBLIC  _end_of_data         ; end of all data (label)
+                PUBLIC  _end_of_code         ; end of all code (label)
+        
+; ----------------------------------------------------------------------------
+; Device Driver Header
+
+DEVHDR          SEGMENT WORD PUBLIC 'DATA'
+_dev_hdr        dd      -1                      ; next device header
+                dw      DEVLEV_3 + DEV_CHAR_DEV ; flags for ADD drivers
+                dw      OFFSET _asm_strat       ; strategy routine
+                dw      0                       ; IDC entry point
+                db      "IDCTEST$"              ; name of character device
+                dq      0                       ; 8 reserved bytes
+                dd      0                       ; ADD flags
+                dw      0
+DEVHDR          ENDS
+
+; ----------------------------------------------------------------------------
+; Segment Definitions. We need to reference all segments here, even if they
+; are not used, to allow proper grouping of all segments into one group for
+; data and one group for code as well as proper ordering of the segments
+; within each group to make sure the end of segment markers are at the end
+; of each group.
+
+; On top of that, we need to make sure that the end of segment marker is in
+; a data segment of class 'BSS' because BSS segments are always put towards
+; the end of the executable when linking with high-level language objects
+; such as C.
+
+_DATA           SEGMENT WORD PUBLIC 'DATA'
+_DATA           ENDS
+
+CONST           SEGMENT WORD PUBLIC 'CONST'
+CONST           ENDS
+
+_BSS            SEGMENT WORD PUBLIC 'BSS'
+_BSS            ENDS
+
+c_common        SEGMENT WORD PUBLIC 'BSS'
+c_common        ENDS
+
+_z_data         SEGMENT WORD PUBLIC 'BSS'
+_end_of_data    db      0
+_z_data         ENDS
+
+_TEXT           SEGMENT WORD PUBLIC 'CODE'
+                EXTRN   _c_strat_idc : NEAR           ; C strategy routine
+_TEXT           ENDS
+
+CODE            SEGMENT WORD PUBLIC 'CODE'
+CODE            ENDS
+
+RMCode          SEGMENT WORD PUBLIC 'CODE'
+RMCode          ENDS
+
+LIBCODE         SEGMENT WORD PUBLIC 'CODE'
+LIBCODE         ENDS
+
+_z_text         SEGMENT WORD PUBLIC 'CODE'
+_end_of_code    LABEL NEAR
+_z_text         ENDS
+
+DGROUP          GROUP   DEVHDR, _DATA, CONST, _BSS, c_common, _z_data
+TGROUP          GROUP   _TEXT, CODE, _z_text
+
+; ----------------------------------------------------------------------------
+; Start of code
+
+_TEXT           SEGMENT WORD PUBLIC 'CODE'
+                ASSUME  DS:DGROUP
+                ASSUME  ES:NOTHING
+                ASSUME  SS:NOTHING
+
+
+; Device driver main entry point (strategy routine)
+_asm_strat      PROC    FAR
+
+                ; push request packet address
+                PUSH    ES
+                PUSH    BX
+                CLD
+
+                ; call C strategy routine
+                CALL    _c_strat_idc
+
+                POP     BX
+                POP     ES
+                MOV     WORD PTR ES:[BX+3], AX
+                RET
+_asm_strat      ENDP
+
+
+_TEXT           ENDS
+
+                END
+
Index: trunk/src/idctest/testprog.c
===================================================================
--- trunk/src/idctest/testprog.c	(revision 133)
+++ trunk/src/idctest/testprog.c	(revision 133)
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ *  testprog.c - ring 3 test program for AHCI IDC function.
+ *  This program opens the IDCTEST.SYS driver, which will call OS2AHCI's
+ *  IDC entry point with a TEST IOCTL that does nothing but beep.
+ * 
+ *  Author: Markus Thielen, thi.guten Software Development.
+ *
+ *  Compilation (Watcom): wcl386 -bt=os2 test.c
+ *
+ * Copyright (c) 2010 by thi.guten Software development, www.thiguten.de
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*---- includes --------------------------------------------------------------*/
+
+#define INCL_DOSFILEMGR
+#define INCL_DOSPROCESS
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/******************************************************************************
+ * main()
+ */
+void main(void)
+{
+  ULONG rc;
+  ULONG action;
+  HFILE hf;
+  char *drv_name = "IDCTEST$";
+
+  printf("OS2AHCI IDC Test Program. Do you hear a beep??\n");
+  rc = DosOpen(drv_name, &hf, &action, 0,
+               FILE_NORMAL, FILE_OPEN, OPEN_SHARE_DENYNONE, NULL);
+  if (rc) {
+    /* open failed */
+    fprintf(stderr, "DosOpen failed with code %d ", rc);
+    fprintf(stderr, "Is IDCTEST.SYS really loaded?\n");
+    return;
+  }
+
+  DosClose(hf);
+
+}
Index: trunk/src/include/ahci-idc.h
===================================================================
--- trunk/src/include/ahci-idc.h	(revision 133)
+++ trunk/src/include/ahci-idc.h	(revision 133)
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * ahciidc.h - definitions for the OS2AHCI IDC interface
+ *
+ * Copyright (c) 2011 thi.guten Software Development
+ * Copyright (c) 2011 Mensys B.V.
+ *
+ * Authors: Christian Mueller, Markus Thielen
+ *
+ * Parts copied from/inspired by the Linux AHCI driver;
+ * those parts are (c) Linux AHCI/ATA maintainers
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/* -------------------------- macros and constants ------------------------- */
+
+/* IDC category */
+#define OS2AHCI_IDC_CATEGORY           0x88
+
+/* enter BIOS mode (e.g. to generate trap dumps)
+ * Request packet parameters: None
+ */
+#define OS2AHCI_IDC_BIOSMODE           0x66
+
+/* test IOCTL; does nothing but BEEP
+ * Request packet parameters: None
+ */
+#define OS2AHCI_IDC_BEEP               0x67
+
+
+/* ------------------------ typedefs and structures ------------------------ */
+
+/* AHCI_IDC_ENTRY defines a function pointer to the OS2AHCI IDC entry point */
+typedef void (_cdecl _far *PFN_AHCI_IDC_ENTRY) (unsigned short real_ds, 
+                                                RP_GENIOCTL _far *ioctl);
+
+#pragma pack(1)
+
+/*
+ * AHCI_ATTACH_AREA defines the device driver attach table as required
+ * to attach to os2ahci.add using DevHelp_AttachDD
+ */
+typedef struct {
+  PFN_AHCI_IDC_ENTRY  real_entry_point;   /* real mode entry point address */
+  unsigned short      real_ds;            /* real mode DS */
+
+  PFN_AHCI_IDC_ENTRY  prot_entry_point;   /* protected mode entry point address */
+  unsigned short      prot_ds;            /* protected mode DS */
+  } AHCI_ATTACH_AREA;
+
+#pragma pack()
+
+/* -------------------------- function prototypes -------------------------- */
+
+/* ------------------------ global/static variables ------------------------ */
+
+
Index: trunk/src/os2ahci/Makefile
===================================================================
--- trunk/src/os2ahci/Makefile	(revision 131)
+++ trunk/src/os2ahci/Makefile	(revision 133)
@@ -50,5 +50,6 @@
 !endif
 
-CC_INCLUDE   = -I$(DDK)\base\h \
+CC_INCLUDE   = -I..\include \
+               -I$(DDK)\base\h \
                -I$(DDK)\base\ibmh \
 	       -I$(DDK)\base\src\dev\dasd\diskh \
@@ -78,5 +79,5 @@
            ctxhook.obj apm.obj ioctl.obj trace.obj
 
-INCS     = os2ahci.h ahci.h version.h
+INCS     = os2ahci.h ahci.h version.h ioctl.h ..\include\ahci-idc.h
 
 
@@ -122,5 +123,7 @@
 	etags.exe $(SRCS) $(INCS) $(DDK)\base\src\dev\dasd\diskh\dhcalls.h \
 	$(DDK)\base\src\dev\dasd\diskh\iorb.h \
-	$(DDK)\base\h\bsedos16.h
+	$(DDK)\base\h\bsedos16.h \
+	$(DDK)\base\h\devcmd.h \
+	$(DDK)\base\h\reqpkt.h
 
 bldday.h:
Index: trunk/src/os2ahci/init.asm
===================================================================
--- trunk/src/os2ahci/init.asm	(revision 131)
+++ trunk/src/os2ahci/init.asm	(revision 133)
@@ -6,7 +6,12 @@
 
 ; -----------------------------------------------------------------------------
+; Constants
+                DEV_IDC  EQU    0400h        ;  IDC bit for ADD flags
+        
+; -----------------------------------------------------------------------------
 ; Public symbols
 
                 PUBLIC  _asm_strat           ; low-level strategy routine
+                PUBLIC  _asm_idc_entry       ; low-level IDC entry point 
                 PUBLIC  _readl               ; MMIO read (32 bits)
                 PUBLIC  _writel              ; MMIO write (32 bits)
@@ -29,7 +34,7 @@
 DEVHDR          SEGMENT WORD PUBLIC 'DATA'
 _dev_hdr        dd      _legacy_hdr             ; next device header
-                dw      DEVLEV_3 + DEV_CHAR_DEV ; flags for ADD drivers
+                dw      DEVLEV_3 + DEV_CHAR_DEV + DEV_IDC ; flags for ADD drivers
                 dw      OFFSET _asm_strat       ; strategy routine
-                dw      0                       ; no IDC routine
+                dw      OFFSET _asm_idc_entry   ; IDC entry point
                 db      "OS2AHCI$"              ; name of character device
                 dq      0                       ; 8 reserved bytes
@@ -40,5 +45,5 @@
                 dw      DEVLEV_3 + DEV_CHAR_DEV ; flags for ADD drivers
                 dw      OFFSET _asm_strat       ; strategy routine
-                dw      0                       ; no IDC routine
+                dw      0                       ; IDC entry point
                 db      "IBMS506$"              ; name of character device
                 dq      0                       ; 8 reserved bytes
@@ -129,4 +134,22 @@
                 RET
 _asm_strat      ENDP
+
+
+; IDC entry point (Assembler stub)
+_asm_idc_entry  PROC    FAR
+        
+                ; push request packet address
+                PUSH    ES
+                PUSH    BX
+                CLD
+
+                ; call C IDC entry point - which is the strategy routine
+                CALL    _c_strat
+
+                POP     BX
+                POP     ES
+                MOV     WORD PTR ES:[BX+3], AX
+                RET
+_asm_idc_entry  ENDP
 
                 .386
Index: trunk/src/os2ahci/os2ahci.c
===================================================================
--- trunk/src/os2ahci/os2ahci.c	(revision 131)
+++ trunk/src/os2ahci/os2ahci.c	(revision 133)
@@ -124,4 +124,7 @@
  * for initialization purposes; all other calls go directly to the adapter
  * device driver's strategy function.
+ *
+ * NOTE: this is also used as the IDC entry point. We expect an IOCTL request
+ *       packet for IDC calls, so they can be handled by gen_ioctl.
  */
 USHORT _cdecl c_strat(RPH _far *req)
@@ -247,5 +250,5 @@
       case 'r':
         /* reset ports during initialization */
-	init_reset = 1;
+        init_reset = 1;
         break;
 
@@ -427,4 +430,26 @@
 
     }
+    break;
+
+  case OS2AHCI_IDC_CATEGORY:
+    switch (ioctl->Function) {
+
+    case OS2AHCI_IDC_BIOSMODE:
+      /* reconfigure adapters in BIOS/int13 mode; needed for generating 
+       * trap dumps on some machines. This is called by ACPI.PSD.
+       *
+       * To enter BIOS mode, we flush all write caches, turn off interrupts
+       * and restore the BIOS configuration. This is exactly what 
+       * apm_suspend() does.
+       */
+      apm_suspend();
+      return(STDON);
+
+    case OS2AHCI_IDC_BEEP:
+      /* IOCTL for IDC testing - just beep */
+      DevHelp_Beep(2000, 100);
+      return(STDON);
+    }
+    break;
 
   case DSKSP_CAT_GENERIC:
Index: trunk/src/os2ahci/os2ahci.h
===================================================================
--- trunk/src/os2ahci/os2ahci.h	(revision 131)
+++ trunk/src/os2ahci/os2ahci.h	(revision 133)
@@ -63,4 +63,5 @@
 
 #include "ahci.h"
+#include "ahci-idc.h"
 #include "version.h"
 
Index: trunk/src/os2ahci/version.h
===================================================================
--- trunk/src/os2ahci/version.h	(revision 131)
+++ trunk/src/os2ahci/version.h	(revision 133)
@@ -14,4 +14,4 @@
 
 
-#define VERSION            122       /* driver version (2 implied decimals) */
+#define VERSION            123       /* driver version (2 implied decimals) */
 
