This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: An IDE disk driver


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 "

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]