Problem with IDE disk

Andrew Lunn andrew@lunn.ch
Tue Feb 8 10:10:00 GMT 2005


On Wed, Feb 02, 2005 at 01:35:40PM +0100, knud.woehler@microplex.de wrote:
> Hello
> the attached patch corrects two problems with the ide_disk driver.
> 
> 1. The check for hard disks does not work. The line
> "if (((ide_idData->general_conf>>8)&0x1f)!=2) " returns true with my 
> hard disk. (ide_idData->general_conf = 0x0040)

I've not commited this part. I would like to understand this
better. Maybe somebody can spend some time looking at the standard and
work out what is correct.
 
> 2. I have to wait for "not busy" before sending a command to the device.

This i have committed.

   Thanks
        Andrew
-------------- next part --------------
Index: devs/disk/ide/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/disk/ide/current/ChangeLog,v
retrieving revision 1.1
diff -u -r1.1 ChangeLog
--- devs/disk/ide/current/ChangeLog	18 Oct 2004 09:03:45 -0000	1.1
+++ devs/disk/ide/current/ChangeLog	8 Feb 2005 10:06:14 -0000
@@ -1,3 +1,8 @@
+2005-02-02 Knud Woehler <knud.woehler@microplex.de>
+
+	* src/ide_disk.c: Check the device is not busy before sending a
+	command to the device. 
+	
 2004-10-17 Iztok Zupet <iz@elsis.si>
 
 	* include/ide_disk.h : moved to ->
Index: devs/disk/ide/current/src/ide_disk.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/disk/ide/current/src/ide_disk.c,v
retrieving revision 1.1
diff -u -r1.1 ide_disk.c
--- devs/disk/ide/current/src/ide_disk.c	18 Oct 2004 09:03:45 -0000	1.1
+++ devs/disk/ide/current/src/ide_disk.c	8 Feb 2005 10:06:14 -0000
@@ -117,14 +117,30 @@
     } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ));
 }
 
+// Wait while the device is busy with the last command
+static inline int
+__wait_busy(int ctlr)
+{
+    cyg_uint8 status;
+    cyg_ucount32 tries;
+    
+    for (tries=0; tries < 1000000; tries++) {
+         CYGACC_CALL_IF_DELAY_US(10);
+         HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+         if ((status & IDE_STAT_BSY) == 0)
+              return 1;
+    }
+    return 0;   
+}
+
 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++) {
+        CYGACC_CALL_IF_DELAY_US(10);
         HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
         if (!(status & IDE_STAT_BSY)) {
             if (status & IDE_STAT_DRQ)
@@ -133,6 +149,7 @@
                 return 0;
         }
     }
+    return 0;
 }
 
 // Return true if any devices attached to controller
@@ -195,13 +212,18 @@
 {
     int i;
 
+    if (!__wait_busy(ctlr)) {
+         return 0;
+    }
+    
     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;
-
+    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);
@@ -217,6 +239,10 @@
     cyg_uint16 p;
     cyg_uint8 * b=buf;
 
+    if(!__wait_busy(ctlr)) {
+         return 0;
+    }
+    
     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);
@@ -248,6 +274,10 @@
     cyg_uint16 p;
     cyg_uint8 * b=buf;
 
+    if(!__wait_busy(ctlr)) {
+         return 0;
+    }
+    
     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);
@@ -332,7 +362,7 @@
     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);


More information about the Ecos-patches mailing list