This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Re: An IDE disk driver
- From: Iztok Zupet <iz at elsis dot si>
- To: Andrew Lunn <andrew at lunn dot ch>
- Cc: eCos patches <ecos-patches at ecos dot sourceware dot org>
- Date: Sun, 17 Oct 2004 22:30:22 +0200
- Subject: Re: An IDE disk driver
- Organization: Elsis d.o.o.
- References: <1098030954.18277.2.camel@iz-h.elsis.si> <20041017181002.GC18923@lunn.ch>
- Reply-to: iz at elsis dot si
On Sun, 2004-10-17 at 20:10 +0200, Andrew Lunn wrote:
> Hi Iztok ...
Done and attached.
Iztok
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/ChangeLog ./ChangeLog
*** /ecoscvs/orig/ecos/packages/ChangeLog 2004-10-10 16:53:37.000000000 +0200
--- ./ChangeLog 2004-10-17 17:25:03.000000000 +0200
***************
*** 1,5 ****
--- 1,9 ----
+ 2004-10-17 Iztok Zupet <iz@elsis.si>
+
+ * ecos.db: Added generic IDE disk driver.
+
2004-10-5 Andrea Michelotti <amichelotti@atmel.com>
* ecos.db: Added atmel jtst watchdog support
2004-10-05 Savin Zlobec <savin@elatec.si>
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl ./devs/disk/ide/current/cdl/ide_disk.cdl
*** /ecoscvs/orig/ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl 1970-01-01 01:00:00.000000000 +0100
--- ./devs/disk/ide/current/cdl/ide_disk.cdl 2004-10-17 21:59:46.000000000 +0200
***************
*** 0 ****
--- 1,128 ----
+ # ====================================================================
+ #
+ # ide_disk.cdl
+ #
+ # A generic IDE disk driver package.
+ #
+ # ====================================================================
+ #####ECOSGPLCOPYRIGHTBEGIN####
+ ## -------------------------------------------
+ ## This file is part of eCos, the Embedded Configurable Operating System.
+ ## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+ ## Copyright (C) 2004 eCosCentric, Ltd
+ ##
+ ## eCos is free software; you can redistribute it and/or modify it under
+ ## the terms of the GNU General Public License as published by the Free
+ ## Software Foundation; either version 2 or (at your option) any later version.
+ ##
+ ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ ## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ ## for more details.
+ ##
+ ## You should have received a copy of the GNU General Public License along
+ ## with eCos; if not, write to the Free Software Foundation, Inc.,
+ ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ ##
+ ## As a special exception, if other files instantiate templates or use macros
+ ## or inline functions from this file, or you compile this file and link it
+ ## with other works to produce a work based on this file, this file does not
+ ## by itself cause the resulting work to be covered by the GNU General Public
+ ## License. However the source code for this file must still be made available
+ ## in accordance with section (3) of the GNU General Public License.
+ ##
+ ## This exception does not invalidate any other reasons why a work based on
+ ## this file might be covered by the GNU General Public License.
+ ##
+ ## -------------------------------------------
+ #####ECOSGPLCOPYRIGHTEND####
+ # ====================================================================
+ ######DESCRIPTIONBEGIN####
+ #
+ # Author(s): iz
+ # Contributors:
+ # Date: 2004-10-16
+ #
+ #####DESCRIPTIONEND####
+ # ====================================================================
+
+ cdl_package CYGPKG_DEVS_DISK_IDE {
+ display "Disk driver for generic IDE"
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+
+ include_dir cyg/io
+ compile -library=libextras.a ide_disk.c
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK0 {
+ display "Provide disk 0 device"
+ flavor bool
+ default_value 1
+ description "IDE chanel 0:0 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK0_NAME {
+ display "Device name for disk 0 device"
+ flavor data
+ default_value {"\"/dev/hda/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK1 {
+ display "Provide disk 1 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 0:1 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK1_NAME {
+ display "Device name for disk 1 device"
+ flavor data
+ default_value {"\"/dev/hdb/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK2 {
+ display "Provide disk 2 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 1:0 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK2_NAME {
+ display "Device name for disk 2 device"
+ flavor data
+ default_value {"\"/dev/hdc/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK3 {
+ display "Provide disk 3 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 1:1 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK3_NAME {
+ display "Device name for disk 3 device"
+ flavor data
+ default_value {"\"/dev/hdd/\""}
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE {
+ display "Disk sector size"
+ flavor data
+ default_value 512
+ description "
+ This option controls the disk sector size (default=512)"
+ }
+
+ cdl_option CYGSEM_DEVS_DISK_IDE_VMWARE {
+ display "Work with VMware virtual disks"
+ flavor bool
+ default_value 0
+ description "
+ This option controls the disk driver behaviour at ide-init"
+ }
+
+ }
+
+ # EOF ide_disk.cdl
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/disk/ide/current/ChangeLog ./devs/disk/ide/current/ChangeLog
*** /ecoscvs/orig/ecos/packages/devs/disk/ide/current/ChangeLog 1970-01-01 01:00:00.000000000 +0100
--- ./devs/disk/ide/current/ChangeLog 2004-10-17 21:47:28.000000000 +0200
***************
*** 0 ****
--- 1,51 ----
+ 2004-10-17 Iztok Zupet <iz@elsis.si>
+
+ * include/ide_disk.h : moved to ->
+ * src/ide_disk.h: because this is a private include file
+
+ * cdl/ide_disk.cdl: define CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE there.
+ * src/ide_disk.c: use the CDL defined sector size
+
+
+ 2004-10-16 Iztok Zupet <iz@elsis.si>
+
+ * cdl/ide_disk.cdl:
+ * src/ide_disk.c:
+ * include/ide_disk.h:
+ A generic IDE disk device driver
+
+
+
+ //===========================================================================
+ //####ECOSGPLCOPYRIGHTBEGIN####
+ // -------------------------------------------
+ // This file is part of eCos, the Embedded Configurable Operating System.
+ // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+ // Copyright (C) 2004 eCosCentric, Ltd.
+ //
+ // eCos is free software; you can redistribute it and/or modify it under
+ // the terms of the GNU General Public License as published by the Free
+ // Software Foundation; either version 2 or (at your option) any later version.
+ //
+ // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ // WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ // for more details.
+ //
+ // You should have received a copy of the GNU General Public License along
+ // with eCos; if not, write to the Free Software Foundation, Inc.,
+ // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ //
+ // As a special exception, if other files instantiate templates or use macros
+ // or inline functions from this file, or you compile this file and link it
+ // with other works to produce a work based on this file, this file does not
+ // by itself cause the resulting work to be covered by the GNU General Public
+ // License. However the source code for this file must still be made available
+ // in accordance with section (3) of the GNU General Public License.
+ //
+ // This exception does not invalidate any other reasons why a work based on
+ // this file might be covered by the GNU General Public License.
+ //
+ // -------------------------------------------
+ //####ECOSGPLCOPYRIGHTEND####
+ //===========================================================================
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/disk/ide/current/src/ide_disk.c ./devs/disk/ide/current/src/ide_disk.c
*** /ecoscvs/orig/ecos/packages/devs/disk/ide/current/src/ide_disk.c 1970-01-01 01:00:00.000000000 +0100
--- ./devs/disk/ide/current/src/ide_disk.c 2004-10-17 21:49:37.000000000 +0200
***************
*** 0 ****
--- 1,425 ----
+ //==========================================================================
+ //
+ // ide_disk.c
+ //
+ // IDE polled mode disk driver
+ //
+ //==========================================================================
+ //####ECOSGPLCOPYRIGHTBEGIN####
+ // -------------------------------------------
+ // This file is part of eCos, the Embedded Configurable Operating System.
+ // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+ // Copyright (C) 2004 eCosCentric, Ltd.
+ //
+ // eCos is free software; you can redistribute it and/or modify it under
+ // the terms of the GNU General Public License as published by the Free
+ // Software Foundation; either version 2 or (at your option) any later version.
+ //
+ // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ // WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ // for more details.
+ //
+ // You should have received a copy of the GNU General Public License along
+ // with eCos; if not, write to the Free Software Foundation, Inc.,
+ // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ //
+ // As a special exception, if other files instantiate templates or use macros
+ // or inline functions from this file, or you compile this file and link it
+ // with other works to produce a work based on this file, this file does not
+ // by itself cause the resulting work to be covered by the GNU General Public
+ // License. However the source code for this file must still be made available
+ // in accordance with section (3) of the GNU General Public License.
+ //
+ // This exception does not invalidate any other reasons why a work based on
+ // this file might be covered by the GNU General Public License.
+ //
+ // -------------------------------------------
+ //####ECOSGPLCOPYRIGHTEND####
+ //==========================================================================
+ //#####DESCRIPTIONBEGIN####
+ //
+ // Author(s): iz
+ // Contributors:
+ // Date: 2004-10-16
+ //
+ //####DESCRIPTIONEND####
+ //
+ //==========================================================================
+
+ #include <pkgconf/devs_disk_ide.h>
+
+ #include <cyg/infra/cyg_type.h>
+ #include <cyg/infra/cyg_ass.h>
+ #include <cyg/infra/diag.h>
+ #include <cyg/hal/hal_arch.h>
+ #include <cyg/hal/hal_io.h>
+ #include <cyg/hal/hal_if.h> // delays
+ #include <cyg/hal/drv_api.h>
+ #include <cyg/io/io.h>
+ #include <cyg/io/devtab.h>
+ #include <cyg/io/disk.h>
+
+ #include "ide_disk.h"
+
+ // ----------------------------------------------------------------------------
+
+ //#define DEBUG 1
+
+ #ifdef DEBUG
+ # define D(fmt,args...) diag_printf(fmt, ## args)
+ #else
+ # define D(fmt,args...)
+ #endif
+
+ // ----------------------------------------------------------------------------
+
+ #ifdef CYGVAR_DEVS_DISK_IDE_DISK0
+ IDE_DISK_INSTANCE(0, 0, 0, true, CYGDAT_IO_DISK_IDE_DISK0_NAME);
+ #endif
+
+ #ifdef CYGVAR_DEVS_DISK_IDE_DISK1
+ IDE_DISK_INSTANCE(1, 0, 1, true, CYGDAT_IO_DISK_IDE_DISK1_NAME);
+ #endif
+
+ #ifdef CYGVAR_DEVS_DISK_IDE_DISK2
+ IDE_DISK_INSTANCE(2, 1, 0, true, CYGDAT_IO_DISK_IDE_DISK2_NAME);
+ #endif
+
+ #ifdef CYGVAR_DEVS_DISK_IDE_DISK3
+ IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME);
+ #endif
+
+ // ----------------------------------------------------------------------------
+
+ static void
+ id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size)
+ {
+ int i;
+
+ for (i = 0; i < size; i+=2)
+ {
+ *dest++ = (char)(*src >> 8);
+ *dest++ = (char)(*src & 0x00FF);
+ src++;
+ }
+ *dest = '\0';
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static inline void
+ __wait_for_ready(int ctlr)
+ {
+ cyg_uint8 status;
+ do {
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ));
+ }
+
+ static inline int
+ __wait_for_drq(int ctlr)
+ {
+ cyg_uint8 status;
+ cyg_ucount32 tries;
+
+ CYGACC_CALL_IF_DELAY_US(10);
+ for (tries=0; tries<1000000; tries++) {
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ if (!(status & IDE_STAT_BSY)) {
+ if (status & IDE_STAT_DRQ)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ // Return true if any devices attached to controller
+ static int
+ ide_presence_detect(int ctlr)
+ {
+ cyg_uint8 sel, val;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ sel = (i << 4) | 0xA0;
+ CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel);
+ CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val);
+ if (val == sel) {
+ #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE
+ if (i)
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0);
+ #endif
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ static int
+ ide_reset(int ctlr)
+ {
+ cyg_uint8 status;
+ int delay;
+ //
+ // VMware note:
+ // VMware virtual IDE device handler obviously expects that
+ // the reset and setup functions were already done
+ // by it's bios and complains if one uses reset here...
+ //
+ #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE
+ HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted
+ CYGACC_CALL_IF_DELAY_US(5000);
+ HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared
+ CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000);
+ #endif
+
+ // wait 30 seconds max for not busy and drive ready
+ for (delay = 0; delay < 300; ++delay) {
+ CYGACC_CALL_IF_DELAY_US((cyg_uint32)100000);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ if (!(status & IDE_STAT_BSY)) {
+ if (status & IDE_STAT_DRDY) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ static int
+ ide_ident(int ctlr, int dev, cyg_uint16 *buf)
+ {
+ int i;
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC);
+ CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+
+ for (i = 0; i < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16));
+ i++, buf++)
+ HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf);
+
+ return 1;
+ }
+
+ static int
+ ide_read_sector(int ctlr, int dev, cyg_uint32 start,
+ cyg_uint8 *buf, cyg_uint32 len)
+ {
+ int j, c;
+ cyg_uint16 p;
+ cyg_uint8 * b=buf;
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE,
+ ((start >> 24) & 0xf) | (dev << 4) | 0x40);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+ //
+ // It would be fine if all buffers were word aligned,
+ // but who knows
+ //
+ for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16));
+ j++) {
+ HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, p);
+ if (c++<len) *b++=p&0xff;
+ if (c++<len) *b++=(p>>8)&0xff;
+ }
+ return 1;
+ }
+
+ static int
+ ide_write_sector(int ctlr, int dev, cyg_uint32 start,
+ cyg_uint8 *buf, cyg_uint32 len)
+ {
+ int j, c;
+ cyg_uint16 p;
+ cyg_uint8 * b=buf;
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE,
+ ((start >> 24) & 0xf) | (dev << 4) | 0x40);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+ //
+ // It would be fine if all buffers were word aligned,
+ // but who knows
+ //
+ for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16));
+ j++) {
+ p = (c++<len) ? *b++ : 0;
+ p |= (c++<len) ? (*b++<<8) : 0;
+ HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, p);
+ }
+ return 1;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static cyg_bool
+ ide_disk_init(struct cyg_devtab_entry *tab)
+ {
+ disk_channel *chan = (disk_channel *) tab->priv;
+ ide_disk_info_t *info = (ide_disk_info_t *) chan->dev_priv;
+ cyg_uint32 id_buf[CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint32)];
+ static int num_controllers;
+ static int ide_present[4], ide_reset_done[4];
+ cyg_disk_identify_t ident;
+ ide_identify_data_t *ide_idData=(ide_identify_data_t*)id_buf;
+
+ if (chan->init)
+ return true;
+
+ D("IDE(%d:%d) hw init\n", info->port, info->chan);
+
+ if (!num_controllers) num_controllers=HAL_IDE_INIT();
+ if (info->chan>=num_controllers) {
+ D("No IDE controller for channel %d:%d\n", info->port, info->chan);
+ return false;
+ }
+ if (!ide_present[info->port]) {
+ ide_present[info->port]=ide_presence_detect(info->port);
+ if (!ide_present[info->port]) {
+ diag_printf("No devices on IDE controller #%d\n",info->port);
+ return false;
+ }
+ }
+ if (!ide_reset_done[info->port]) {
+ ide_reset_done[info->port]=ide_reset(info->port);
+ if (!ide_reset_done[info->port]) {
+ D("Controller #%d reset failure\n",info->port);
+ return false;
+ }
+ }
+
+ D("IDE %d:%d identify drive\n", info->port, info->chan);
+
+ if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) {
+ diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan);
+ return false;
+ }
+
+ id_strcpy(ident.serial, ide_idData->serial, 20);
+ id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8);
+ id_strcpy(ident.model_num, ide_idData->model_num, 40);
+
+ ident.cylinders_num = ide_idData->num_cylinders;
+ ident.heads_num = ide_idData->num_heads;
+ ident.sectors_num = ide_idData->num_sectors;
+ ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 |
+ ide_idData->lba_total_sectors[0];
+
+ D("\tSerial : %s\n", ident.serial);
+ D("\tFirmware rev. : %s\n", ident.firmware_rev);
+ D("\tModel : %s\n", ident.model_num);
+ D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num,
+ ident.heads_num, ident.sectors_num);
+ D("\tKind : %x\n", (ide_idData->general_conf>>8)&0x1f);
+
+ if (((ide_idData->general_conf>>8)&0x1f)!=2) {
+ diag_printf("IDE device %d:%d is not a hard disk!\n",
+ info->port, info->chan);
+ return false;
+ }
+ if (!(chan->callbacks->disk_init)(tab))
+ return false;
+
+ if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
+ return false;
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static Cyg_ErrNo
+ ide_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+ {
+ disk_channel *chan = (disk_channel *) (*tab)->priv;
+ return (chan->callbacks->disk_lookup)(tab, sub_tab, name);
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static Cyg_ErrNo
+ ide_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+ {
+ ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv;
+
+ D("IDE %d:%d read block %d\n", info->port, info->chan, block_num);
+
+ if (!ide_read_sector(info->port, info->chan, block_num,
+ (cyg_uint8 *)buf, len)) {
+ diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan);
+ return -EIO;
+ }
+
+ return ENOERR;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static Cyg_ErrNo
+ ide_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+ {
+ ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv;
+
+ D("IDE %d:%d write block %d\n", info->port, info->chan, block_num);
+
+ if (!ide_write_sector(info->port, info->chan, block_num,
+ (cyg_uint8 *)buf, len)) {
+ diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan);
+ return -EIO;
+ }
+
+ return ENOERR;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static Cyg_ErrNo
+ ide_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+ {
+ return -EINVAL;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ static Cyg_ErrNo
+ ide_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+ {
+ return -EINVAL;
+ }
+
+ //EOF ide_disk.c
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/devs/disk/ide/current/src/ide_disk.h ./devs/disk/ide/current/src/ide_disk.h
*** /ecoscvs/orig/ecos/packages/devs/disk/ide/current/src/ide_disk.h 1970-01-01 01:00:00.000000000 +0100
--- ./devs/disk/ide/current/src/ide_disk.h 2004-10-17 21:38:52.000000000 +0200
***************
*** 0 ****
--- 1,186 ----
+ #ifndef CYGONCE_IDE_DISK_H
+ #define CYGONCE_IDE_DISK_H
+ //==========================================================================
+ //
+ // ide_disk.h
+ //
+ // IDE polled mode disk driver defines
+ //
+ //==========================================================================
+ //####ECOSGPLCOPYRIGHTBEGIN####
+ // -------------------------------------------
+ // This file is part of eCos, the Embedded Configurable Operating System.
+ // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+ // Copyright (C) 2004 eCosCentric, Ltd.
+ //
+ // eCos is free software; you can redistribute it and/or modify it under
+ // the terms of the GNU General Public License as published by the Free
+ // Software Foundation; either version 2 or (at your option) any later version.
+ //
+ // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ // WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ // for more details.
+ //
+ // You should have received a copy of the GNU General Public License along
+ // with eCos; if not, write to the Free Software Foundation, Inc.,
+ // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ //
+ // As a special exception, if other files instantiate templates or use macros
+ // or inline functions from this file, or you compile this file and link it
+ // with other works to produce a work based on this file, this file does not
+ // by itself cause the resulting work to be covered by the GNU General Public
+ // License. However the source code for this file must still be made available
+ // in accordance with section (3) of the GNU General Public License.
+ //
+ // This exception does not invalidate any other reasons why a work based on
+ // this file might be covered by the GNU General Public License.
+ //
+ // -------------------------------------------
+ //####ECOSGPLCOPYRIGHTEND####
+ //==========================================================================
+ //#####DESCRIPTIONBEGIN####
+ //
+ // Author(s): iz
+ // Contributors:
+ // Date: 2004-10-16
+ //
+ //####DESCRIPTIONEND####
+ //
+ //==========================================================================
+
+ // IDE Register Indices
+ #define IDE_REG_DATA 0
+ #define IDE_REG_ERROR 1
+ #define IDE_REG_FEATURES 1
+ #define IDE_REG_COUNT 2
+ #define IDE_REG_REASON 2 // ATAPI
+ #define IDE_REG_LBALOW 3
+ #define IDE_REG_LBAMID 4
+ #define IDE_REG_LBAHI 5
+ #define IDE_REG_DEVICE 6
+ #define IDE_REG_STATUS 7
+ #define IDE_REG_COMMAND 7
+
+ #define IDE_STAT_BSY 0x80
+ #define IDE_STAT_DRDY 0x40
+ #define IDE_STAT_SERVICE 0x10
+ #define IDE_STAT_DRQ 0x08
+ #define IDE_STAT_CORR 0x04
+ #define IDE_STAT_ERR 0x01
+
+ #define IDE_REASON_REL 0x04
+ #define IDE_REASON_IO 0x02
+ #define IDE_REASON_COD 0x01
+
+ /* flag values */
+ #define IDE_DEV_PRESENT 1 // Device is present
+ #define IDE_DEV_PACKET 2 // Supports packet interface
+ #define IDE_DEV_ADDR48 3 // Supports 48bit addressing
+
+ typedef struct ide_identify_data_t_ {
+ cyg_uint16 general_conf; // 00 : general configuration
+ cyg_uint16 num_cylinders; // 01 : number of cylinders (default CHS trans)
+ cyg_uint16 reserved0; // 02 : reserved
+ cyg_uint16 num_heads; // 03 : number of heads (default CHS trans)
+ cyg_uint16 num_ub_per_track; // 04 : number of unformatted bytes per track
+ cyg_uint16 num_ub_per_sector; // 05 : number of unformatted bytes per sector
+ cyg_uint16 num_sectors; // 06 : number of sectors per track (default CHS trans)
+ cyg_uint16 num_card_sectors[2]; // 07-08 : number of sectors per card
+ cyg_uint16 reserved1; // 09 : reserved
+ cyg_uint16 serial[10]; // 10-19 : serial number (string)
+ cyg_uint16 buffer_type; // 20 : buffer type (dual ported)
+ cyg_uint16 buffer_size; // 21 : buffer size in 512 increments
+ cyg_uint16 num_ECC_bytes; // 22 : number of ECC bytes passed on R/W Long cmds
+ cyg_uint16 firmware_rev[4]; // 23-26 : firmware revision (string)
+ cyg_uint16 model_num[20]; // 27-46 : model number (string)
+ cyg_uint16 rw_mult_support; // 47 : max number of sectors on R/W multiple cmds
+ cyg_uint16 reserved2; // 48 : reserved
+ cyg_uint16 capabilities; // 49 : LBA, DMA, IORDY support indicator
+ cyg_uint16 reserved3; // 50 : reserved
+ cyg_uint16 pio_xferc_timing; // 51 : PIO data transfer cycle timing mode
+ cyg_uint16 dma_xferc_timing; // 52 : single word DMA data transfer cycle timing mode
+ cyg_uint16 cur_field_validity; // 53 : words 54-58 validity (0 == not valid)
+ cyg_uint16 cur_cylinders; // 54 : number of current cylinders
+ cyg_uint16 cur_heads; // 55 : number of current heads
+ cyg_uint16 cur_spt; // 56 : number of current sectors per track
+ cyg_uint16 cur_capacity[2]; // 57-58 : current capacity in sectors
+ cyg_uint16 mult_sectors; // 59 : multiple sector setting
+ cyg_uint16 lba_total_sectors[2]; // 60-61 : total sectors in LBA mode
+ cyg_uint16 sw_dma; // 62 : single word DMA support
+ cyg_uint16 mw_dma; // 63 : multi word DMA support
+ cyg_uint16 apio_modes; // 64 : advanced PIO transfer mode supported
+ cyg_uint16 min_dma_timing; // 65 : minimum multiword DMA transfer cycle
+ cyg_uint16 rec_dma_timing; // 66 : recommended multiword DMA cycle
+ cyg_uint16 min_pio_timing; // 67 : min PIO transfer time without flow control
+ cyg_uint16 min_pio_iordy_timing; // 68 : min PIO transfer time with IORDY flow control
+ // cyg_uint16 reserved4[187]; // 69-255: reserved
+ } ide_identify_data_t;
+
+
+ typedef struct ide_disk_info_t_ {
+ cyg_uint8 port;
+ cyg_uint8 chan;
+ } ide_disk_info_t;
+
+ // ----------------------------------------------------------------------------
+
+ static cyg_bool ide_disk_init(struct cyg_devtab_entry *tab);
+
+ static Cyg_ErrNo ide_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+
+ static Cyg_ErrNo ide_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+ static Cyg_ErrNo ide_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+ static Cyg_ErrNo ide_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+ static Cyg_ErrNo ide_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+ static DISK_FUNS(ide_disk_funs,
+ ide_disk_read,
+ ide_disk_write,
+ ide_disk_get_config,
+ ide_disk_set_config
+ );
+
+ // ----------------------------------------------------------------------------
+
+ #define IDE_DISK_INSTANCE(_number_,_port_,_chan_,_mbr_supp_,_name_) \
+ static ide_disk_info_t ide_disk_info##_number_ = { \
+ port: (cyg_uint8) _port_, \
+ chan: (cyg_uint8) _chan_ \
+ }; \
+ DISK_CHANNEL(ide_disk_channel##_number_, \
+ ide_disk_funs, \
+ ide_disk_info##_number_, \
+ _mbr_supp_, \
+ 4 \
+ ); \
+ BLOCK_DEVTAB_ENTRY(ide_disk_io##_number_, \
+ _name_, \
+ 0, \
+ &cyg_io_disk_devio, \
+ ide_disk_init, \
+ ide_disk_lookup, \
+ &ide_disk_channel##_number_ \
+ );
+
+ // ----------------------------------------------------------------------------
+
+ #endif // CYGONCE_IDE_DISK_H
diff -C5 -N -P -r -x '.*' /ecoscvs/orig/ecos/packages/ecos.db ./ecos.db
*** /ecoscvs/orig/ecos/packages/ecos.db 2004-10-10 16:53:38.000000000 +0200
--- ./ecos.db 2004-10-17 17:21:22.000000000 +0200
***************
*** 5705,5714 ****
--- 5705,5721 ----
script synthdisk.cdl
hardware
description "Disk driver for the synthetic target."
}
+ package CYGPKG_DEVS_DISK_IDE {
+ alias { "Generic IDE disk driver" ide_disk }
+ directory devs/disk/ide
+ script ide_disk.cdl
+ description "Disk driver for generic IDE interface."
+ }
+
package CYGPKG_IO_DISK {
alias { "Disk device drivers" disk io_disk }
directory io/disk
script io_disk.cdl
description "