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