Index: bsps/i386/pc386/ata/ide.c
===================================================================
--- bsps/i386/pc386/ata/ide.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/i386/pc386/ata/ide.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,725 @@
+/*===============================================================*\
+| Project: RTEMS PC386 IDE harddisc driver                        |
++-----------------------------------------------------------------+
+| File: ide.c                                                     |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2003 IMD                       |
+|      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler      |
+|               <Thomas.Doerfler@imd-systems.de>                  |
+|                       all rights reserved                       |
++-----------------------------------------------------------------+
+| this file contains the BSP layer for IDE access below the       |
+| libchip IDE harddisc driver                                     |
+| based on a board specific driver from                           |
+| Eugeny S. Mints, Oktet                                          |
+|                                                                 |
+|  The license and distribution terms for this file may be        |
+|  found in the file LICENSE in this distribution or at           |
+|  http://www.rtems.org/license/LICENSE.                     |
+|                                                                 |
++-----------------------------------------------------------------+
+|   date                      history                        ID   |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.14.03  creation                                         doe  |
+\*===============================================================*/
+
+#include <inttypes.h>
+
+#include <rtems.h>
+
+#include <bsp.h>
+#include <libchip/ide_ctrl.h>
+#include <libchip/ide_ctrl_cfg.h>
+#include <libchip/ide_ctrl_io.h>
+
+#define ATA_SECTOR_SIZE (512)
+
+/*
+ * Use during initialisation.
+ */
+extern void Wait_X_ms(unsigned int msecs);
+
+bool pc386_ide_show;
+uint32_t pc386_ide_timeout;
+
+#define PC386_IDE_DEBUG_OUT 0
+
+#if PC386_IDE_DEBUG_OUT
+bool pc386_ide_trace;
+#define pc386_ide_printk if (pc386_ide_trace) printk
+#endif
+
+#define PC386_IDE_PROBE_TIMEOUT    (500)
+#define PC386_IDE_PRESTART_TIMEOUT (1000)
+#define PC386_IDE_TASKING_TIMEOUT  (2000)
+
+/*
+ * Prestart sleep using a calibrated timing loop.
+ */
+static void pc386_ide_prestart_sleep (void)
+{
+  Wait_X_ms (10);
+}
+
+/*
+ * Once tasking has started we use a task sleep.
+ */
+static void pc386_ide_tasking_sleep (void)
+{
+  rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (10000) ?
+                         RTEMS_MICROSECONDS_TO_TICKS (10000) : 1);
+}
+
+typedef void (*pc386_ide_sleeper)(void);
+
+static void pc386_ide_sleep (pc386_ide_sleeper sleeper)
+{
+  sleeper ();
+}
+
+static void wait(volatile uint32_t loops)
+{
+  while (loops)
+    loops--;
+}
+
+static bool pc386_ide_status_busy (uint32_t          port,
+                                   volatile uint32_t timeout,
+                                   uint8_t*          status_val,
+                                   pc386_ide_sleeper sleeper)
+{
+  volatile uint8_t status;
+  int              polls;
+
+  do
+  {
+    polls = 500;
+    while (polls)
+    {
+      inport_byte (port + IDE_REGISTER_STATUS, status);
+      if ((status & IDE_REGISTER_STATUS_BSY) == 0)
+      {
+        *status_val = status;
+        return true;
+      }
+      polls--;
+    }
+
+    if (timeout)
+    {
+      timeout--;
+      pc386_ide_sleep (sleeper);
+    }
+  }
+  while (timeout);
+
+  *status_val = status;
+  return false;
+}
+
+static bool pc386_ide_status_data_ready (uint32_t          port,
+                                         volatile uint32_t timeout,
+                                         uint8_t*          status_val,
+                                         pc386_ide_sleeper sleeper)
+{
+  volatile uint8_t status;
+  int              polls;
+
+  do
+  {
+    polls = 1000;
+    while (polls)
+    {
+      inport_byte (port + IDE_REGISTER_STATUS, status);
+
+      if (((status & IDE_REGISTER_STATUS_BSY) == 0) &&
+          (status & IDE_REGISTER_STATUS_DRQ))
+      {
+        *status_val = status;
+        return true;
+      }
+
+      polls--;
+    }
+
+    if (timeout)
+    {
+      timeout--;
+      pc386_ide_sleep (sleeper);
+    }
+  }
+  while (timeout);
+
+  *status_val = status;
+  return false;
+}
+
+/*
+ * support functions for IDE harddisk IF
+ */
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static bool pc386_ide_probe
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  This function should probe, whether a IDE disk is available              |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int minor
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    true, when flash disk available                                        |
+\*=========================================================================*/
+{
+  bool ide_card_plugged = true; /* assume: we have a disk here */
+
+  return ide_card_plugged;
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static void pc386_ide_initialize
+(
+/*-------------------------------------------------------------------------*\
+  | Purpose:                                                                  |
+  |  initialize IDE access                                                    |
+  +---------------------------------------------------------------------------+
+  | Input Parameters:                                                         |
+  \*-------------------------------------------------------------------------*/
+  int  minor                              /* controller minor number       */
+ )
+/*-------------------------------------------------------------------------*\
+  | Return Value:                                                             |
+  |    <none>                                                                 |
+  \*=========================================================================*/
+{
+  uint32_t port = IDE_Controller_Table[minor].port1;
+  uint8_t  dev = 0;
+
+  if (pc386_ide_show)
+    printk("IDE%d: port base: %04" PRIu32 "\n", minor, port);
+
+  outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
+               (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
+  wait(10000);
+  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
+               IDE_REGISTER_DEVICE_CONTROL_SRST | IDE_REGISTER_DEVICE_CONTROL_nIEN);
+  wait(10000);
+  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
+               IDE_REGISTER_DEVICE_CONTROL_nIEN);
+  wait(10000);
+
+  for (dev = 0; dev < 2; dev++)
+  {
+    uint16_t    capabilities = 0;
+    uint32_t    byte;
+    uint8_t     status;
+    uint8_t     error;
+    uint8_t     cyllsb;
+    uint8_t     cylmsb;
+    const char* label = dev ? " slave" : "master";
+    int         max_multiple_sectors = 0;
+    int         cur_multiple_sectors = 0;
+    uint32_t    cylinders = 0;
+    uint32_t    heads = 0;
+    uint32_t    sectors = 0;
+    uint32_t    lba_sectors = 0;
+    char        model_number[41];
+    char*       p = &model_number[0];
+    bool        data_ready;
+
+    (void) cur_multiple_sectors; /* avoid set but not used warning */
+
+    memset(model_number, 0, sizeof(model_number));
+
+    outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
+                 (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
+    /*
+      outport_byte(port+IDE_REGISTER_SECTOR_NUMBER,
+      (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | IDE_REGISTER_LBA3_L);
+    */
+
+    outport_byte(port+IDE_REGISTER_COMMAND, 0x00);
+
+    if (!pc386_ide_status_busy (port, PC386_IDE_PROBE_TIMEOUT,
+                                &status, pc386_ide_prestart_sleep))
+      continue;
+
+    inport_byte(port+IDE_REGISTER_STATUS,        status);
+    inport_byte(port+IDE_REGISTER_ERROR,         error);
+    inport_byte(port+IDE_REGISTER_CYLINDER_LOW,  cyllsb);
+    inport_byte(port+IDE_REGISTER_CYLINDER_HIGH, cylmsb);
+
+    if (pc386_ide_show)
+    {
+      printk("IDE%d:%s: status=%02x\n", minor, label, status);
+      printk("IDE%d:%s: error=%02x\n", minor, label, error);
+      printk("IDE%d:%s: cylinder-low=%02x\n", minor, label, cyllsb);
+      printk("IDE%d:%s: cylinder-high=%02x\n", minor, label, cylmsb);
+    }
+
+    outport_byte(port+IDE_REGISTER_COMMAND, 0xec);
+
+    if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT,
+                                &status, pc386_ide_prestart_sleep))
+    {
+      if (pc386_ide_show)
+        printk("IDE%d:%s: device busy: %02x\n", minor, label, status);
+      continue;
+    }
+
+    data_ready = pc386_ide_status_data_ready (port,
+                                              250,
+                                              &status,
+                                              pc386_ide_prestart_sleep);
+
+    if (status & IDE_REGISTER_STATUS_ERR)
+    {
+      inport_byte(port+IDE_REGISTER_ERROR, error);
+      if (error != 4)
+      {
+        if (pc386_ide_show)
+          printk("IDE%d:%s: error=%04x\n", minor, label, error);
+        continue;
+      }
+      /*
+       * The device is an ATAPI device.
+       */
+      outport_byte(port+IDE_REGISTER_COMMAND, 0xa1);
+      data_ready = pc386_ide_status_data_ready (port,
+                                                250,
+                                                &status,
+                                                pc386_ide_prestart_sleep);
+    }
+
+    if (!data_ready)
+      continue;
+
+    byte = 0;
+    while (byte < 512)
+    {
+      uint16_t word;
+
+      if (pc386_ide_show && ((byte % 16) == 0))
+        printk("\n %04" PRIx32 " : ", byte);
+
+      inport_word(port+IDE_REGISTER_DATA, word);
+
+      if (pc386_ide_show)
+        printk ("%04x ", word);
+
+      if (byte == 2)
+        cylinders = word;
+      if (byte == 6)
+        heads = word;
+      if (byte == 12)
+        sectors = word;
+
+      if (byte >= 54 && byte < (54 + 40))
+      {
+        *p = word >> 8;
+        p++;
+        *p = word;
+        p++;
+      }
+
+      if (byte == (47 * 2))
+        max_multiple_sectors = word & 0xff;
+
+      if (byte == (49 * 2))
+        capabilities = word;
+
+      if (byte == (59 * 2))
+      {
+        if (word & (1 << 8))
+          cur_multiple_sectors = word & 0xff;
+      }
+
+      if (byte == (60 * 2))
+        lba_sectors = word;
+      if (byte == (61 * 2))
+        lba_sectors |= word << 16;
+
+      byte += 2;
+    }
+
+    if (pc386_ide_show)
+      printk("\nbytes read = %" PRIu32 "\n", byte);
+
+    if (p != &model_number[0])
+    {
+      uint32_t size;
+      uint32_t left;
+      uint32_t right;
+      char     units;
+
+      if (capabilities & (1 << 9))
+        size = lba_sectors;
+      else
+        size = cylinders * heads * sectors;
+
+      size /= 2;
+
+      if (size > (1024 * 1024))
+      {
+        size = (size * 10) / (1000 * 1000);
+        units = 'G';
+      }
+      else if (size > 1024)
+      {
+        size = (size * 10) / 1000;
+        units = 'M';
+      }
+      else
+      {
+        size = size * 10;
+        units = 'K';
+      }
+
+      left = size / 10;
+      right = size % 10;
+
+      p--;
+      while (*p == ' ')
+      {
+        *p = '\0';
+        p--;
+      }
+
+      printk("IDE%d:%s:%s, %" PRIu32 ".%" PRIu32 "%c (%" PRIu32 "/%" PRIu32 "/%" PRIu32 "), max blk size:%d\n",
+             minor, label, model_number, left, right, units,
+             heads, cylinders, sectors, max_multiple_sectors * 512);
+    }
+
+#if IDE_CLEAR_MULTI_SECTOR_COUNT
+    if (max_multiple_sectors)
+    {
+      outport_byte(port+IDE_REGISTER_SECTOR_COUNT, 0);
+      outport_byte(port+IDE_REGISTER_COMMAND, 0xc6);
+
+      if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT,
+                                  &status, pc386_ide_prestart_sleep))
+      {
+        if (pc386_ide_show)
+          printk("IDE%d:%s: device busy: %02x\n", minor, label, status);
+        continue;
+      }
+
+      inport_byte(port+IDE_REGISTER_STATUS, status);
+      if (status & IDE_REGISTER_STATUS_ERR)
+      {
+        inport_byte(port+IDE_REGISTER_ERROR, error);
+        if (error & IDE_REGISTER_ERROR_ABRT)
+          printk("IDE%d:%s: disable multiple failed\n", minor, label);
+        else
+          printk("IDE%d:%s: unknown error on disable multiple: %02x\n",
+                 minor, label, error);
+      }
+    }
+#endif
+
+    outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
+                 IDE_REGISTER_DEVICE_CONTROL_nIEN);
+    wait(10000);
+  }
+
+  pc386_ide_timeout = PC386_IDE_TASKING_TIMEOUT;
+
+  /*
+   * FIXME: enable interrupts, if needed
+   */
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static void pc386_ide_read_reg
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  read a IDE controller register                                           |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int                        minor,  /* controller minor number       */
+ int                        reg,    /* register index to access      */
+ uint16_t                  *value   /* ptr to return value location  */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    <none>                                                                 |
+\*=========================================================================*/
+{
+  uint32_t    port = IDE_Controller_Table[minor].port1;
+  uint8_t   bval1,bval2;
+
+  if (reg == IDE_REGISTER_DATA_WORD) {
+    inport_byte(port+reg, bval1);
+    inport_byte(port+reg+1, bval2);
+    *value = bval1 + (bval2 << 8);
+  }
+  else {
+    inport_byte(port+reg, bval1);
+    *value = bval1;
+  }
+#if PC386_IDE_DEBUG_OUT
+  pc386_ide_printk("pc386_ide_read_reg (0x%x)=0x%x\r\n",reg,*value & 0xff);
+#endif
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static void pc386_ide_write_reg
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  write a IDE controller register                                          |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int                        minor,  /* controller minor number       */
+ int                        reg,    /* register index to access      */
+ uint16_t                   value   /* value to write                */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    <none>                                                                 |
+\*=========================================================================*/
+{
+  uint32_t    port = IDE_Controller_Table[minor].port1;
+
+#if PC386_IDE_DEBUG_OUT
+  pc386_ide_printk("pc386_ide_write_reg(0x%x,0x%x)\r\n",reg,value & 0xff);
+#endif
+  if (reg == IDE_REGISTER_DATA_WORD) {
+    outport_word(port+reg,value);
+  }
+  else {
+    outport_byte(port+reg,value);
+  }
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static void pc386_ide_read_block
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  read a IDE controller data block                                         |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int                     minor,
+ uint32_t                block_size,
+ rtems_blkdev_sg_buffer *bufs,
+ uint32_t               *cbuf,
+ uint32_t               *pos
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    <none>                                                                 |
+\*=========================================================================*/
+{
+  uint32_t port = IDE_Controller_Table[minor].port1;
+  uint32_t cnt = 0;
+#if PC386_IDE_DEBUG_OUT
+  int i32 = 0;
+  pc386_ide_printk("pc386_ide_read_block(bs=%u,bn=%u,bl=%u,cb=%d,p=%d)\n",
+                   block_size, bufs[(*cbuf)].block, llength, *cbuf, *pos);
+#endif
+
+  while (cnt < block_size)
+  {
+    uint16_t *lbuf;
+    uint8_t  status_val;
+    int      b;
+
+    if (!pc386_ide_status_data_ready (port, pc386_ide_timeout,
+                                      &status_val, pc386_ide_tasking_sleep))
+    {
+      printk ("pc386_ide_read_block: block=%" PRIu32 \
+              " cbuf=%" PRIu32 " status=%02x, cnt=%" PRIu32 " bs=%" PRIu32 "\n",
+              bufs[*cbuf].block, *cbuf, status_val, cnt, block_size);
+      /* FIXME: add an error here. */
+      return;
+    }
+
+    if (status_val & IDE_REGISTER_STATUS_ERR)
+    {
+      inport_byte(port+IDE_REGISTER_ERROR, status_val);
+      printk("pc386_ide_read_block: error: %02x\n", status_val);
+      return;
+    }
+
+    lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer) + (*pos));
+
+    for (b = 0; b < (ATA_SECTOR_SIZE / 2); b++)
+    {
+      inport_word(port+IDE_REGISTER_DATA,*lbuf);
+
+#if PC386_IDE_DEBUG_OUT
+      pc386_ide_printk("%04x ",*lbuf);
+      i32++;
+      if (i32 >= 16)
+      {
+        pc386_ide_printk("\n");
+        i32 = 0;
+      }
+#endif
+      lbuf++;
+    }
+    cnt    += ATA_SECTOR_SIZE;
+    (*pos) += ATA_SECTOR_SIZE;
+    if ((*pos) == bufs[(*cbuf)].length) {
+      (*pos) = 0;
+      (*cbuf)++;
+      lbuf = bufs[(*cbuf)].buffer;
+    }
+  }
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static void pc386_ide_write_block
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  write a IDE controller data block                                        |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int minor,
+ uint32_t                block_size,
+ rtems_blkdev_sg_buffer *bufs,
+ uint32_t               *cbuf,
+ uint32_t               *pos
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    <none>                                                                 |
+\*=========================================================================*/
+{
+  uint32_t port = IDE_Controller_Table[minor].port1;
+  uint32_t cnt = 0;
+#if PC386_IDE_DEBUG_OUT
+  int i32 = 0;
+  pc386_ide_printk("pc386_ide_write_block(bs=%u,bn=%u,bl=%u,cb=%d,p=%d)\n",
+                   block_size, bufs[(*cbuf)].block, llength, *cbuf, *pos);
+#endif
+
+  while (cnt < block_size)
+  {
+    uint16_t *lbuf;
+    uint8_t  status_val;
+    int      b;
+
+    if (!pc386_ide_status_data_ready (port, pc386_ide_timeout,
+                                      &status_val, pc386_ide_tasking_sleep))
+    {
+      printk ("pc386_ide_write_block: block=%" PRIu32 " status=%02x, cnt=%" PRIu32 " bs=%" PRIu32 "\n",
+              bufs[*cbuf].block, status_val, cnt, block_size);
+      /* FIXME: add an error here. */
+      return;
+    }
+
+    if (status_val & IDE_REGISTER_STATUS_ERR)
+    {
+      inport_byte(port+IDE_REGISTER_ERROR, status_val);
+      printk ("pc386_ide_write_block: error: %02x\n", status_val);
+      return;
+    }
+
+    lbuf = (uint16_t*)(((uint8_t*)bufs[*cbuf].buffer) + (*pos));
+
+    for (b = 0; b < (ATA_SECTOR_SIZE / 2); b++)
+    {
+#if PC386_IDE_DEBUG_OUT
+      pc386_ide_printk("%04x ",*lbuf);
+      i32++;
+      if (i32 >= 16)
+      {
+        pc386_ide_printk("\n");
+        i32 = 0;
+      }
+#endif
+      outport_word(port+IDE_REGISTER_DATA,*lbuf);
+      lbuf++;
+    }
+    cnt    += ATA_SECTOR_SIZE;
+    (*pos) += ATA_SECTOR_SIZE;
+    if ((*pos) == bufs[(*cbuf)].length) {
+      (*pos) = 0;
+      (*cbuf)++;
+      lbuf = bufs[(*cbuf)].buffer;
+    }
+  }
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static int pc386_ide_control
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  control interface for controller                                         |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int  minor,                        /* controller minor number       */
+ uint32_t   cmd,                    /* command to send               */
+ void * arg                         /* optional argument             */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    <none>                                                                 |
+\*=========================================================================*/
+{
+  return 0;
+}
+
+/*=========================================================================*\
+| Function:                                                                 |
+\*-------------------------------------------------------------------------*/
+static rtems_status_code pc386_ide_config_io_speed
+(
+/*-------------------------------------------------------------------------*\
+| Purpose:                                                                  |
+|  set up transfer speed, if possible                                       |
++---------------------------------------------------------------------------+
+| Input Parameters:                                                         |
+\*-------------------------------------------------------------------------*/
+ int        minor,                   /* controller minor number       */
+ uint16_t   modes_avail              /* optional argument             */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value:                                                             |
+|    rtems_status_code                                                      |
+\*=========================================================================*/
+{
+  return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * The following table configures the functions used for IDE drivers
+ * in this BSP.
+ */
+
+ide_ctrl_fns_t pc386_ide_ctrl_fns = {
+  pc386_ide_probe,
+  pc386_ide_initialize,
+  pc386_ide_control,
+  pc386_ide_read_reg,
+  pc386_ide_write_reg,
+  pc386_ide_read_block,
+  pc386_ide_write_block,
+  pc386_ide_config_io_speed
+};
Index: bsps/i386/pc386/ata/idecfg.c
===================================================================
--- bsps/i386/pc386/ata/idecfg.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/i386/pc386/ata/idecfg.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,145 @@
+/*===============================================================*\
+| Project: RTEMS PC386 IDE harddisc driver tables                 |
++-----------------------------------------------------------------+
+| File: idecfg.c                                                  |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2003 IMD                       |
+|      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler      |
+|               <Thomas.Doerfler@imd-systems.de>                  |
+|                       all rights reserved                       |
++-----------------------------------------------------------------+
+| this file contains the table of functions for the BSP layer     |
+| for IDE access below the libchip IDE harddisc driver            |
+|                                                                 |
++-----------------------------------------------------------------+
+|   date                      history                        ID   |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.14.03  creation                                         doe  |
+\*===============================================================*/
+
+#include <rtems.h>
+#include <bsp.h>
+#include <libchip/ide_ctrl.h>
+#include <libchip/ide_ctrl_cfg.h>
+#include <libchip/ide_ctrl_io.h>
+
+extern bool pc386_ide_show;
+
+/*
+ * The following table configures the functions used for IDE drivers
+ * in this BSP.
+ */
+
+/*
+ * The following table configures the IDE drivers used in this BSP.
+ */
+extern ide_ctrl_fns_t pc386_ide_ctrl_fns;
+
+/* IDE controllers Table */
+ide_controller_bsp_table_t IDE_Controller_Table[] = {
+  {"/dev/ide0",
+   IDE_STD, /* standard IDE controller */
+   &pc386_ide_ctrl_fns,
+   NULL, /* probe for IDE standard registers */
+   FALSE, /* not (yet) initialized */
+   0x1f0,  /* base I/O address for first IDE controller */
+   FALSE,0, /* not (yet) interrupt driven */
+   NULL
+  }
+  , /* colon only needed when both interfaces present */
+  {"/dev/ide1",
+   IDE_STD, /* standard IDE controller */
+   &pc386_ide_ctrl_fns,
+   NULL, /* probe for IDE standard registers */
+   FALSE, /* not (yet) initialized */
+   0x170,  /* base I/O address for second IDE controller */
+   FALSE,0, /* not (yet) interrupt driven */
+   NULL
+  }
+};
+
+/* Number of rows in IDE_Controller_Table. Default is 0. */
+unsigned long IDE_Controller_Count;
+
+#if IDE_USE_PRIMARY_INTERFACE
+#define IDE1_DEFAULT true
+#else
+#define IDE1_DEFAULT false
+#endif
+#if IDE_USE_SECONDARY_INTERFACE
+#define IDE2_DEFAULT true
+#else
+#define IDE2_DEFAULT false
+#endif
+
+void bsp_ide_cmdline_init(void)
+{
+  const char* ide_disable;
+
+  ide_disable = bsp_cmdline_arg ("--ide-disable");
+
+  if (ide_disable == NULL) {
+    bool ide1 = IDE1_DEFAULT;
+    bool ide2 = IDE2_DEFAULT;
+    const char* ide;
+
+    /*
+     * Can have:
+     *  --ide=0,1
+     */
+    ide = bsp_cmdline_arg ("--ide=");
+
+    if (ide)
+    {
+      int i;
+      /*
+       * If a command line option exists remove the defaults.
+       */
+      ide1 = ide2 = false;
+
+      ide += sizeof ("--ide=") - 1;
+
+      for (i = 0; i < 3; i++)
+      {
+        switch (ide[i])
+        {
+          case '0':
+            ide1 = true;
+            break;
+          case '1':
+            ide2 = true;
+            break;
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9':
+          case ',':
+            break;
+          default:
+            break;
+        }
+      }
+    }
+
+    if (ide2 && !ide1)
+      IDE_Controller_Table[0] = IDE_Controller_Table[1];
+
+    if (ide1)
+      IDE_Controller_Count++;
+    if (ide2)
+      IDE_Controller_Count++;
+
+    /*
+     * Allow the user to get the initialise to print probing
+     * type information.
+     */
+    ide = bsp_cmdline_arg ("--ide-show");
+
+    if (ide)
+      pc386_ide_show = true;
+  }
+}
Index: bsps/powerpc/gen5200/ata/ata-dma-pio-single.c
===================================================================
--- bsps/powerpc/gen5200/ata/ata-dma-pio-single.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/powerpc/gen5200/ata/ata-dma-pio-single.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2011-2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define NDEBUG
+
+#include <bsp/ata.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/fatal.h>
+#include <bsp/irq.h>
+
+typedef enum {
+  DATA_CURRENT = 0,
+  DATA_END,
+  DATA_REG
+} variables;
+
+typedef enum {
+  INC_0_NE = 0,
+  INC_2_NE
+} increments;
+
+/*
+ * for
+ *   idx0 = DATA_CURRENT, idx1 = DATA_REG
+ *   idx0 != DATA_END
+ *   idx0 += 2, idx1 += 0
+ * do
+ *   *idx0 = *idx1 [INT, 16 bit] OR *idx1 = *idx0 [INT, 16 bit]
+ */
+static const uint32_t ops[] = {
+  LCD(0, VAR(DATA_CURRENT), 0, VAR(DATA_REG), TERM_FIRST, VAR(DATA_END), INC_2_NE, INC_0_NE),
+    0, /* Transfer opcode, see transfer() */
+};
+
+static bool is_last_transfer(const ata_driver_dma_pio_single *self)
+{
+  return self->transfer_current + 1 == self->transfer_end;
+}
+
+static void start_sector_transfer(ata_driver_dma_pio_single *self)
+{
+  uint16_t *current = ata_sg_get_sector_data_begin(&self->sg_context, self->transfer_current);
+  bestcomm_task_set_variable(&self->task, DATA_CURRENT, (uint32_t) current);
+  bestcomm_task_set_variable(&self->task, DATA_END, (uint32_t) ata_sg_get_sector_data_end(&self->sg_context, current));
+  bestcomm_task_start(&self->task);
+
+  bool last = is_last_transfer(self);
+  ++self->transfer_current;
+
+  if (!last) {
+    ata_flush_sector(ata_sg_get_sector_data_begin(&self->sg_context, self->transfer_current));
+  }
+}
+
+static void dma_pio_single_interrupt_handler(void *arg)
+{
+  ata_driver_dma_pio_single *self = arg;
+  bool ok = ata_check_status();
+  bool send_event = false;
+  if (ok && self->transfer_current != self->transfer_end) {
+    bool enable_dma_interrupt = self->read && is_last_transfer(self);
+    if (enable_dma_interrupt) {
+      bestcomm_task_irq_clear(&self->task);
+      bestcomm_task_irq_enable(&self->task);
+    }
+
+    start_sector_transfer(self);
+  } else {
+    send_event = true;
+  }
+
+  if (send_event) {
+    bestcomm_task_wakeup_event_task(&self->task);
+  }
+}
+
+static bool transfer_dma_pio_single(ata_driver *super, bool read, rtems_blkdev_sg_buffer *sg, size_t sg_count)
+{
+  bool ok = true;
+  ata_driver_dma_pio_single *self = (ata_driver_dma_pio_single *) super;
+
+  self->read = read;
+  ata_sg_reset(&self->sg_context, sg, sg_count);
+  rtems_blkdev_bnum start_sector = ata_sg_get_start_sector(&self->sg_context);
+  rtems_blkdev_bnum sector_count = ata_sg_get_sector_count(&self->sg_context);
+  rtems_blkdev_bnum relative_sector = 0;
+
+  ata_flush_sector(ata_sg_get_sector_data_begin(&self->sg_context, relative_sector));
+
+  uint8_t command = ata_read_or_write_sectors_command(read);
+
+  uint32_t opcode;
+  if (read) {
+    opcode = DRD1A(INT, INIT_ALWAYS, DEST_DEREF_IDX(0), SZ_16, SRC_DEREF_IDX(1), SZ_16);
+  } else {
+    opcode = DRD1A(INT, INIT_ALWAYS, DEST_DEREF_IDX(1), SZ_16, SRC_DEREF_IDX(0), SZ_16);
+  }
+
+  bestcomm_task_irq_disable(&self->task);
+  bestcomm_task_associate_with_current_task(&self->task);
+
+  size_t transfer_opcode_index = 1; /* See ops */
+  bestcomm_task_set_opcode(&self->task, transfer_opcode_index, opcode);
+
+  while (ok && relative_sector < sector_count) {
+    rtems_blkdev_bnum remaining_sectors = sector_count - relative_sector;
+    rtems_blkdev_bnum transfer_count = ata_max_transfer_count(remaining_sectors);
+
+    self->transfer_current = relative_sector;
+    self->transfer_end = relative_sector + transfer_count;
+
+    ok = ata_execute_io_command(command, start_sector + relative_sector, transfer_count);
+    if (ok) {
+      if (!read) {
+        ok = ata_wait_for_data_request();
+        assert(ok);
+
+        rtems_interrupt_level level;
+        rtems_interrupt_disable(level);
+        start_sector_transfer(self);
+        rtems_interrupt_enable(level);
+      }
+
+      bestcomm_task_wait(&self->task);
+
+      ok = ata_check_status();
+
+      relative_sector += ATA_PER_TRANSFER_SECTOR_COUNT_MAX;
+    }
+  }
+
+  return ok;
+}
+
+static int io_control_dma_pio_single(
+  rtems_disk_device *dd,
+  uint32_t cmd,
+  void *arg
+)
+{
+  return ata_driver_io_control(dd, cmd, arg, transfer_dma_pio_single);
+}
+
+void ata_driver_dma_pio_single_create(ata_driver_dma_pio_single *self, const char *device_file_path, TaskId task_index)
+{
+  ata_driver_create(&self->super, device_file_path, io_control_dma_pio_single);
+
+  self->read = false;
+
+  if (ata_driver_is_card_present(&self->super)) {
+    bestcomm_task_create_and_load(&self->task, task_index, ops, sizeof(ops));
+
+    bestcomm_task_set_variable(&self->task, DATA_REG, (uint32_t) &ATA->write.data);
+
+    bestcomm_task_set_increment_and_condition(&self->task, INC_0_NE, 0, COND_NE);
+    bestcomm_task_set_increment_and_condition(&self->task, INC_2_NE, 2, COND_NE);
+
+    bestcomm_task_enable_combined_write(&self->task, true);
+    bestcomm_task_enable_read_buffer(&self->task, true);
+    bestcomm_task_enable_speculative_read(&self->task, true);
+
+    ata_clear_interrupts();
+
+    rtems_status_code sc = rtems_interrupt_handler_install(
+      BSP_SIU_IRQ_ATA,
+      "ATA",
+      RTEMS_INTERRUPT_UNIQUE,
+      dma_pio_single_interrupt_handler,
+      self
+    );
+    if (sc != RTEMS_SUCCESSFUL) {
+      bsp_fatal(MPC5200_FATAL_ATA_DMA_SINGLE_IRQ_INSTALL);
+    }
+  }
+}
Index: bsps/powerpc/gen5200/ata/ata-instance.c
===================================================================
--- bsps/powerpc/gen5200/ata/ata-instance.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/powerpc/gen5200/ata/ata-instance.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011-2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/ata.h>
+#include <bsp/fatal.h>
+
+#include <libchip/ata.h>
+
+#include <bsp.h>
+
+static ata_driver_dma_pio_single ata_driver_instance;
+
+rtems_status_code rtems_ata_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor_arg,
+  void *arg
+)
+{
+  rtems_status_code sc = rtems_disk_io_initialize();
+
+  if (sc == RTEMS_SUCCESSFUL) {
+    bestcomm_glue_init();
+
+    ata_driver_dma_pio_single_create(&ata_driver_instance, "/dev/hda", TASK_PCI_TX);
+  } else {
+    bsp_fatal(MPC5200_FATAL_ATA_DISK_IO_INIT);
+  }
+
+  return sc;
+}
Index: bsps/powerpc/gen5200/ata/idecfg.c
===================================================================
--- bsps/powerpc/gen5200/ata/idecfg.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/powerpc/gen5200/ata/idecfg.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,100 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP                              |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2005                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the IDE configuration                        |
+\*===============================================================*/
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/mpc5200.h>
+#include "./pcmcia_ide.h"
+
+#include <libchip/ide_ctrl.h>
+#include <libchip/ide_ctrl_cfg.h>
+#include <libchip/ide_ctrl_io.h>
+
+/*
+ * The following table configures the IDE driver used in this BSP.
+ */
+extern ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns;
+
+volatile uint32_t * mpc5200_ata_drive_regs[] =
+  {
+  (uint32_t *)&(mpc5200.ata_ddr),       /* data (offset 0x00)                */
+  (uint32_t *)&(mpc5200.ata_dfr_der),   /* features / error (offset 0x01)    */
+  (uint32_t *)&(mpc5200.ata_dscr),      /* sector count (offset 0x02)        */
+  (uint32_t *)&(mpc5200.ata_dsnr),      /* sector no.   / lba0 (offset 0x03) */
+  (uint32_t *)&(mpc5200.ata_dclr),      /* cylinder low / lba1 (offset 0x04) */
+  (uint32_t *)&(mpc5200.ata_dchr),      /* cylinder high/ lba2 (offset 0x05) */
+  (uint32_t *)&(mpc5200.ata_ddhr),      /* device head  / lba3 (offset 0x06) */
+  (uint32_t *)&(mpc5200.ata_dcr_dsr),   /* command /status (offset 0x07)     */
+
+  (uint32_t *)&(mpc5200.ata_dctr_dasr), /* device control / alternate status (offset 0x08) */
+  (uint32_t *)&(mpc5200.ata_ddr),       /* (offset 0x09) */
+  (uint32_t *)&(mpc5200.ata_ddr),       /* (offset 0x0A) */
+  NULL,                                 /* (offset 0x0B) */
+  NULL,                                 /* (offset 0x0C) */
+  NULL,                                 /* (offset 0x0D) */
+  NULL,                                 /* (offset 0x0E) */
+  NULL                                  /* (offset 0x0F) */
+  };
+
+/* IDE controllers Table */
+ide_controller_bsp_table_t IDE_Controller_Table[] =
+  {
+    {
+	"/dev/idepcmcia",
+    IDE_CUSTOM,                                        /* PCMCIA Flash cards emulate custom IDE controller */
+    &mpc5200_pcmciaide_ctrl_fns,                       /* pointer to function set used for IDE drivers in this BSP */
+    NULL,                                              /* no BSP dependent probe needed */
+    FALSE,                                             /* not (yet) initialized */
+    (uint32_t)0,                                     /* no port address but custom reg.set in params is used */
+#ifdef ATA_USE_INT
+    TRUE,                                              /* interrupt driven */
+#else
+    FALSE,                                             /* non interrupt driven     */
+#endif
+    BSP_SIU_IRQ_ATA,                                   /* interrupt vector         */
+    NULL                                               /* no additional parameters */
+    }
+};
+
+/* Number of rows in IDE_Controller_Table */
+unsigned long IDE_Controller_Count = sizeof(IDE_Controller_Table)/sizeof(IDE_Controller_Table[0]);
+
+uint32_t ata_pio_timings[2][6] =
+ {
+   /* PIO3 timings in nanosconds */
+   {
+   180, /* t0 cycle time */
+   80,  /* t2 DIOR-/DIOW pulse width 8 bit */
+   80,  /* t1 DIOR-/DIOW pulse width 16 bit */
+   10,  /* t4 DIOW- data hold */
+   30,  /* t1 Addr.valid to DIOR-/DIOW setup */
+   35,  /* ta IORDY setup time */
+   },
+   /* PIO4 timings in nanosconds */
+   {
+   120, /* t0 cycle time */
+   70,  /* t1 DIOR-/DIOW pulse width 8 bit */
+   70,  /* t1 DIOR-/DIOW pulse width 16 bit */
+   10,  /* t4 DIOW- data hold */
+   25,  /* t1 Addr.valid to DIOR-/DIOW setup */
+   35,  /* ta IORDY setup time */
+   }
+ };
+
+
Index: bsps/powerpc/gen5200/ata/pcmcia_ide.c
===================================================================
--- bsps/powerpc/gen5200/ata/pcmcia_ide.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/powerpc/gen5200/ata/pcmcia_ide.c	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,682 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP                              |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2005                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the PCMCIA IDE access functions              |
+\*===============================================================*/
+/***********************************************************************/
+/*                                                                     */
+/*   Module:       pcmcia_ide.c                                        */
+/*   Date:         07/17/2003                                          */
+/*   Purpose:      RTEMS MPC5x00 PCMCIA IDE harddisk driver            */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Description:                                                      */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Code                                                              */
+/*   References:   RTEMS MBX8xx PCMCIA IDE harddisc driver             */
+/*   Module:       pcmcia_ide.c                                        */
+/*   Project:      RTEMS 4.6.0pre1 / Mbx8xx BSP                        */
+/*   Version                                                           */
+/*   Date:         01/14/2003                                          */
+/*                                                                     */
+/*   Author(s) / Copyright(s):                                         */
+/*                                                                     */
+/*                    Copyright (c) 2003 IMD                           */
+/*      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler          */
+/*               <Thomas.Doerfler@imd-systems.de>                      */
+/*                       all rights reserved                           */
+/*                                                                     */
+/*  this file contains the BSP layer for PCMCIA IDE access below the   */
+/*  libchip IDE harddisc driver based on a board specific driver from  */
+/*  Eugeny S. Mints, Oktet                                             */
+/*                                                                     */
+/*  The license and distribution terms for this file may be            */
+/*  found in the file LICENSE in this distribution or at               */
+/*  http://www.rtems.org/license/LICENSE.                         */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Partially based on the code references which are named above.     */
+/*   Adaptions, modifications, enhancements and any recent parts of    */
+/*   the code are under the right of                                   */
+/*                                                                     */
+/*         IPR Engineering, Dachauer StraÃe 38, D-80335 MÃŒnchen        */
+/*                        Copyright(C) 2003                            */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   IPR Engineering makes no representation or warranties with        */
+/*   respect to the performance of this computer program, and          */
+/*   specifically disclaims any responsibility for any damages,        */
+/*   special or consequential, connected with the use of this program. */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Version history:  1.0                                             */
+/*                                                                     */
+/***********************************************************************/
+
+#include <sys/param.h>
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/score/sysstate.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/mpc5200.h>
+#include "./pcmcia_ide.h"
+
+#include <libchip/ide_ctrl.h>
+#include <libchip/ide_ctrl_cfg.h>
+#include <libchip/ide_ctrl_io.h>
+#include <string.h>
+
+#define IDE_DMA_TEST            FALSE
+
+/* DMA supported PIO mode is broken */
+#define IDE_USE_INT             TRUE
+#define IDE_READ_USE_DMA        FALSE
+#define IDE_USE_READ_PIO_OPT    FALSE
+#define IDE_WRITE_USE_DMA       FALSE
+#define IDE_USE_WRITE_PIO_OPT   FALSE
+#define IDE_USE_DMA (IDE_READ_USE_DMA || IDE_WRITE_USE_DMA)
+
+#define IDE_USE_STATISTICS      TRUE
+
+#if IDE_USE_DMA
+#define PCMCIA_IDE_DMA_WR_BD_CNT 2
+#define PCMCIA_IDE_DMA_RD_BD_CNT 2
+#define PCMCIA_IDE_INTERRUPT_EVENT RTEMS_EVENT_2
+/* Task number assignment */
+#include "../bestcomm/bestcomm_glue.h"
+#include "../bestcomm/bestcomm_api.h"
+#include "../bestcomm/task_api/bestcomm_cntrl.h"
+#include "../bestcomm/task_api/tasksetup_bdtable.h"
+
+#define IDE_RX_TASK_NO TASK_GEN_DP_BD_0
+#define IDE_TX_TASK_NO TASK_GEN_DP_BD_1
+static TaskId pcmcia_ide_rxTaskId;	/* SDMA RX task ID */
+static TaskId pcmcia_ide_txTaskId;	/* SDMA TX task ID */
+#define PCMCIA_IDE_RD_SECTOR_SIZE 512   /* FIXME: make this better... */
+#define PCMCIA_IDE_WR_SECTOR_SIZE 512   /* FIXME: make this better... */
+
+bool mpc5200_dma_task_started[2] = {false,false};
+#endif /* IDE_USE_DMA */
+
+#if IDE_USE_STATISTICS
+uint32_t mpc5200_pcmciaide_write_block_call_cnt  = 0;
+uint32_t mpc5200_pcmciaide_write_block_block_cnt = 0;
+uint32_t mpc5200_pcmciaide_read_block_call_cnt   = 0;
+uint32_t mpc5200_pcmciaide_read_block_block_cnt  = 0;
+#endif
+
+extern volatile uint32_t * mpc5200_ata_drive_regs[];
+extern uint32_t ata_pio_timings[2][6];
+
+void mpc5200_pcmciaide_dma_blockop(
+  bool, int, uint16_t, rtems_blkdev_sg_buffer *, uint32_t *, uint32_t *);
+/*
+ * support functions for PCMCIA IDE IF
+ */
+static bool mpc5200_pcmciaide_probe(int minor)
+  {
+  bool ide_card_plugged = false; /* assume: we don't have a card plugged in */
+  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT2]);
+
+  #ifdef MPC5200_BOARD_DP2
+    /* Deactivate RESET signal */
+    rtems_interrupt_level level;
+    rtems_interrupt_disable(level);
+    mpc5200.gpiowe |= GPIO_W_PIN_PSC1_4;
+    mpc5200.gpiowod &= ~GPIO_W_PIN_PSC1_4;
+    mpc5200.gpiowdd |= GPIO_W_PIN_PSC1_4;
+    mpc5200.gpiowdo |= GPIO_W_PIN_PSC1_4;
+    rtems_interrupt_enable(level);
+    /* FIXME */
+    volatile int i = 0;
+    while (++i < 20000000);
+  #endif
+
+  /* enable card detection on GPT2 */
+  gpt->emsel = (GPT_EMSEL_GPIO_IN | GPT_EMSEL_TIMER_MS_GPIO);
+
+#if defined (MPC5200_BOARD_BRS5L)
+  /* Check for card detection (-CD0) */
+  if((gpt->status) & GPT_STATUS_PIN)
+    ide_card_plugged = false;
+  else
+#endif
+    ide_card_plugged = true;
+
+  return ide_card_plugged;
+
+  }
+
+#define DMA1_T0(val) BSP_BFLD32(COUNT_VAL(val), 0, 7)
+#define DMA1_TD(val) BSP_BFLD32(COUNT_VAL(val), 8, 15)
+#define DMA1_TK(val) BSP_BFLD32(COUNT_VAL(val), 16, 23)
+#define DMA1_TM(val) BSP_BFLD32(COUNT_VAL(val), 24, 31)
+
+#define DMA2_TH(val) BSP_BFLD32(COUNT_VAL(val), 0, 7)
+#define DMA2_TJ(val) BSP_BFLD32(COUNT_VAL(val), 8, 15)
+#define DMA2_TN(val) BSP_BFLD32(COUNT_VAL(val), 16, 23)
+
+static rtems_status_code mpc5200_pcmciaide_config_io_speed(int minor, uint16_t modes_avail)
+  {
+  uint8_t pio_t0, pio_t2_8, pio_t2_16, pio_t4, pio_t1, pio_ta;
+
+  if((modes_avail & ATA_MODES_PIO4) != 0)
+    {
+
+    pio_t0    = ata_pio_timings[PIO_4][T0];
+    pio_t2_8  = ata_pio_timings[PIO_4][T2_8];
+    pio_t2_16 = ata_pio_timings[PIO_4][T2_16];
+    pio_t4    = ata_pio_timings[PIO_4][T4];
+    pio_t1    = ata_pio_timings[PIO_4][T1];
+    pio_ta    = ata_pio_timings[PIO_4][TA];
+
+    }
+  else
+    {
+
+    pio_t0    = ata_pio_timings[PIO_3][T0];
+    pio_t2_8  = ata_pio_timings[PIO_3][T2_8];
+    pio_t2_16 = ata_pio_timings[PIO_3][T2_16];
+    pio_t4    = ata_pio_timings[PIO_3][T4];
+    pio_t1    = ata_pio_timings[PIO_3][T1];
+    pio_ta    = ata_pio_timings[PIO_3][TA];
+
+    }
+
+  /* set timings according according to selected ATA mode */
+  mpc5200.ata_pio1 = ATA_PIO_TIMING_1(pio_t0, pio_t2_8, pio_t2_16);
+  mpc5200.ata_pio2 = ATA_PIO_TIMING_2(pio_t4, pio_t1, pio_ta);
+
+  mpc5200.ata_dma1 = DMA1_T0(120) | DMA1_TD(70) | DMA1_TK(25) | DMA1_TM(25);
+  mpc5200.ata_dma2 = DMA2_TH(10) | DMA2_TJ(5) | DMA2_TN(10);
+
+  return RTEMS_SUCCESSFUL;
+
+  }
+
+
+
+static void mpc5200_pcmciaide_read_reg(int minor, int reg, uint16_t *value)
+  {
+  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
+
+  if(reg == IDE_REGISTER_DATA_WORD)
+    *value = *(volatile uint16_t *)(ata_reg);
+  else
+    *value = *(volatile uint8_t  *)(ata_reg);
+  }
+
+
+static void mpc5200_pcmciaide_write_reg(int minor, int reg, uint16_t value)
+  {
+  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
+
+  if(reg == IDE_REGISTER_DATA_WORD)
+    *(volatile uint16_t *)(ata_reg) = value;
+  else
+    *(volatile uint8_t  *)(ata_reg) = value;
+  }
+
+#if IDE_USE_DMA
+
+
+uint32_t pcmcia_ide_rxInterrupts;
+uint32_t pcmcia_ide_txInterrupts;
+volatile rtems_id pcmcia_ide_hdl_task = 0;
+/*
+ * MPC5200 BestComm interrupt handlers
+ */
+static void pcmcia_ide_recv_dmairq_hdl(rtems_irq_hdl_param unused)
+{
+  SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,IDE_RX_TASK_NO);
+
+/*Disable receive ints*/
+  bestcomm_glue_irq_disable(IDE_RX_TASK_NO);
+
+  pcmcia_ide_rxInterrupts++; 		/* Rx int has occurred */
+
+  if (pcmcia_ide_hdl_task != 0) {
+    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
+  }
+}
+
+static void pcmcia_ide_xmit_dmairq_hdl(rtems_irq_hdl_param unused)
+{
+
+  SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,IDE_TX_TASK_NO);
+
+  /*Disable transmit ints*/
+  bestcomm_glue_irq_disable(IDE_TX_TASK_NO);
+
+  pcmcia_ide_txInterrupts++; 		/* Tx int has occurred */
+
+  if (pcmcia_ide_hdl_task != 0) {
+    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
+  }
+}
+
+
+void mpc5200_pcmciaide_dma_init(int minor)
+{
+  TaskSetupParamSet_t	rxParam;	/* RX task setup parameters	*/
+  TaskSetupParamSet_t	txParam;	/* TX task setup parameters	*/
+  /*
+   * Init Bestcomm system
+   */
+  bestcomm_glue_init();
+  /*
+   * Setup the SDMA RX task.
+   */
+  rxParam.NumBD        = PCMCIA_IDE_DMA_RD_BD_CNT;
+  rxParam.Size.MaxBuf  = PCMCIA_IDE_RD_SECTOR_SIZE;
+  rxParam.Initiator    = INITIATOR_ALWAYS;
+  rxParam.StartAddrSrc =
+    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
+  rxParam.IncrSrc      = 0;
+  rxParam.SzSrc	       = sizeof(uint16_t);
+  rxParam.StartAddrDst = (uint32)NULL;
+  rxParam.IncrDst      = sizeof(uint16_t);
+  rxParam.SzDst	       = sizeof(uint16_t);  /* XXX: set this to 32 bit? */
+
+  pcmcia_ide_rxTaskId  = TaskSetup(IDE_RX_TASK_NO,&rxParam );
+
+  /*
+   * Setup the TX task.
+   */
+  txParam.NumBD        = PCMCIA_IDE_DMA_WR_BD_CNT;
+  txParam.Size.MaxBuf  = PCMCIA_IDE_WR_SECTOR_SIZE;
+  txParam.Initiator    = INITIATOR_ALWAYS;
+  txParam.StartAddrSrc = (uint32)NULL;
+  txParam.IncrSrc      = sizeof(uint16_t);
+  txParam.SzSrc        = sizeof(uint16_t); /* do not set this to 32 bit! */
+  txParam.StartAddrDst =
+    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
+  txParam.IncrDst      = 0;
+  txParam.SzDst        = sizeof(uint16_t);
+
+  pcmcia_ide_txTaskId  = TaskSetup( IDE_TX_TASK_NO, &txParam );
+  /*
+   * FIXME: Init BD rings
+   */
+  /*
+   * Enable the SmartDMA transmit/receive task.
+   * do not enable interrupts to CPU
+   */
+  /*
+   * connect interrupt handlers
+   */
+  bestcomm_glue_irq_install(IDE_TX_TASK_NO,pcmcia_ide_xmit_dmairq_hdl,NULL);
+  bestcomm_glue_irq_install(IDE_RX_TASK_NO,pcmcia_ide_recv_dmairq_hdl,NULL);
+}
+#endif /* IDE_USE_DMA */
+
+void mpc5200_pcmciaide_dma_blockop(bool is_write,
+				   int minor,
+				   uint16_t block_size,
+				   rtems_blkdev_sg_buffer *bufs,
+				   uint32_t *cbuf,
+				   uint32_t *pos)
+
+{
+#if IDE_USE_DMA
+  /*
+   * Nameing:
+   * - a block is one unit of data on disk (multiple sectors)
+   * - a buffer is a contignuous chunk of data in memory
+   * a block on disk may be filled with data from several buffers
+   */
+  uint32_t buf_idx,bufs_from_dma, bufs_to_dma,bufs_total;
+  uint32_t bds_free;
+  uint32_t llength;
+  rtems_status_code rc = RTEMS_SUCCESSFUL;
+  rtems_event_set events;
+  BDIdx nxt_bd_idx;
+  bool use_irq = (_System_state_Current == SYSTEM_STATE_UP);
+  /*
+   * determine number of blocks
+   */
+  llength = 0;
+  buf_idx = 0;
+  bufs += *cbuf; /* *cbuf is the index of the next buffer to send in this transaction */
+  while (llength < block_size) {
+    llength += bufs[buf_idx++].length;
+  }
+  bufs_from_dma = 0;
+  bufs_to_dma   = 0;
+  bufs_total    = buf_idx;
+  /*
+   * here all BDs should be unused
+   */
+  bds_free = is_write ? PCMCIA_IDE_DMA_WR_BD_CNT : PCMCIA_IDE_DMA_RD_BD_CNT;
+  /*
+   * repeat, until all bufs are transferred
+   */
+  while ((rc == RTEMS_SUCCESSFUL) &&
+	 (bufs_from_dma < bufs_total)) {
+
+    while ((rc == RTEMS_SUCCESSFUL) &&
+	   (bufs_to_dma < bufs_total) &&
+	   (bds_free > 0)) {
+      /*
+       * fill in BD, set interrupt if needed
+       */
+    SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,(is_write
+	                                  ? IDE_TX_TASK_NO
+	                                  : IDE_RX_TASK_NO));
+      if (is_write) {
+	TaskBDAssign(pcmcia_ide_txTaskId ,
+		     (void *)bufs[bufs_to_dma].buffer,
+		     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
+		     bufs[bufs_to_dma].length,
+		     0/* flags */);
+#if IDE_USE_STATISTICS
+	mpc5200_pcmciaide_write_block_block_cnt++;
+#endif
+      }
+      else {
+	TaskBDAssign(pcmcia_ide_rxTaskId ,
+		     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
+		     (void *)bufs[bufs_to_dma].buffer,
+		     bufs[bufs_to_dma].length,
+		     0/* flags */);
+#if IDE_USE_STATISTICS
+	mpc5200_pcmciaide_read_block_block_cnt++;
+#endif
+      }
+      bufs_to_dma ++;
+      bds_free    --;
+    }
+    if (is_write) {
+      TaskStart( pcmcia_ide_txTaskId, TASK_AUTOSTART_DISABLE,
+		 pcmcia_ide_txTaskId, TASK_INTERRUPT_DISABLE );
+    }
+    else {
+      TaskStart( pcmcia_ide_rxTaskId, TASK_AUTOSTART_DISABLE,
+		 pcmcia_ide_rxTaskId, TASK_INTERRUPT_DISABLE );
+    }
+    if (use_irq) {
+
+      /*
+       * enable interrupts, wait for interrupt event
+       */
+      pcmcia_ide_hdl_task = rtems_task_self();
+      bestcomm_glue_irq_enable((is_write
+				? IDE_TX_TASK_NO
+				: IDE_RX_TASK_NO));
+
+      rtems_event_receive(PCMCIA_IDE_INTERRUPT_EVENT,
+			  RTEMS_WAIT | RTEMS_EVENT_ANY,
+			  RTEMS_NO_TIMEOUT, &events);
+
+      pcmcia_ide_hdl_task = 0;
+    }
+    else {
+      /*
+       * HACK: just wait some time...
+       */
+      /*
+       * FIXME: poll, until SDMA is finished
+       */
+      volatile int32_t i;
+      for (i = 0;i < 10000;i++) {};
+    }
+
+    do {
+	  nxt_bd_idx = TaskBDRelease(is_write
+	   				             ? pcmcia_ide_txTaskId
+					             : pcmcia_ide_rxTaskId);
+      if ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
+          (nxt_bd_idx != TASK_ERR_BD_BUSY)) {
+        (*cbuf)++;
+        (*pos) += bufs[bufs_from_dma].length;
+        bufs_from_dma++;
+        bds_free++;
+	  }
+    } while ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
+             (nxt_bd_idx != TASK_ERR_BD_BUSY)       &&
+  	         (bufs_from_dma < bufs_to_dma));
+  }
+#endif /* IDE_USE_DMA */
+}
+
+
+static void mpc5200_pcmciaide_read_block(int minor, uint32_t block_size,
+    rtems_blkdev_sg_buffer *bufs, uint32_t *cbuf, uint32_t *pos)
+{
+
+  volatile uint32_t *ata_reg=mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
+  uint16_t  cnt = 0;
+  uint16_t *lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer)+(*pos));
+  uint32_t  llength = bufs[(*cbuf)].length;
+  bool      use_dma;
+
+#if IDE_USE_STATISTICS
+      mpc5200_pcmciaide_read_block_call_cnt++;
+#endif
+#if IDE_READ_USE_DMA
+  /*
+   * FIXME: walk through buffer list. If any buffer has other size than default,
+   * then do not use DMA
+   * Is this needed?
+   */
+  use_dma = true;
+  /* use_dma = false; */
+#else
+  use_dma = false;
+#endif
+  if (use_dma) {
+    /*
+     * FIXME: wait for DRQ ready
+     * check, that once DRQ is ready, we really can send ALL data for this
+     * type of transfer mode
+     */
+    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
+						 (mpc5200.ata_dctr_dasr)) &
+	    IDE_REGISTER_STATUS_DRQ) == 0);
+    /*
+     * translate (part of) buffer list into DMA BDs
+     * only last (available) DMA BD sends interrupt
+     * DMA BDs may get ready as soon as possible
+     */
+    mpc5200_pcmciaide_dma_blockop(FALSE, /* read operation */
+				  minor,
+				  block_size,bufs,cbuf,pos);
+  }
+  else {
+#if IDE_USE_READ_PIO_OPT
+    while(cnt < block_size) {
+
+      *lbuf++ = GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*(volatile uint32_t *)(ata_reg)); /* only 16 bit data port */
+      cnt += 2;
+      (*pos) += 2;
+
+      if((*pos) == llength) {
+
+	  (*pos) = 0;
+	  (*cbuf)++;
+	  lbuf = bufs[(*cbuf)].buffer;
+	  llength = bufs[(*cbuf)].length;
+
+      }
+    }
+#else
+
+    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) & IDE_REGISTER_STATUS_DRQ) && (cnt < block_size)) {
+
+      *lbuf++ = *(volatile uint16_t *)(ata_reg); /* only 16 bit data port */
+      cnt += 2;
+      (*pos) += 2;
+
+      if((*pos) == llength) {
+	(*pos) = 0;
+	(*cbuf)++;
+	lbuf = bufs[(*cbuf)].buffer;
+	llength = bufs[(*cbuf)].length;
+      }
+    }
+#endif
+  }
+}
+
+static void mpc5200_pcmciaide_write_block(int minor, uint32_t block_size,
+    rtems_blkdev_sg_buffer *bufs, uint32_t *cbuf, uint32_t *pos)
+{
+
+
+  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
+  uint16_t  cnt = 0;
+  uint16_t *lbuf = (uint16_t *)((uint8_t *)(bufs[(*cbuf)].buffer) + (*pos));
+  uint32_t  llength = bufs[(*cbuf)].length;
+  bool use_dma;
+
+#if IDE_USE_STATISTICS
+  mpc5200_pcmciaide_write_block_call_cnt++;
+#endif
+#if IDE_WRITE_USE_DMA
+  /*
+   * FIXME: walk through buffer list. If any buffer has other size than default,
+   * then do not use DMA
+   * Is this needed?
+   */
+  use_dma = true;
+#else
+  use_dma = false;
+#endif
+
+  if (use_dma) {
+    /*
+     * wait for DRQ ready
+     * FIXME: check, that once DRQ is ready, we really can send ALL data for this
+     * type of transfer mode
+     */
+    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
+						 (mpc5200.ata_dctr_dasr)) &
+	    IDE_REGISTER_STATUS_DRQ) == 0);
+    /*
+     * translate (part of) buffer list into DMA BDs
+     * only last (available) DMA BD sends interrupt
+     * DMA BDs may get ready as soon as possible
+     */
+    mpc5200_pcmciaide_dma_blockop(true, /* write opeartion */
+				  minor,
+				  block_size,bufs,cbuf,pos);
+  }
+  else {
+#if IDE_USE_WRITE_PIO_OPT
+    while(cnt < block_size) {
+      int32_t loop_cnt,loop_max;
+
+#if IDE_USE_STATISTICS
+      mpc5200_pcmciaide_write_block_block_cnt++;
+#endif
+
+      loop_max = llength - (*pos) ;
+      if (loop_max > (block_size - cnt)) {
+	loop_max = (block_size - cnt);
+      }
+      for (loop_cnt = loop_max/2;loop_cnt > 0;loop_cnt--) {
+	*(volatile uint32_t *)(ata_reg) =
+	  SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*lbuf++); /* only 16 bit data port */
+      }
+      cnt += loop_max;
+      (*pos) += loop_max;
+
+      if((*pos) == llength) {
+
+	(*pos) = 0;
+	(*cbuf)++;
+	lbuf = bufs[(*cbuf)].buffer;
+	llength = bufs[(*cbuf)].length;
+      }
+    }
+#else
+    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr))
+	   & IDE_REGISTER_STATUS_DRQ)
+	  && (cnt < block_size)) {
+      *(volatile uint16_t *)(ata_reg) = *lbuf++; /* only 16 bit data port */
+      cnt += 2;
+      (*pos) += 2;
+
+      if((*pos) == llength) {
+	(*pos) = 0;
+	(*cbuf)++;
+	lbuf = bufs[(*cbuf)].buffer;
+	llength = bufs[(*cbuf)].length;
+      }
+    }
+#endif
+  }
+}
+
+static int mpc5200_pcmciaide_control(int  minor, uint32_t cmd, void * arg)
+  {
+  return RTEMS_SUCCESSFUL;
+  }
+
+static void mpc5200_pcmciaide_initialize(int minor)
+  {
+#if defined (MPC5200_BOARD_BRS5L)
+  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT7]);
+
+  /* invert ATA reset on GPT7 */
+  gpt->emsel = (GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO);
+#endif
+  /* reset ata host contr. and FIFO */
+  mpc5200.ata_hcfg |= (ATA_HCFG_SMR | ATA_HCFG_FR);
+  mpc5200.ata_hcfg &= ~(ATA_HCFG_SMR | ATA_HCFG_FR);
+
+  /* for the first access set lowest performance transfer mode to PIO3 */
+  mpc5200_pcmciaide_config_io_speed(minor, ATA_MODES_PIO3);
+
+  /* enable PIO operations (PIO 3/4) */
+  mpc5200.ata_hcfg |= ATA_HCFG_IORDY;
+
+#ifdef IDE_USE_INT
+  mpc5200.ata_hcfg |= ATA_HCFG_IE ;
+#endif
+
+#if IDE_USE_DMA
+  mpc5200_pcmciaide_dma_init(minor);
+#endif
+  }
+
+
+/*
+ * The following table configures the functions used for IDE drivers
+ * in this BSP.
+ */
+ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns =
+  {
+  mpc5200_pcmciaide_probe,
+  mpc5200_pcmciaide_initialize,
+  mpc5200_pcmciaide_control,
+  mpc5200_pcmciaide_read_reg,
+  mpc5200_pcmciaide_write_reg,
+  mpc5200_pcmciaide_read_block,
+  mpc5200_pcmciaide_write_block,
+  mpc5200_pcmciaide_config_io_speed
+  };
+
Index: bsps/powerpc/gen5200/ata/pcmcia_ide.h
===================================================================
--- bsps/powerpc/gen5200/ata/pcmcia_ide.h	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
+++ bsps/powerpc/gen5200/ata/pcmcia_ide.h	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -0,0 +1,98 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP                              |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2005                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains declarations for the PCMCIA IDE Interface    |
+\*===============================================================*/
+/***********************************************************************/
+/*                                                                     */
+/*   Module:       pcmcia_ide.h                                        */
+/*   Date:         17/07/2003                                          */
+/*   Purpose:      RTEMS MPC5x00 PCMCIA IDE harddisk header file       */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Description:                                                      */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Code                                                              */
+/*   References:   none                                                */
+/*   Module:                                                           */
+/*   Project:                                                          */
+/*   Version                                                           */
+/*   Date:                                                             */
+/*                                                                     */
+/*   Author(s) / Copyright(s):                                         */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Partially based on the code references which are named above.     */
+/*   Adaptions, modifications, enhancements and any recent parts of    */
+/*   the code are under the right of                                   */
+/*                                                                     */
+/*         IPR Engineering, Dachauer StraÃe 38, D-80335 MÃŒnchen        */
+/*                        Copyright(C) 2003                            */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   IPR Engineering makes no representation or warranties with        */
+/*   respect to the performance of this computer program, and          */
+/*   specifically disclaims any responsibility for any damages,        */
+/*   special or consequential, connected with the use of this program. */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/*   Version history:  1.0                                             */
+/*                                                                     */
+/***********************************************************************/
+
+#ifndef __PCMCIA_IDE_h
+#define __PCMCIA_IDE_h
+
+#include <bsp.h>
+
+#define GPIOPCR_ATA_CS_4_5                           (1 << 24)
+
+/*#define DEBUG_OUT*/
+#define GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val32)  ((uint16_t)((val32) >> 24))
+#define SET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val8)   ((uint32_t)((val8)  << 24))
+#define GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val32)  ((uint16_t)((val32) >> 16))
+#define SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val16)  ((uint32_t)((val16) << 16))
+
+#define ATA_HCFG_SMR                                 (1 << 31)
+#define ATA_HCFG_FR                                  (1 << 30)
+#define ATA_HCFG_IORDY                               (1 << 24)
+#define ATA_HCFG_IE                                  (1 << 25)
+
+#define COUNT_VAL(nsec)                              (((nsec) * (IPB_CLOCK / 1000000) + 999) / 1000)
+
+#define PIO_3                                        0
+#define PIO_4                                        1
+
+#define T0                                           0
+#define T2_8                                         1
+#define T2_16                                        2
+#define T4                                           3
+#define T1                                           4
+#define TA                                           5
+
+#define ATA_PIO_TIMING_1(t0,t2_8,t2_16)              (((COUNT_VAL(t0)) << 24) | ((COUNT_VAL(t2_8)) << 16) | ((COUNT_VAL(t2_16)) << 8))
+#define ATA_PIO_TIMING_2(t4,t1,ta)                   (((COUNT_VAL(t4)) << 24) | ((COUNT_VAL(t1)) << 16) | ((COUNT_VAL(ta)) << 8))
+
+#endif
Index: c/src/lib/libbsp/i386/pc386/Makefile.am
===================================================================
--- c/src/lib/libbsp/i386/pc386/Makefile.am	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ c/src/lib/libbsp/i386/pc386/Makefile.am	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -128,6 +128,6 @@
 if HAS_IDE
 # ide
-librtemsbsp_a_SOURCES += ide/ide.c
-librtemsbsp_a_SOURCES += ide/idecfg.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/ata/ide.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/ata/idecfg.c
 endif
 
Index: src/lib/libbsp/i386/pc386/ide/ide.c
===================================================================
--- c/src/lib/libbsp/i386/pc386/ide/ide.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,725 +1,0 @@
-/*===============================================================*\
-| Project: RTEMS PC386 IDE harddisc driver                        |
-+-----------------------------------------------------------------+
-| File: ide.c                                                     |
-+-----------------------------------------------------------------+
-|                    Copyright (c) 2003 IMD                       |
-|      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler      |
-|               <Thomas.Doerfler@imd-systems.de>                  |
-|                       all rights reserved                       |
-+-----------------------------------------------------------------+
-| this file contains the BSP layer for IDE access below the       |
-| libchip IDE harddisc driver                                     |
-| based on a board specific driver from                           |
-| Eugeny S. Mints, Oktet                                          |
-|                                                                 |
-|  The license and distribution terms for this file may be        |
-|  found in the file LICENSE in this distribution or at           |
-|  http://www.rtems.org/license/LICENSE.                     |
-|                                                                 |
-+-----------------------------------------------------------------+
-|   date                      history                        ID   |
-| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-| 01.14.03  creation                                         doe  |
-\*===============================================================*/
-
-#include <inttypes.h>
-
-#include <rtems.h>
-
-#include <bsp.h>
-#include <libchip/ide_ctrl.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ide_ctrl_io.h>
-
-#define ATA_SECTOR_SIZE (512)
-
-/*
- * Use during initialisation.
- */
-extern void Wait_X_ms(unsigned int msecs);
-
-bool pc386_ide_show;
-uint32_t pc386_ide_timeout;
-
-#define PC386_IDE_DEBUG_OUT 0
-
-#if PC386_IDE_DEBUG_OUT
-bool pc386_ide_trace;
-#define pc386_ide_printk if (pc386_ide_trace) printk
-#endif
-
-#define PC386_IDE_PROBE_TIMEOUT    (500)
-#define PC386_IDE_PRESTART_TIMEOUT (1000)
-#define PC386_IDE_TASKING_TIMEOUT  (2000)
-
-/*
- * Prestart sleep using a calibrated timing loop.
- */
-static void pc386_ide_prestart_sleep (void)
-{
-  Wait_X_ms (10);
-}
-
-/*
- * Once tasking has started we use a task sleep.
- */
-static void pc386_ide_tasking_sleep (void)
-{
-  rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (10000) ?
-                         RTEMS_MICROSECONDS_TO_TICKS (10000) : 1);
-}
-
-typedef void (*pc386_ide_sleeper)(void);
-
-static void pc386_ide_sleep (pc386_ide_sleeper sleeper)
-{
-  sleeper ();
-}
-
-static void wait(volatile uint32_t loops)
-{
-  while (loops)
-    loops--;
-}
-
-static bool pc386_ide_status_busy (uint32_t          port,
-                                   volatile uint32_t timeout,
-                                   uint8_t*          status_val,
-                                   pc386_ide_sleeper sleeper)
-{
-  volatile uint8_t status;
-  int              polls;
-
-  do
-  {
-    polls = 500;
-    while (polls)
-    {
-      inport_byte (port + IDE_REGISTER_STATUS, status);
-      if ((status & IDE_REGISTER_STATUS_BSY) == 0)
-      {
-        *status_val = status;
-        return true;
-      }
-      polls--;
-    }
-
-    if (timeout)
-    {
-      timeout--;
-      pc386_ide_sleep (sleeper);
-    }
-  }
-  while (timeout);
-
-  *status_val = status;
-  return false;
-}
-
-static bool pc386_ide_status_data_ready (uint32_t          port,
-                                         volatile uint32_t timeout,
-                                         uint8_t*          status_val,
-                                         pc386_ide_sleeper sleeper)
-{
-  volatile uint8_t status;
-  int              polls;
-
-  do
-  {
-    polls = 1000;
-    while (polls)
-    {
-      inport_byte (port + IDE_REGISTER_STATUS, status);
-
-      if (((status & IDE_REGISTER_STATUS_BSY) == 0) &&
-          (status & IDE_REGISTER_STATUS_DRQ))
-      {
-        *status_val = status;
-        return true;
-      }
-
-      polls--;
-    }
-
-    if (timeout)
-    {
-      timeout--;
-      pc386_ide_sleep (sleeper);
-    }
-  }
-  while (timeout);
-
-  *status_val = status;
-  return false;
-}
-
-/*
- * support functions for IDE harddisk IF
- */
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static bool pc386_ide_probe
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  This function should probe, whether a IDE disk is available              |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int minor
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    true, when flash disk available                                        |
-\*=========================================================================*/
-{
-  bool ide_card_plugged = true; /* assume: we have a disk here */
-
-  return ide_card_plugged;
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static void pc386_ide_initialize
-(
-/*-------------------------------------------------------------------------*\
-  | Purpose:                                                                  |
-  |  initialize IDE access                                                    |
-  +---------------------------------------------------------------------------+
-  | Input Parameters:                                                         |
-  \*-------------------------------------------------------------------------*/
-  int  minor                              /* controller minor number       */
- )
-/*-------------------------------------------------------------------------*\
-  | Return Value:                                                             |
-  |    <none>                                                                 |
-  \*=========================================================================*/
-{
-  uint32_t port = IDE_Controller_Table[minor].port1;
-  uint8_t  dev = 0;
-
-  if (pc386_ide_show)
-    printk("IDE%d: port base: %04" PRIu32 "\n", minor, port);
-
-  outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
-               (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
-  wait(10000);
-  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
-               IDE_REGISTER_DEVICE_CONTROL_SRST | IDE_REGISTER_DEVICE_CONTROL_nIEN);
-  wait(10000);
-  outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
-               IDE_REGISTER_DEVICE_CONTROL_nIEN);
-  wait(10000);
-
-  for (dev = 0; dev < 2; dev++)
-  {
-    uint16_t    capabilities = 0;
-    uint32_t    byte;
-    uint8_t     status;
-    uint8_t     error;
-    uint8_t     cyllsb;
-    uint8_t     cylmsb;
-    const char* label = dev ? " slave" : "master";
-    int         max_multiple_sectors = 0;
-    int         cur_multiple_sectors = 0;
-    uint32_t    cylinders = 0;
-    uint32_t    heads = 0;
-    uint32_t    sectors = 0;
-    uint32_t    lba_sectors = 0;
-    char        model_number[41];
-    char*       p = &model_number[0];
-    bool        data_ready;
-
-    (void) cur_multiple_sectors; /* avoid set but not used warning */
-
-    memset(model_number, 0, sizeof(model_number));
-
-    outport_byte(port+IDE_REGISTER_DEVICE_HEAD,
-                 (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0);
-    /*
-      outport_byte(port+IDE_REGISTER_SECTOR_NUMBER,
-      (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | IDE_REGISTER_LBA3_L);
-    */
-
-    outport_byte(port+IDE_REGISTER_COMMAND, 0x00);
-
-    if (!pc386_ide_status_busy (port, PC386_IDE_PROBE_TIMEOUT,
-                                &status, pc386_ide_prestart_sleep))
-      continue;
-
-    inport_byte(port+IDE_REGISTER_STATUS,        status);
-    inport_byte(port+IDE_REGISTER_ERROR,         error);
-    inport_byte(port+IDE_REGISTER_CYLINDER_LOW,  cyllsb);
-    inport_byte(port+IDE_REGISTER_CYLINDER_HIGH, cylmsb);
-
-    if (pc386_ide_show)
-    {
-      printk("IDE%d:%s: status=%02x\n", minor, label, status);
-      printk("IDE%d:%s: error=%02x\n", minor, label, error);
-      printk("IDE%d:%s: cylinder-low=%02x\n", minor, label, cyllsb);
-      printk("IDE%d:%s: cylinder-high=%02x\n", minor, label, cylmsb);
-    }
-
-    outport_byte(port+IDE_REGISTER_COMMAND, 0xec);
-
-    if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT,
-                                &status, pc386_ide_prestart_sleep))
-    {
-      if (pc386_ide_show)
-        printk("IDE%d:%s: device busy: %02x\n", minor, label, status);
-      continue;
-    }
-
-    data_ready = pc386_ide_status_data_ready (port,
-                                              250,
-                                              &status,
-                                              pc386_ide_prestart_sleep);
-
-    if (status & IDE_REGISTER_STATUS_ERR)
-    {
-      inport_byte(port+IDE_REGISTER_ERROR, error);
-      if (error != 4)
-      {
-        if (pc386_ide_show)
-          printk("IDE%d:%s: error=%04x\n", minor, label, error);
-        continue;
-      }
-      /*
-       * The device is an ATAPI device.
-       */
-      outport_byte(port+IDE_REGISTER_COMMAND, 0xa1);
-      data_ready = pc386_ide_status_data_ready (port,
-                                                250,
-                                                &status,
-                                                pc386_ide_prestart_sleep);
-    }
-
-    if (!data_ready)
-      continue;
-
-    byte = 0;
-    while (byte < 512)
-    {
-      uint16_t word;
-
-      if (pc386_ide_show && ((byte % 16) == 0))
-        printk("\n %04" PRIx32 " : ", byte);
-
-      inport_word(port+IDE_REGISTER_DATA, word);
-
-      if (pc386_ide_show)
-        printk ("%04x ", word);
-
-      if (byte == 2)
-        cylinders = word;
-      if (byte == 6)
-        heads = word;
-      if (byte == 12)
-        sectors = word;
-
-      if (byte >= 54 && byte < (54 + 40))
-      {
-        *p = word >> 8;
-        p++;
-        *p = word;
-        p++;
-      }
-
-      if (byte == (47 * 2))
-        max_multiple_sectors = word & 0xff;
-
-      if (byte == (49 * 2))
-        capabilities = word;
-
-      if (byte == (59 * 2))
-      {
-        if (word & (1 << 8))
-          cur_multiple_sectors = word & 0xff;
-      }
-
-      if (byte == (60 * 2))
-        lba_sectors = word;
-      if (byte == (61 * 2))
-        lba_sectors |= word << 16;
-
-      byte += 2;
-    }
-
-    if (pc386_ide_show)
-      printk("\nbytes read = %" PRIu32 "\n", byte);
-
-    if (p != &model_number[0])
-    {
-      uint32_t size;
-      uint32_t left;
-      uint32_t right;
-      char     units;
-
-      if (capabilities & (1 << 9))
-        size = lba_sectors;
-      else
-        size = cylinders * heads * sectors;
-
-      size /= 2;
-
-      if (size > (1024 * 1024))
-      {
-        size = (size * 10) / (1000 * 1000);
-        units = 'G';
-      }
-      else if (size > 1024)
-      {
-        size = (size * 10) / 1000;
-        units = 'M';
-      }
-      else
-      {
-        size = size * 10;
-        units = 'K';
-      }
-
-      left = size / 10;
-      right = size % 10;
-
-      p--;
-      while (*p == ' ')
-      {
-        *p = '\0';
-        p--;
-      }
-
-      printk("IDE%d:%s:%s, %" PRIu32 ".%" PRIu32 "%c (%" PRIu32 "/%" PRIu32 "/%" PRIu32 "), max blk size:%d\n",
-             minor, label, model_number, left, right, units,
-             heads, cylinders, sectors, max_multiple_sectors * 512);
-    }
-
-#if IDE_CLEAR_MULTI_SECTOR_COUNT
-    if (max_multiple_sectors)
-    {
-      outport_byte(port+IDE_REGISTER_SECTOR_COUNT, 0);
-      outport_byte(port+IDE_REGISTER_COMMAND, 0xc6);
-
-      if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT,
-                                  &status, pc386_ide_prestart_sleep))
-      {
-        if (pc386_ide_show)
-          printk("IDE%d:%s: device busy: %02x\n", minor, label, status);
-        continue;
-      }
-
-      inport_byte(port+IDE_REGISTER_STATUS, status);
-      if (status & IDE_REGISTER_STATUS_ERR)
-      {
-        inport_byte(port+IDE_REGISTER_ERROR, error);
-        if (error & IDE_REGISTER_ERROR_ABRT)
-          printk("IDE%d:%s: disable multiple failed\n", minor, label);
-        else
-          printk("IDE%d:%s: unknown error on disable multiple: %02x\n",
-                 minor, label, error);
-      }
-    }
-#endif
-
-    outport_byte(port+IDE_REGISTER_DEVICE_CONTROL,
-                 IDE_REGISTER_DEVICE_CONTROL_nIEN);
-    wait(10000);
-  }
-
-  pc386_ide_timeout = PC386_IDE_TASKING_TIMEOUT;
-
-  /*
-   * FIXME: enable interrupts, if needed
-   */
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static void pc386_ide_read_reg
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  read a IDE controller register                                           |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int                        minor,  /* controller minor number       */
- int                        reg,    /* register index to access      */
- uint16_t                  *value   /* ptr to return value location  */
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    <none>                                                                 |
-\*=========================================================================*/
-{
-  uint32_t    port = IDE_Controller_Table[minor].port1;
-  uint8_t   bval1,bval2;
-
-  if (reg == IDE_REGISTER_DATA_WORD) {
-    inport_byte(port+reg, bval1);
-    inport_byte(port+reg+1, bval2);
-    *value = bval1 + (bval2 << 8);
-  }
-  else {
-    inport_byte(port+reg, bval1);
-    *value = bval1;
-  }
-#if PC386_IDE_DEBUG_OUT
-  pc386_ide_printk("pc386_ide_read_reg (0x%x)=0x%x\r\n",reg,*value & 0xff);
-#endif
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static void pc386_ide_write_reg
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  write a IDE controller register                                          |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int                        minor,  /* controller minor number       */
- int                        reg,    /* register index to access      */
- uint16_t                   value   /* value to write                */
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    <none>                                                                 |
-\*=========================================================================*/
-{
-  uint32_t    port = IDE_Controller_Table[minor].port1;
-
-#if PC386_IDE_DEBUG_OUT
-  pc386_ide_printk("pc386_ide_write_reg(0x%x,0x%x)\r\n",reg,value & 0xff);
-#endif
-  if (reg == IDE_REGISTER_DATA_WORD) {
-    outport_word(port+reg,value);
-  }
-  else {
-    outport_byte(port+reg,value);
-  }
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static void pc386_ide_read_block
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  read a IDE controller data block                                         |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int                     minor,
- uint32_t                block_size,
- rtems_blkdev_sg_buffer *bufs,
- uint32_t               *cbuf,
- uint32_t               *pos
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    <none>                                                                 |
-\*=========================================================================*/
-{
-  uint32_t port = IDE_Controller_Table[minor].port1;
-  uint32_t cnt = 0;
-#if PC386_IDE_DEBUG_OUT
-  int i32 = 0;
-  pc386_ide_printk("pc386_ide_read_block(bs=%u,bn=%u,bl=%u,cb=%d,p=%d)\n",
-                   block_size, bufs[(*cbuf)].block, llength, *cbuf, *pos);
-#endif
-
-  while (cnt < block_size)
-  {
-    uint16_t *lbuf;
-    uint8_t  status_val;
-    int      b;
-
-    if (!pc386_ide_status_data_ready (port, pc386_ide_timeout,
-                                      &status_val, pc386_ide_tasking_sleep))
-    {
-      printk ("pc386_ide_read_block: block=%" PRIu32 \
-              " cbuf=%" PRIu32 " status=%02x, cnt=%" PRIu32 " bs=%" PRIu32 "\n",
-              bufs[*cbuf].block, *cbuf, status_val, cnt, block_size);
-      /* FIXME: add an error here. */
-      return;
-    }
-
-    if (status_val & IDE_REGISTER_STATUS_ERR)
-    {
-      inport_byte(port+IDE_REGISTER_ERROR, status_val);
-      printk("pc386_ide_read_block: error: %02x\n", status_val);
-      return;
-    }
-
-    lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer) + (*pos));
-
-    for (b = 0; b < (ATA_SECTOR_SIZE / 2); b++)
-    {
-      inport_word(port+IDE_REGISTER_DATA,*lbuf);
-
-#if PC386_IDE_DEBUG_OUT
-      pc386_ide_printk("%04x ",*lbuf);
-      i32++;
-      if (i32 >= 16)
-      {
-        pc386_ide_printk("\n");
-        i32 = 0;
-      }
-#endif
-      lbuf++;
-    }
-    cnt    += ATA_SECTOR_SIZE;
-    (*pos) += ATA_SECTOR_SIZE;
-    if ((*pos) == bufs[(*cbuf)].length) {
-      (*pos) = 0;
-      (*cbuf)++;
-      lbuf = bufs[(*cbuf)].buffer;
-    }
-  }
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static void pc386_ide_write_block
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  write a IDE controller data block                                        |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int minor,
- uint32_t                block_size,
- rtems_blkdev_sg_buffer *bufs,
- uint32_t               *cbuf,
- uint32_t               *pos
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    <none>                                                                 |
-\*=========================================================================*/
-{
-  uint32_t port = IDE_Controller_Table[minor].port1;
-  uint32_t cnt = 0;
-#if PC386_IDE_DEBUG_OUT
-  int i32 = 0;
-  pc386_ide_printk("pc386_ide_write_block(bs=%u,bn=%u,bl=%u,cb=%d,p=%d)\n",
-                   block_size, bufs[(*cbuf)].block, llength, *cbuf, *pos);
-#endif
-
-  while (cnt < block_size)
-  {
-    uint16_t *lbuf;
-    uint8_t  status_val;
-    int      b;
-
-    if (!pc386_ide_status_data_ready (port, pc386_ide_timeout,
-                                      &status_val, pc386_ide_tasking_sleep))
-    {
-      printk ("pc386_ide_write_block: block=%" PRIu32 " status=%02x, cnt=%" PRIu32 " bs=%" PRIu32 "\n",
-              bufs[*cbuf].block, status_val, cnt, block_size);
-      /* FIXME: add an error here. */
-      return;
-    }
-
-    if (status_val & IDE_REGISTER_STATUS_ERR)
-    {
-      inport_byte(port+IDE_REGISTER_ERROR, status_val);
-      printk ("pc386_ide_write_block: error: %02x\n", status_val);
-      return;
-    }
-
-    lbuf = (uint16_t*)(((uint8_t*)bufs[*cbuf].buffer) + (*pos));
-
-    for (b = 0; b < (ATA_SECTOR_SIZE / 2); b++)
-    {
-#if PC386_IDE_DEBUG_OUT
-      pc386_ide_printk("%04x ",*lbuf);
-      i32++;
-      if (i32 >= 16)
-      {
-        pc386_ide_printk("\n");
-        i32 = 0;
-      }
-#endif
-      outport_word(port+IDE_REGISTER_DATA,*lbuf);
-      lbuf++;
-    }
-    cnt    += ATA_SECTOR_SIZE;
-    (*pos) += ATA_SECTOR_SIZE;
-    if ((*pos) == bufs[(*cbuf)].length) {
-      (*pos) = 0;
-      (*cbuf)++;
-      lbuf = bufs[(*cbuf)].buffer;
-    }
-  }
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static int pc386_ide_control
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  control interface for controller                                         |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int  minor,                        /* controller minor number       */
- uint32_t   cmd,                    /* command to send               */
- void * arg                         /* optional argument             */
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    <none>                                                                 |
-\*=========================================================================*/
-{
-  return 0;
-}
-
-/*=========================================================================*\
-| Function:                                                                 |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code pc386_ide_config_io_speed
-(
-/*-------------------------------------------------------------------------*\
-| Purpose:                                                                  |
-|  set up transfer speed, if possible                                       |
-+---------------------------------------------------------------------------+
-| Input Parameters:                                                         |
-\*-------------------------------------------------------------------------*/
- int        minor,                   /* controller minor number       */
- uint16_t   modes_avail              /* optional argument             */
- )
-/*-------------------------------------------------------------------------*\
-| Return Value:                                                             |
-|    rtems_status_code                                                      |
-\*=========================================================================*/
-{
-  return RTEMS_SUCCESSFUL;
-}
-
-/*
- * The following table configures the functions used for IDE drivers
- * in this BSP.
- */
-
-ide_ctrl_fns_t pc386_ide_ctrl_fns = {
-  pc386_ide_probe,
-  pc386_ide_initialize,
-  pc386_ide_control,
-  pc386_ide_read_reg,
-  pc386_ide_write_reg,
-  pc386_ide_read_block,
-  pc386_ide_write_block,
-  pc386_ide_config_io_speed
-};
Index: src/lib/libbsp/i386/pc386/ide/idecfg.c
===================================================================
--- c/src/lib/libbsp/i386/pc386/ide/idecfg.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,145 +1,0 @@
-/*===============================================================*\
-| Project: RTEMS PC386 IDE harddisc driver tables                 |
-+-----------------------------------------------------------------+
-| File: idecfg.c                                                  |
-+-----------------------------------------------------------------+
-|                    Copyright (c) 2003 IMD                       |
-|      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler      |
-|               <Thomas.Doerfler@imd-systems.de>                  |
-|                       all rights reserved                       |
-+-----------------------------------------------------------------+
-| this file contains the table of functions for the BSP layer     |
-| for IDE access below the libchip IDE harddisc driver            |
-|                                                                 |
-+-----------------------------------------------------------------+
-|   date                      history                        ID   |
-| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
-| 01.14.03  creation                                         doe  |
-\*===============================================================*/
-
-#include <rtems.h>
-#include <bsp.h>
-#include <libchip/ide_ctrl.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ide_ctrl_io.h>
-
-extern bool pc386_ide_show;
-
-/*
- * The following table configures the functions used for IDE drivers
- * in this BSP.
- */
-
-/*
- * The following table configures the IDE drivers used in this BSP.
- */
-extern ide_ctrl_fns_t pc386_ide_ctrl_fns;
-
-/* IDE controllers Table */
-ide_controller_bsp_table_t IDE_Controller_Table[] = {
-  {"/dev/ide0",
-   IDE_STD, /* standard IDE controller */
-   &pc386_ide_ctrl_fns,
-   NULL, /* probe for IDE standard registers */
-   FALSE, /* not (yet) initialized */
-   0x1f0,  /* base I/O address for first IDE controller */
-   FALSE,0, /* not (yet) interrupt driven */
-   NULL
-  }
-  , /* colon only needed when both interfaces present */
-  {"/dev/ide1",
-   IDE_STD, /* standard IDE controller */
-   &pc386_ide_ctrl_fns,
-   NULL, /* probe for IDE standard registers */
-   FALSE, /* not (yet) initialized */
-   0x170,  /* base I/O address for second IDE controller */
-   FALSE,0, /* not (yet) interrupt driven */
-   NULL
-  }
-};
-
-/* Number of rows in IDE_Controller_Table. Default is 0. */
-unsigned long IDE_Controller_Count;
-
-#if IDE_USE_PRIMARY_INTERFACE
-#define IDE1_DEFAULT true
-#else
-#define IDE1_DEFAULT false
-#endif
-#if IDE_USE_SECONDARY_INTERFACE
-#define IDE2_DEFAULT true
-#else
-#define IDE2_DEFAULT false
-#endif
-
-void bsp_ide_cmdline_init(void)
-{
-  const char* ide_disable;
-
-  ide_disable = bsp_cmdline_arg ("--ide-disable");
-
-  if (ide_disable == NULL) {
-    bool ide1 = IDE1_DEFAULT;
-    bool ide2 = IDE2_DEFAULT;
-    const char* ide;
-
-    /*
-     * Can have:
-     *  --ide=0,1
-     */
-    ide = bsp_cmdline_arg ("--ide=");
-
-    if (ide)
-    {
-      int i;
-      /*
-       * If a command line option exists remove the defaults.
-       */
-      ide1 = ide2 = false;
-
-      ide += sizeof ("--ide=") - 1;
-
-      for (i = 0; i < 3; i++)
-      {
-        switch (ide[i])
-        {
-          case '0':
-            ide1 = true;
-            break;
-          case '1':
-            ide2 = true;
-            break;
-          case '2':
-          case '3':
-          case '4':
-          case '5':
-          case '6':
-          case '7':
-          case '8':
-          case '9':
-          case ',':
-            break;
-          default:
-            break;
-        }
-      }
-    }
-
-    if (ide2 && !ide1)
-      IDE_Controller_Table[0] = IDE_Controller_Table[1];
-
-    if (ide1)
-      IDE_Controller_Count++;
-    if (ide2)
-      IDE_Controller_Count++;
-
-    /*
-     * Allow the user to get the initialise to print probing
-     * type information.
-     */
-    ide = bsp_cmdline_arg ("--ide-show");
-
-    if (ide)
-      pc386_ide_show = true;
-  }
-}
Index: c/src/lib/libbsp/powerpc/gen5200/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/Makefile.am	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ c/src/lib/libbsp/powerpc/gen5200/Makefile.am	(revision fc79b268eb1d0588588c529888ce585f5cacf7c0)
@@ -63,9 +63,9 @@
 librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/i2c/mpc5200mbus.c
 # ide
-librtemsbsp_a_SOURCES += ide/idecfg.c
-librtemsbsp_a_SOURCES += ide/pcmcia_ide.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/ata/idecfg.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/ata/pcmcia_ide.c
 librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/dev/mpc5200-ata.c
-librtemsbsp_a_SOURCES += ide/ata-instance.c
-librtemsbsp_a_SOURCES += ide/ata-dma-pio-single.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/ata/ata-instance.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/ata/ata-dma-pio-single.c
 
 # irq
Index: src/lib/libbsp/powerpc/gen5200/ide/ata-dma-pio-single.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/ide/ata-dma-pio-single.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,189 +1,0 @@
-/*
- * Copyright (c) 2011-2013 embedded brains GmbH.  All rights reserved.
- *
- *  embedded brains GmbH
- *  Dornierstr. 4
- *  82178 Puchheim
- *  Germany
- *  <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#define NDEBUG
-
-#include <bsp/ata.h>
-
-#include <libcpu/powerpc-utility.h>
-
-#include <bsp.h>
-#include <bsp/fatal.h>
-#include <bsp/irq.h>
-
-typedef enum {
-  DATA_CURRENT = 0,
-  DATA_END,
-  DATA_REG
-} variables;
-
-typedef enum {
-  INC_0_NE = 0,
-  INC_2_NE
-} increments;
-
-/*
- * for
- *   idx0 = DATA_CURRENT, idx1 = DATA_REG
- *   idx0 != DATA_END
- *   idx0 += 2, idx1 += 0
- * do
- *   *idx0 = *idx1 [INT, 16 bit] OR *idx1 = *idx0 [INT, 16 bit]
- */
-static const uint32_t ops[] = {
-  LCD(0, VAR(DATA_CURRENT), 0, VAR(DATA_REG), TERM_FIRST, VAR(DATA_END), INC_2_NE, INC_0_NE),
-    0, /* Transfer opcode, see transfer() */
-};
-
-static bool is_last_transfer(const ata_driver_dma_pio_single *self)
-{
-  return self->transfer_current + 1 == self->transfer_end;
-}
-
-static void start_sector_transfer(ata_driver_dma_pio_single *self)
-{
-  uint16_t *current = ata_sg_get_sector_data_begin(&self->sg_context, self->transfer_current);
-  bestcomm_task_set_variable(&self->task, DATA_CURRENT, (uint32_t) current);
-  bestcomm_task_set_variable(&self->task, DATA_END, (uint32_t) ata_sg_get_sector_data_end(&self->sg_context, current));
-  bestcomm_task_start(&self->task);
-
-  bool last = is_last_transfer(self);
-  ++self->transfer_current;
-
-  if (!last) {
-    ata_flush_sector(ata_sg_get_sector_data_begin(&self->sg_context, self->transfer_current));
-  }
-}
-
-static void dma_pio_single_interrupt_handler(void *arg)
-{
-  ata_driver_dma_pio_single *self = arg;
-  bool ok = ata_check_status();
-  bool send_event = false;
-  if (ok && self->transfer_current != self->transfer_end) {
-    bool enable_dma_interrupt = self->read && is_last_transfer(self);
-    if (enable_dma_interrupt) {
-      bestcomm_task_irq_clear(&self->task);
-      bestcomm_task_irq_enable(&self->task);
-    }
-
-    start_sector_transfer(self);
-  } else {
-    send_event = true;
-  }
-
-  if (send_event) {
-    bestcomm_task_wakeup_event_task(&self->task);
-  }
-}
-
-static bool transfer_dma_pio_single(ata_driver *super, bool read, rtems_blkdev_sg_buffer *sg, size_t sg_count)
-{
-  bool ok = true;
-  ata_driver_dma_pio_single *self = (ata_driver_dma_pio_single *) super;
-
-  self->read = read;
-  ata_sg_reset(&self->sg_context, sg, sg_count);
-  rtems_blkdev_bnum start_sector = ata_sg_get_start_sector(&self->sg_context);
-  rtems_blkdev_bnum sector_count = ata_sg_get_sector_count(&self->sg_context);
-  rtems_blkdev_bnum relative_sector = 0;
-
-  ata_flush_sector(ata_sg_get_sector_data_begin(&self->sg_context, relative_sector));
-
-  uint8_t command = ata_read_or_write_sectors_command(read);
-
-  uint32_t opcode;
-  if (read) {
-    opcode = DRD1A(INT, INIT_ALWAYS, DEST_DEREF_IDX(0), SZ_16, SRC_DEREF_IDX(1), SZ_16);
-  } else {
-    opcode = DRD1A(INT, INIT_ALWAYS, DEST_DEREF_IDX(1), SZ_16, SRC_DEREF_IDX(0), SZ_16);
-  }
-
-  bestcomm_task_irq_disable(&self->task);
-  bestcomm_task_associate_with_current_task(&self->task);
-
-  size_t transfer_opcode_index = 1; /* See ops */
-  bestcomm_task_set_opcode(&self->task, transfer_opcode_index, opcode);
-
-  while (ok && relative_sector < sector_count) {
-    rtems_blkdev_bnum remaining_sectors = sector_count - relative_sector;
-    rtems_blkdev_bnum transfer_count = ata_max_transfer_count(remaining_sectors);
-
-    self->transfer_current = relative_sector;
-    self->transfer_end = relative_sector + transfer_count;
-
-    ok = ata_execute_io_command(command, start_sector + relative_sector, transfer_count);
-    if (ok) {
-      if (!read) {
-        ok = ata_wait_for_data_request();
-        assert(ok);
-
-        rtems_interrupt_level level;
-        rtems_interrupt_disable(level);
-        start_sector_transfer(self);
-        rtems_interrupt_enable(level);
-      }
-
-      bestcomm_task_wait(&self->task);
-
-      ok = ata_check_status();
-
-      relative_sector += ATA_PER_TRANSFER_SECTOR_COUNT_MAX;
-    }
-  }
-
-  return ok;
-}
-
-static int io_control_dma_pio_single(
-  rtems_disk_device *dd,
-  uint32_t cmd,
-  void *arg
-)
-{
-  return ata_driver_io_control(dd, cmd, arg, transfer_dma_pio_single);
-}
-
-void ata_driver_dma_pio_single_create(ata_driver_dma_pio_single *self, const char *device_file_path, TaskId task_index)
-{
-  ata_driver_create(&self->super, device_file_path, io_control_dma_pio_single);
-
-  self->read = false;
-
-  if (ata_driver_is_card_present(&self->super)) {
-    bestcomm_task_create_and_load(&self->task, task_index, ops, sizeof(ops));
-
-    bestcomm_task_set_variable(&self->task, DATA_REG, (uint32_t) &ATA->write.data);
-
-    bestcomm_task_set_increment_and_condition(&self->task, INC_0_NE, 0, COND_NE);
-    bestcomm_task_set_increment_and_condition(&self->task, INC_2_NE, 2, COND_NE);
-
-    bestcomm_task_enable_combined_write(&self->task, true);
-    bestcomm_task_enable_read_buffer(&self->task, true);
-    bestcomm_task_enable_speculative_read(&self->task, true);
-
-    ata_clear_interrupts();
-
-    rtems_status_code sc = rtems_interrupt_handler_install(
-      BSP_SIU_IRQ_ATA,
-      "ATA",
-      RTEMS_INTERRUPT_UNIQUE,
-      dma_pio_single_interrupt_handler,
-      self
-    );
-    if (sc != RTEMS_SUCCESSFUL) {
-      bsp_fatal(MPC5200_FATAL_ATA_DMA_SINGLE_IRQ_INSTALL);
-    }
-  }
-}
Index: src/lib/libbsp/powerpc/gen5200/ide/ata-instance.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/ide/ata-instance.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2011-2013 embedded brains GmbH.  All rights reserved.
- *
- *  embedded brains GmbH
- *  Dornierstr. 4
- *  82178 Puchheim
- *  Germany
- *  <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp/ata.h>
-#include <bsp/fatal.h>
-
-#include <libchip/ata.h>
-
-#include <bsp.h>
-
-static ata_driver_dma_pio_single ata_driver_instance;
-
-rtems_status_code rtems_ata_initialize(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor_arg,
-  void *arg
-)
-{
-  rtems_status_code sc = rtems_disk_io_initialize();
-
-  if (sc == RTEMS_SUCCESSFUL) {
-    bestcomm_glue_init();
-
-    ata_driver_dma_pio_single_create(&ata_driver_instance, "/dev/hda", TASK_PCI_TX);
-  } else {
-    bsp_fatal(MPC5200_FATAL_ATA_DISK_IO_INIT);
-  }
-
-  return sc;
-}
Index: src/lib/libbsp/powerpc/gen5200/ide/idecfg.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/ide/idecfg.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/*===============================================================*\
-| Project: RTEMS generic MPC5200 BSP                              |
-+-----------------------------------------------------------------+
-|                    Copyright (c) 2005                           |
-|                    Embedded Brains GmbH                         |
-|                    Obere Lagerstr. 30                           |
-|                    D-82178 Puchheim                             |
-|                    Germany                                      |
-|                    rtems@embedded-brains.de                     |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be         |
-| found in the file LICENSE in this distribution or at            |
-|                                                                 |
-| http://www.rtems.org/license/LICENSE.                           |
-|                                                                 |
-+-----------------------------------------------------------------+
-| this file contains the IDE configuration                        |
-\*===============================================================*/
-#include <rtems.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/mpc5200.h>
-#include "./pcmcia_ide.h"
-
-#include <libchip/ide_ctrl.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ide_ctrl_io.h>
-
-/*
- * The following table configures the IDE driver used in this BSP.
- */
-extern ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns;
-
-volatile uint32_t * mpc5200_ata_drive_regs[] =
-  {
-  (uint32_t *)&(mpc5200.ata_ddr),       /* data (offset 0x00)                */
-  (uint32_t *)&(mpc5200.ata_dfr_der),   /* features / error (offset 0x01)    */
-  (uint32_t *)&(mpc5200.ata_dscr),      /* sector count (offset 0x02)        */
-  (uint32_t *)&(mpc5200.ata_dsnr),      /* sector no.   / lba0 (offset 0x03) */
-  (uint32_t *)&(mpc5200.ata_dclr),      /* cylinder low / lba1 (offset 0x04) */
-  (uint32_t *)&(mpc5200.ata_dchr),      /* cylinder high/ lba2 (offset 0x05) */
-  (uint32_t *)&(mpc5200.ata_ddhr),      /* device head  / lba3 (offset 0x06) */
-  (uint32_t *)&(mpc5200.ata_dcr_dsr),   /* command /status (offset 0x07)     */
-
-  (uint32_t *)&(mpc5200.ata_dctr_dasr), /* device control / alternate status (offset 0x08) */
-  (uint32_t *)&(mpc5200.ata_ddr),       /* (offset 0x09) */
-  (uint32_t *)&(mpc5200.ata_ddr),       /* (offset 0x0A) */
-  NULL,                                 /* (offset 0x0B) */
-  NULL,                                 /* (offset 0x0C) */
-  NULL,                                 /* (offset 0x0D) */
-  NULL,                                 /* (offset 0x0E) */
-  NULL                                  /* (offset 0x0F) */
-  };
-
-/* IDE controllers Table */
-ide_controller_bsp_table_t IDE_Controller_Table[] =
-  {
-    {
-	"/dev/idepcmcia",
-    IDE_CUSTOM,                                        /* PCMCIA Flash cards emulate custom IDE controller */
-    &mpc5200_pcmciaide_ctrl_fns,                       /* pointer to function set used for IDE drivers in this BSP */
-    NULL,                                              /* no BSP dependent probe needed */
-    FALSE,                                             /* not (yet) initialized */
-    (uint32_t)0,                                     /* no port address but custom reg.set in params is used */
-#ifdef ATA_USE_INT
-    TRUE,                                              /* interrupt driven */
-#else
-    FALSE,                                             /* non interrupt driven     */
-#endif
-    BSP_SIU_IRQ_ATA,                                   /* interrupt vector         */
-    NULL                                               /* no additional parameters */
-    }
-};
-
-/* Number of rows in IDE_Controller_Table */
-unsigned long IDE_Controller_Count = sizeof(IDE_Controller_Table)/sizeof(IDE_Controller_Table[0]);
-
-uint32_t ata_pio_timings[2][6] =
- {
-   /* PIO3 timings in nanosconds */
-   {
-   180, /* t0 cycle time */
-   80,  /* t2 DIOR-/DIOW pulse width 8 bit */
-   80,  /* t1 DIOR-/DIOW pulse width 16 bit */
-   10,  /* t4 DIOW- data hold */
-   30,  /* t1 Addr.valid to DIOR-/DIOW setup */
-   35,  /* ta IORDY setup time */
-   },
-   /* PIO4 timings in nanosconds */
-   {
-   120, /* t0 cycle time */
-   70,  /* t1 DIOR-/DIOW pulse width 8 bit */
-   70,  /* t1 DIOR-/DIOW pulse width 16 bit */
-   10,  /* t4 DIOW- data hold */
-   25,  /* t1 Addr.valid to DIOR-/DIOW setup */
-   35,  /* ta IORDY setup time */
-   }
- };
-
-
Index: src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,682 +1,0 @@
-/*===============================================================*\
-| Project: RTEMS generic MPC5200 BSP                              |
-+-----------------------------------------------------------------+
-| Partially based on the code references which are named below.   |
-| Adaptions, modifications, enhancements and any recent parts of  |
-| the code are:                                                   |
-|                    Copyright (c) 2005                           |
-|                    Embedded Brains GmbH                         |
-|                    Obere Lagerstr. 30                           |
-|                    D-82178 Puchheim                             |
-|                    Germany                                      |
-|                    rtems@embedded-brains.de                     |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be         |
-| found in the file LICENSE in this distribution or at            |
-|                                                                 |
-| http://www.rtems.org/license/LICENSE.                           |
-|                                                                 |
-+-----------------------------------------------------------------+
-| this file contains the PCMCIA IDE access functions              |
-\*===============================================================*/
-/***********************************************************************/
-/*                                                                     */
-/*   Module:       pcmcia_ide.c                                        */
-/*   Date:         07/17/2003                                          */
-/*   Purpose:      RTEMS MPC5x00 PCMCIA IDE harddisk driver            */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Description:                                                      */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Code                                                              */
-/*   References:   RTEMS MBX8xx PCMCIA IDE harddisc driver             */
-/*   Module:       pcmcia_ide.c                                        */
-/*   Project:      RTEMS 4.6.0pre1 / Mbx8xx BSP                        */
-/*   Version                                                           */
-/*   Date:         01/14/2003                                          */
-/*                                                                     */
-/*   Author(s) / Copyright(s):                                         */
-/*                                                                     */
-/*                    Copyright (c) 2003 IMD                           */
-/*      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler          */
-/*               <Thomas.Doerfler@imd-systems.de>                      */
-/*                       all rights reserved                           */
-/*                                                                     */
-/*  this file contains the BSP layer for PCMCIA IDE access below the   */
-/*  libchip IDE harddisc driver based on a board specific driver from  */
-/*  Eugeny S. Mints, Oktet                                             */
-/*                                                                     */
-/*  The license and distribution terms for this file may be            */
-/*  found in the file LICENSE in this distribution or at               */
-/*  http://www.rtems.org/license/LICENSE.                         */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Partially based on the code references which are named above.     */
-/*   Adaptions, modifications, enhancements and any recent parts of    */
-/*   the code are under the right of                                   */
-/*                                                                     */
-/*         IPR Engineering, Dachauer StraÃe 38, D-80335 MÃŒnchen        */
-/*                        Copyright(C) 2003                            */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   IPR Engineering makes no representation or warranties with        */
-/*   respect to the performance of this computer program, and          */
-/*   specifically disclaims any responsibility for any damages,        */
-/*   special or consequential, connected with the use of this program. */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Version history:  1.0                                             */
-/*                                                                     */
-/***********************************************************************/
-
-#include <sys/param.h>
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/score/sysstate.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/mpc5200.h>
-#include "./pcmcia_ide.h"
-
-#include <libchip/ide_ctrl.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ide_ctrl_io.h>
-#include <string.h>
-
-#define IDE_DMA_TEST            FALSE
-
-/* DMA supported PIO mode is broken */
-#define IDE_USE_INT             TRUE
-#define IDE_READ_USE_DMA        FALSE
-#define IDE_USE_READ_PIO_OPT    FALSE
-#define IDE_WRITE_USE_DMA       FALSE
-#define IDE_USE_WRITE_PIO_OPT   FALSE
-#define IDE_USE_DMA (IDE_READ_USE_DMA || IDE_WRITE_USE_DMA)
-
-#define IDE_USE_STATISTICS      TRUE
-
-#if IDE_USE_DMA
-#define PCMCIA_IDE_DMA_WR_BD_CNT 2
-#define PCMCIA_IDE_DMA_RD_BD_CNT 2
-#define PCMCIA_IDE_INTERRUPT_EVENT RTEMS_EVENT_2
-/* Task number assignment */
-#include "../bestcomm/bestcomm_glue.h"
-#include "../bestcomm/bestcomm_api.h"
-#include "../bestcomm/task_api/bestcomm_cntrl.h"
-#include "../bestcomm/task_api/tasksetup_bdtable.h"
-
-#define IDE_RX_TASK_NO TASK_GEN_DP_BD_0
-#define IDE_TX_TASK_NO TASK_GEN_DP_BD_1
-static TaskId pcmcia_ide_rxTaskId;	/* SDMA RX task ID */
-static TaskId pcmcia_ide_txTaskId;	/* SDMA TX task ID */
-#define PCMCIA_IDE_RD_SECTOR_SIZE 512   /* FIXME: make this better... */
-#define PCMCIA_IDE_WR_SECTOR_SIZE 512   /* FIXME: make this better... */
-
-bool mpc5200_dma_task_started[2] = {false,false};
-#endif /* IDE_USE_DMA */
-
-#if IDE_USE_STATISTICS
-uint32_t mpc5200_pcmciaide_write_block_call_cnt  = 0;
-uint32_t mpc5200_pcmciaide_write_block_block_cnt = 0;
-uint32_t mpc5200_pcmciaide_read_block_call_cnt   = 0;
-uint32_t mpc5200_pcmciaide_read_block_block_cnt  = 0;
-#endif
-
-extern volatile uint32_t * mpc5200_ata_drive_regs[];
-extern uint32_t ata_pio_timings[2][6];
-
-void mpc5200_pcmciaide_dma_blockop(
-  bool, int, uint16_t, rtems_blkdev_sg_buffer *, uint32_t *, uint32_t *);
-/*
- * support functions for PCMCIA IDE IF
- */
-static bool mpc5200_pcmciaide_probe(int minor)
-  {
-  bool ide_card_plugged = false; /* assume: we don't have a card plugged in */
-  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT2]);
-
-  #ifdef MPC5200_BOARD_DP2
-    /* Deactivate RESET signal */
-    rtems_interrupt_level level;
-    rtems_interrupt_disable(level);
-    mpc5200.gpiowe |= GPIO_W_PIN_PSC1_4;
-    mpc5200.gpiowod &= ~GPIO_W_PIN_PSC1_4;
-    mpc5200.gpiowdd |= GPIO_W_PIN_PSC1_4;
-    mpc5200.gpiowdo |= GPIO_W_PIN_PSC1_4;
-    rtems_interrupt_enable(level);
-    /* FIXME */
-    volatile int i = 0;
-    while (++i < 20000000);
-  #endif
-
-  /* enable card detection on GPT2 */
-  gpt->emsel = (GPT_EMSEL_GPIO_IN | GPT_EMSEL_TIMER_MS_GPIO);
-
-#if defined (MPC5200_BOARD_BRS5L)
-  /* Check for card detection (-CD0) */
-  if((gpt->status) & GPT_STATUS_PIN)
-    ide_card_plugged = false;
-  else
-#endif
-    ide_card_plugged = true;
-
-  return ide_card_plugged;
-
-  }
-
-#define DMA1_T0(val) BSP_BFLD32(COUNT_VAL(val), 0, 7)
-#define DMA1_TD(val) BSP_BFLD32(COUNT_VAL(val), 8, 15)
-#define DMA1_TK(val) BSP_BFLD32(COUNT_VAL(val), 16, 23)
-#define DMA1_TM(val) BSP_BFLD32(COUNT_VAL(val), 24, 31)
-
-#define DMA2_TH(val) BSP_BFLD32(COUNT_VAL(val), 0, 7)
-#define DMA2_TJ(val) BSP_BFLD32(COUNT_VAL(val), 8, 15)
-#define DMA2_TN(val) BSP_BFLD32(COUNT_VAL(val), 16, 23)
-
-static rtems_status_code mpc5200_pcmciaide_config_io_speed(int minor, uint16_t modes_avail)
-  {
-  uint8_t pio_t0, pio_t2_8, pio_t2_16, pio_t4, pio_t1, pio_ta;
-
-  if((modes_avail & ATA_MODES_PIO4) != 0)
-    {
-
-    pio_t0    = ata_pio_timings[PIO_4][T0];
-    pio_t2_8  = ata_pio_timings[PIO_4][T2_8];
-    pio_t2_16 = ata_pio_timings[PIO_4][T2_16];
-    pio_t4    = ata_pio_timings[PIO_4][T4];
-    pio_t1    = ata_pio_timings[PIO_4][T1];
-    pio_ta    = ata_pio_timings[PIO_4][TA];
-
-    }
-  else
-    {
-
-    pio_t0    = ata_pio_timings[PIO_3][T0];
-    pio_t2_8  = ata_pio_timings[PIO_3][T2_8];
-    pio_t2_16 = ata_pio_timings[PIO_3][T2_16];
-    pio_t4    = ata_pio_timings[PIO_3][T4];
-    pio_t1    = ata_pio_timings[PIO_3][T1];
-    pio_ta    = ata_pio_timings[PIO_3][TA];
-
-    }
-
-  /* set timings according according to selected ATA mode */
-  mpc5200.ata_pio1 = ATA_PIO_TIMING_1(pio_t0, pio_t2_8, pio_t2_16);
-  mpc5200.ata_pio2 = ATA_PIO_TIMING_2(pio_t4, pio_t1, pio_ta);
-
-  mpc5200.ata_dma1 = DMA1_T0(120) | DMA1_TD(70) | DMA1_TK(25) | DMA1_TM(25);
-  mpc5200.ata_dma2 = DMA2_TH(10) | DMA2_TJ(5) | DMA2_TN(10);
-
-  return RTEMS_SUCCESSFUL;
-
-  }
-
-
-
-static void mpc5200_pcmciaide_read_reg(int minor, int reg, uint16_t *value)
-  {
-  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
-
-  if(reg == IDE_REGISTER_DATA_WORD)
-    *value = *(volatile uint16_t *)(ata_reg);
-  else
-    *value = *(volatile uint8_t  *)(ata_reg);
-  }
-
-
-static void mpc5200_pcmciaide_write_reg(int minor, int reg, uint16_t value)
-  {
-  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
-
-  if(reg == IDE_REGISTER_DATA_WORD)
-    *(volatile uint16_t *)(ata_reg) = value;
-  else
-    *(volatile uint8_t  *)(ata_reg) = value;
-  }
-
-#if IDE_USE_DMA
-
-
-uint32_t pcmcia_ide_rxInterrupts;
-uint32_t pcmcia_ide_txInterrupts;
-volatile rtems_id pcmcia_ide_hdl_task = 0;
-/*
- * MPC5200 BestComm interrupt handlers
- */
-static void pcmcia_ide_recv_dmairq_hdl(rtems_irq_hdl_param unused)
-{
-  SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,IDE_RX_TASK_NO);
-
-/*Disable receive ints*/
-  bestcomm_glue_irq_disable(IDE_RX_TASK_NO);
-
-  pcmcia_ide_rxInterrupts++; 		/* Rx int has occurred */
-
-  if (pcmcia_ide_hdl_task != 0) {
-    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
-  }
-}
-
-static void pcmcia_ide_xmit_dmairq_hdl(rtems_irq_hdl_param unused)
-{
-
-  SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,IDE_TX_TASK_NO);
-
-  /*Disable transmit ints*/
-  bestcomm_glue_irq_disable(IDE_TX_TASK_NO);
-
-  pcmcia_ide_txInterrupts++; 		/* Tx int has occurred */
-
-  if (pcmcia_ide_hdl_task != 0) {
-    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
-  }
-}
-
-
-void mpc5200_pcmciaide_dma_init(int minor)
-{
-  TaskSetupParamSet_t	rxParam;	/* RX task setup parameters	*/
-  TaskSetupParamSet_t	txParam;	/* TX task setup parameters	*/
-  /*
-   * Init Bestcomm system
-   */
-  bestcomm_glue_init();
-  /*
-   * Setup the SDMA RX task.
-   */
-  rxParam.NumBD        = PCMCIA_IDE_DMA_RD_BD_CNT;
-  rxParam.Size.MaxBuf  = PCMCIA_IDE_RD_SECTOR_SIZE;
-  rxParam.Initiator    = INITIATOR_ALWAYS;
-  rxParam.StartAddrSrc =
-    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
-  rxParam.IncrSrc      = 0;
-  rxParam.SzSrc	       = sizeof(uint16_t);
-  rxParam.StartAddrDst = (uint32)NULL;
-  rxParam.IncrDst      = sizeof(uint16_t);
-  rxParam.SzDst	       = sizeof(uint16_t);  /* XXX: set this to 32 bit? */
-
-  pcmcia_ide_rxTaskId  = TaskSetup(IDE_RX_TASK_NO,&rxParam );
-
-  /*
-   * Setup the TX task.
-   */
-  txParam.NumBD        = PCMCIA_IDE_DMA_WR_BD_CNT;
-  txParam.Size.MaxBuf  = PCMCIA_IDE_WR_SECTOR_SIZE;
-  txParam.Initiator    = INITIATOR_ALWAYS;
-  txParam.StartAddrSrc = (uint32)NULL;
-  txParam.IncrSrc      = sizeof(uint16_t);
-  txParam.SzSrc        = sizeof(uint16_t); /* do not set this to 32 bit! */
-  txParam.StartAddrDst =
-    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
-  txParam.IncrDst      = 0;
-  txParam.SzDst        = sizeof(uint16_t);
-
-  pcmcia_ide_txTaskId  = TaskSetup( IDE_TX_TASK_NO, &txParam );
-  /*
-   * FIXME: Init BD rings
-   */
-  /*
-   * Enable the SmartDMA transmit/receive task.
-   * do not enable interrupts to CPU
-   */
-  /*
-   * connect interrupt handlers
-   */
-  bestcomm_glue_irq_install(IDE_TX_TASK_NO,pcmcia_ide_xmit_dmairq_hdl,NULL);
-  bestcomm_glue_irq_install(IDE_RX_TASK_NO,pcmcia_ide_recv_dmairq_hdl,NULL);
-}
-#endif /* IDE_USE_DMA */
-
-void mpc5200_pcmciaide_dma_blockop(bool is_write,
-				   int minor,
-				   uint16_t block_size,
-				   rtems_blkdev_sg_buffer *bufs,
-				   uint32_t *cbuf,
-				   uint32_t *pos)
-
-{
-#if IDE_USE_DMA
-  /*
-   * Nameing:
-   * - a block is one unit of data on disk (multiple sectors)
-   * - a buffer is a contignuous chunk of data in memory
-   * a block on disk may be filled with data from several buffers
-   */
-  uint32_t buf_idx,bufs_from_dma, bufs_to_dma,bufs_total;
-  uint32_t bds_free;
-  uint32_t llength;
-  rtems_status_code rc = RTEMS_SUCCESSFUL;
-  rtems_event_set events;
-  BDIdx nxt_bd_idx;
-  bool use_irq = (_System_state_Current == SYSTEM_STATE_UP);
-  /*
-   * determine number of blocks
-   */
-  llength = 0;
-  buf_idx = 0;
-  bufs += *cbuf; /* *cbuf is the index of the next buffer to send in this transaction */
-  while (llength < block_size) {
-    llength += bufs[buf_idx++].length;
-  }
-  bufs_from_dma = 0;
-  bufs_to_dma   = 0;
-  bufs_total    = buf_idx;
-  /*
-   * here all BDs should be unused
-   */
-  bds_free = is_write ? PCMCIA_IDE_DMA_WR_BD_CNT : PCMCIA_IDE_DMA_RD_BD_CNT;
-  /*
-   * repeat, until all bufs are transferred
-   */
-  while ((rc == RTEMS_SUCCESSFUL) &&
-	 (bufs_from_dma < bufs_total)) {
-
-    while ((rc == RTEMS_SUCCESSFUL) &&
-	   (bufs_to_dma < bufs_total) &&
-	   (bds_free > 0)) {
-      /*
-       * fill in BD, set interrupt if needed
-       */
-    SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,(is_write
-	                                  ? IDE_TX_TASK_NO
-	                                  : IDE_RX_TASK_NO));
-      if (is_write) {
-	TaskBDAssign(pcmcia_ide_txTaskId ,
-		     (void *)bufs[bufs_to_dma].buffer,
-		     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
-		     bufs[bufs_to_dma].length,
-		     0/* flags */);
-#if IDE_USE_STATISTICS
-	mpc5200_pcmciaide_write_block_block_cnt++;
-#endif
-      }
-      else {
-	TaskBDAssign(pcmcia_ide_rxTaskId ,
-		     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
-		     (void *)bufs[bufs_to_dma].buffer,
-		     bufs[bufs_to_dma].length,
-		     0/* flags */);
-#if IDE_USE_STATISTICS
-	mpc5200_pcmciaide_read_block_block_cnt++;
-#endif
-      }
-      bufs_to_dma ++;
-      bds_free    --;
-    }
-    if (is_write) {
-      TaskStart( pcmcia_ide_txTaskId, TASK_AUTOSTART_DISABLE,
-		 pcmcia_ide_txTaskId, TASK_INTERRUPT_DISABLE );
-    }
-    else {
-      TaskStart( pcmcia_ide_rxTaskId, TASK_AUTOSTART_DISABLE,
-		 pcmcia_ide_rxTaskId, TASK_INTERRUPT_DISABLE );
-    }
-    if (use_irq) {
-
-      /*
-       * enable interrupts, wait for interrupt event
-       */
-      pcmcia_ide_hdl_task = rtems_task_self();
-      bestcomm_glue_irq_enable((is_write
-				? IDE_TX_TASK_NO
-				: IDE_RX_TASK_NO));
-
-      rtems_event_receive(PCMCIA_IDE_INTERRUPT_EVENT,
-			  RTEMS_WAIT | RTEMS_EVENT_ANY,
-			  RTEMS_NO_TIMEOUT, &events);
-
-      pcmcia_ide_hdl_task = 0;
-    }
-    else {
-      /*
-       * HACK: just wait some time...
-       */
-      /*
-       * FIXME: poll, until SDMA is finished
-       */
-      volatile int32_t i;
-      for (i = 0;i < 10000;i++) {};
-    }
-
-    do {
-	  nxt_bd_idx = TaskBDRelease(is_write
-	   				             ? pcmcia_ide_txTaskId
-					             : pcmcia_ide_rxTaskId);
-      if ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
-          (nxt_bd_idx != TASK_ERR_BD_BUSY)) {
-        (*cbuf)++;
-        (*pos) += bufs[bufs_from_dma].length;
-        bufs_from_dma++;
-        bds_free++;
-	  }
-    } while ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
-             (nxt_bd_idx != TASK_ERR_BD_BUSY)       &&
-  	         (bufs_from_dma < bufs_to_dma));
-  }
-#endif /* IDE_USE_DMA */
-}
-
-
-static void mpc5200_pcmciaide_read_block(int minor, uint32_t block_size,
-    rtems_blkdev_sg_buffer *bufs, uint32_t *cbuf, uint32_t *pos)
-{
-
-  volatile uint32_t *ata_reg=mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
-  uint16_t  cnt = 0;
-  uint16_t *lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer)+(*pos));
-  uint32_t  llength = bufs[(*cbuf)].length;
-  bool      use_dma;
-
-#if IDE_USE_STATISTICS
-      mpc5200_pcmciaide_read_block_call_cnt++;
-#endif
-#if IDE_READ_USE_DMA
-  /*
-   * FIXME: walk through buffer list. If any buffer has other size than default,
-   * then do not use DMA
-   * Is this needed?
-   */
-  use_dma = true;
-  /* use_dma = false; */
-#else
-  use_dma = false;
-#endif
-  if (use_dma) {
-    /*
-     * FIXME: wait for DRQ ready
-     * check, that once DRQ is ready, we really can send ALL data for this
-     * type of transfer mode
-     */
-    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
-						 (mpc5200.ata_dctr_dasr)) &
-	    IDE_REGISTER_STATUS_DRQ) == 0);
-    /*
-     * translate (part of) buffer list into DMA BDs
-     * only last (available) DMA BD sends interrupt
-     * DMA BDs may get ready as soon as possible
-     */
-    mpc5200_pcmciaide_dma_blockop(FALSE, /* read operation */
-				  minor,
-				  block_size,bufs,cbuf,pos);
-  }
-  else {
-#if IDE_USE_READ_PIO_OPT
-    while(cnt < block_size) {
-
-      *lbuf++ = GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*(volatile uint32_t *)(ata_reg)); /* only 16 bit data port */
-      cnt += 2;
-      (*pos) += 2;
-
-      if((*pos) == llength) {
-
-	  (*pos) = 0;
-	  (*cbuf)++;
-	  lbuf = bufs[(*cbuf)].buffer;
-	  llength = bufs[(*cbuf)].length;
-
-      }
-    }
-#else
-
-    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) & IDE_REGISTER_STATUS_DRQ) && (cnt < block_size)) {
-
-      *lbuf++ = *(volatile uint16_t *)(ata_reg); /* only 16 bit data port */
-      cnt += 2;
-      (*pos) += 2;
-
-      if((*pos) == llength) {
-	(*pos) = 0;
-	(*cbuf)++;
-	lbuf = bufs[(*cbuf)].buffer;
-	llength = bufs[(*cbuf)].length;
-      }
-    }
-#endif
-  }
-}
-
-static void mpc5200_pcmciaide_write_block(int minor, uint32_t block_size,
-    rtems_blkdev_sg_buffer *bufs, uint32_t *cbuf, uint32_t *pos)
-{
-
-
-  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
-  uint16_t  cnt = 0;
-  uint16_t *lbuf = (uint16_t *)((uint8_t *)(bufs[(*cbuf)].buffer) + (*pos));
-  uint32_t  llength = bufs[(*cbuf)].length;
-  bool use_dma;
-
-#if IDE_USE_STATISTICS
-  mpc5200_pcmciaide_write_block_call_cnt++;
-#endif
-#if IDE_WRITE_USE_DMA
-  /*
-   * FIXME: walk through buffer list. If any buffer has other size than default,
-   * then do not use DMA
-   * Is this needed?
-   */
-  use_dma = true;
-#else
-  use_dma = false;
-#endif
-
-  if (use_dma) {
-    /*
-     * wait for DRQ ready
-     * FIXME: check, that once DRQ is ready, we really can send ALL data for this
-     * type of transfer mode
-     */
-    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
-						 (mpc5200.ata_dctr_dasr)) &
-	    IDE_REGISTER_STATUS_DRQ) == 0);
-    /*
-     * translate (part of) buffer list into DMA BDs
-     * only last (available) DMA BD sends interrupt
-     * DMA BDs may get ready as soon as possible
-     */
-    mpc5200_pcmciaide_dma_blockop(true, /* write opeartion */
-				  minor,
-				  block_size,bufs,cbuf,pos);
-  }
-  else {
-#if IDE_USE_WRITE_PIO_OPT
-    while(cnt < block_size) {
-      int32_t loop_cnt,loop_max;
-
-#if IDE_USE_STATISTICS
-      mpc5200_pcmciaide_write_block_block_cnt++;
-#endif
-
-      loop_max = llength - (*pos) ;
-      if (loop_max > (block_size - cnt)) {
-	loop_max = (block_size - cnt);
-      }
-      for (loop_cnt = loop_max/2;loop_cnt > 0;loop_cnt--) {
-	*(volatile uint32_t *)(ata_reg) =
-	  SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*lbuf++); /* only 16 bit data port */
-      }
-      cnt += loop_max;
-      (*pos) += loop_max;
-
-      if((*pos) == llength) {
-
-	(*pos) = 0;
-	(*cbuf)++;
-	lbuf = bufs[(*cbuf)].buffer;
-	llength = bufs[(*cbuf)].length;
-      }
-    }
-#else
-    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr))
-	   & IDE_REGISTER_STATUS_DRQ)
-	  && (cnt < block_size)) {
-      *(volatile uint16_t *)(ata_reg) = *lbuf++; /* only 16 bit data port */
-      cnt += 2;
-      (*pos) += 2;
-
-      if((*pos) == llength) {
-	(*pos) = 0;
-	(*cbuf)++;
-	lbuf = bufs[(*cbuf)].buffer;
-	llength = bufs[(*cbuf)].length;
-      }
-    }
-#endif
-  }
-}
-
-static int mpc5200_pcmciaide_control(int  minor, uint32_t cmd, void * arg)
-  {
-  return RTEMS_SUCCESSFUL;
-  }
-
-static void mpc5200_pcmciaide_initialize(int minor)
-  {
-#if defined (MPC5200_BOARD_BRS5L)
-  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT7]);
-
-  /* invert ATA reset on GPT7 */
-  gpt->emsel = (GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO);
-#endif
-  /* reset ata host contr. and FIFO */
-  mpc5200.ata_hcfg |= (ATA_HCFG_SMR | ATA_HCFG_FR);
-  mpc5200.ata_hcfg &= ~(ATA_HCFG_SMR | ATA_HCFG_FR);
-
-  /* for the first access set lowest performance transfer mode to PIO3 */
-  mpc5200_pcmciaide_config_io_speed(minor, ATA_MODES_PIO3);
-
-  /* enable PIO operations (PIO 3/4) */
-  mpc5200.ata_hcfg |= ATA_HCFG_IORDY;
-
-#ifdef IDE_USE_INT
-  mpc5200.ata_hcfg |= ATA_HCFG_IE ;
-#endif
-
-#if IDE_USE_DMA
-  mpc5200_pcmciaide_dma_init(minor);
-#endif
-  }
-
-
-/*
- * The following table configures the functions used for IDE drivers
- * in this BSP.
- */
-ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns =
-  {
-  mpc5200_pcmciaide_probe,
-  mpc5200_pcmciaide_initialize,
-  mpc5200_pcmciaide_control,
-  mpc5200_pcmciaide_read_reg,
-  mpc5200_pcmciaide_write_reg,
-  mpc5200_pcmciaide_read_block,
-  mpc5200_pcmciaide_write_block,
-  mpc5200_pcmciaide_config_io_speed
-  };
-
Index: src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.h
===================================================================
--- c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.h	(revision 5a4e3dc0a5af631b1723858bc50a9af1545392fb)
+++ 	(revision )
@@ -1,98 +1,0 @@
-/*===============================================================*\
-| Project: RTEMS generic MPC5200 BSP                              |
-+-----------------------------------------------------------------+
-| Partially based on the code references which are named below.   |
-| Adaptions, modifications, enhancements and any recent parts of  |
-| the code are:                                                   |
-|                    Copyright (c) 2005                           |
-|                    Embedded Brains GmbH                         |
-|                    Obere Lagerstr. 30                           |
-|                    D-82178 Puchheim                             |
-|                    Germany                                      |
-|                    rtems@embedded-brains.de                     |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be         |
-| found in the file LICENSE in this distribution or at            |
-|                                                                 |
-| http://www.rtems.org/license/LICENSE.                           |
-|                                                                 |
-+-----------------------------------------------------------------+
-| this file contains declarations for the PCMCIA IDE Interface    |
-\*===============================================================*/
-/***********************************************************************/
-/*                                                                     */
-/*   Module:       pcmcia_ide.h                                        */
-/*   Date:         17/07/2003                                          */
-/*   Purpose:      RTEMS MPC5x00 PCMCIA IDE harddisk header file       */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Description:                                                      */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Code                                                              */
-/*   References:   none                                                */
-/*   Module:                                                           */
-/*   Project:                                                          */
-/*   Version                                                           */
-/*   Date:                                                             */
-/*                                                                     */
-/*   Author(s) / Copyright(s):                                         */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Partially based on the code references which are named above.     */
-/*   Adaptions, modifications, enhancements and any recent parts of    */
-/*   the code are under the right of                                   */
-/*                                                                     */
-/*         IPR Engineering, Dachauer StraÃe 38, D-80335 MÃŒnchen        */
-/*                        Copyright(C) 2003                            */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   IPR Engineering makes no representation or warranties with        */
-/*   respect to the performance of this computer program, and          */
-/*   specifically disclaims any responsibility for any damages,        */
-/*   special or consequential, connected with the use of this program. */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/*   Version history:  1.0                                             */
-/*                                                                     */
-/***********************************************************************/
-
-#ifndef __PCMCIA_IDE_h
-#define __PCMCIA_IDE_h
-
-#include <bsp.h>
-
-#define GPIOPCR_ATA_CS_4_5                           (1 << 24)
-
-/*#define DEBUG_OUT*/
-#define GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val32)  ((uint16_t)((val32) >> 24))
-#define SET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val8)   ((uint32_t)((val8)  << 24))
-#define GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val32)  ((uint16_t)((val32) >> 16))
-#define SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val16)  ((uint32_t)((val16) << 16))
-
-#define ATA_HCFG_SMR                                 (1 << 31)
-#define ATA_HCFG_FR                                  (1 << 30)
-#define ATA_HCFG_IORDY                               (1 << 24)
-#define ATA_HCFG_IE                                  (1 << 25)
-
-#define COUNT_VAL(nsec)                              (((nsec) * (IPB_CLOCK / 1000000) + 999) / 1000)
-
-#define PIO_3                                        0
-#define PIO_4                                        1
-
-#define T0                                           0
-#define T2_8                                         1
-#define T2_16                                        2
-#define T4                                           3
-#define T1                                           4
-#define TA                                           5
-
-#define ATA_PIO_TIMING_1(t0,t2_8,t2_16)              (((COUNT_VAL(t0)) << 24) | ((COUNT_VAL(t2_8)) << 16) | ((COUNT_VAL(t2_16)) << 8))
-#define ATA_PIO_TIMING_2(t4,t1,ta)                   (((COUNT_VAL(t4)) << 24) | ((COUNT_VAL(t1)) << 16) | ((COUNT_VAL(ta)) << 8))
-
-#endif
