[PATCH 1/9] block: introduce a delay before every outb operation

2013-02-12 Thread Linus Walleij
When I plug an ISA XT 8bit card into a 16bit compatible EISA
slot, the outb() operations seemingly stumble over each other
so we need to introduce a small delay after each outb()
operation. After this my MFM MiniScribe harddrive is properly
detected like this:

Detected 1 hard drive (using IRQ5 & DMA3)
 xda: CHS=615/4/17

Signed-off-by: Linus Walleij 
---
 drivers/block/xd.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index ff54052..303e9f2 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -57,6 +57,8 @@
 
 #include "xd.h"
 
+#define OUTB_DELAY 100
+
 static DEFINE_MUTEX(xd_mutex);
 static void __init do_xd_setup (int *integers);
 #ifdef MODULE
@@ -485,7 +487,8 @@ static irqreturn_t xd_interrupt_handler(int irq, void 
*dev_id)
 #ifdef DEBUG_OTHER
printk("xd_interrupt_handler: interrupt detected\n");
 #endif /* DEBUG_OTHER */
-   outb(0,XD_CONTROL); 
/* acknowledge interrupt */
+   outb(0,XD_CONTROL); /* acknowledge interrupt */
+   udelay(OUTB_DELAY);
wake_up(_wait_int);  /* and wake up sleeping processes */
return IRQ_HANDLED;
}
@@ -588,7 +591,9 @@ static u_int xd_command (u_char *command,u_char mode,u_char 
*indata,u_char *outd
 #endif /* DEBUG_COMMAND */
 
outb(0,XD_SELECT);
+   udelay(OUTB_DELAY);
outb(mode,XD_CONTROL);
+   udelay(OUTB_DELAY);
 
if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
return (1);
@@ -602,8 +607,10 @@ static u_int xd_command (u_char *command,u_char 
mode,u_char *indata,u_char *outd
if (mode == DMA_MODE) {
if (xd_wait_for_IRQ())
return (1);
-   } else
+   } else {
outb(outdata ? *outdata++ : 0,XD_DATA);
+   udelay(OUTB_DELAY);
+   }
break;
case STAT_INPUT:
if (mode == DMA_MODE) {
@@ -617,6 +624,7 @@ static u_int xd_command (u_char *command,u_char mode,u_char 
*indata,u_char *outd
break;
case STAT_COMMAND:
outb(command ? *command++ : 0,XD_DATA);
+   udelay(OUTB_DELAY);
break;
case STAT_COMMAND | STAT_INPUT:
complete = 1;
@@ -680,6 +688,7 @@ static void __init xd_dtc_init_controller (unsigned int 
address)
xd_maxsectors = 0x01;   /* my card seems to have trouble doing 
multi-block transfers? */
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 
@@ -773,6 +782,7 @@ static void __init xd_wd_init_controller (unsigned int 
address)
xd_maxsectors = 0x01;   /* this one doesn't wrap properly 
either... */
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 
msleep(XD_INIT_DISK_DELAY);
 }
@@ -875,6 +885,7 @@ static void __init xd_seagate_init_controller (unsigned int 
address)
xd_maxsectors = 0x40;
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 static void __init xd_seagate_init_drive (u_char drive)
@@ -908,6 +919,7 @@ static void __init xd_omti_init_controller (unsigned int 
address)
xd_maxsectors = 0x40;
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 static void __init xd_omti_init_drive (u_char drive)
@@ -947,6 +959,7 @@ If you need non-standard settings use the xd=... command */
 
xd_maxsectors = 0x01;
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 
msleep(XD_INIT_DISK_DELAY);
 }
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/9] block: introduce a delay before every outb operation

2013-02-12 Thread Linus Walleij
When I plug an ISA XT 8bit card into a 16bit compatible EISA
slot, the outb() operations seemingly stumble over each other
so we need to introduce a small delay after each outb()
operation. After this my MFM MiniScribe harddrive is properly
detected like this:

Detected 1 hard drive (using IRQ5  DMA3)
 xda: CHS=615/4/17

Signed-off-by: Linus Walleij linus.wall...@linaro.org
---
 drivers/block/xd.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index ff54052..303e9f2 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -57,6 +57,8 @@
 
 #include xd.h
 
+#define OUTB_DELAY 100
+
 static DEFINE_MUTEX(xd_mutex);
 static void __init do_xd_setup (int *integers);
 #ifdef MODULE
@@ -485,7 +487,8 @@ static irqreturn_t xd_interrupt_handler(int irq, void 
*dev_id)
 #ifdef DEBUG_OTHER
printk(xd_interrupt_handler: interrupt detected\n);
 #endif /* DEBUG_OTHER */
-   outb(0,XD_CONTROL); 
/* acknowledge interrupt */
+   outb(0,XD_CONTROL); /* acknowledge interrupt */
+   udelay(OUTB_DELAY);
wake_up(xd_wait_int);  /* and wake up sleeping processes */
return IRQ_HANDLED;
}
@@ -588,7 +591,9 @@ static u_int xd_command (u_char *command,u_char mode,u_char 
*indata,u_char *outd
 #endif /* DEBUG_COMMAND */
 
outb(0,XD_SELECT);
+   udelay(OUTB_DELAY);
outb(mode,XD_CONTROL);
+   udelay(OUTB_DELAY);
 
if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
return (1);
@@ -602,8 +607,10 @@ static u_int xd_command (u_char *command,u_char 
mode,u_char *indata,u_char *outd
if (mode == DMA_MODE) {
if (xd_wait_for_IRQ())
return (1);
-   } else
+   } else {
outb(outdata ? *outdata++ : 0,XD_DATA);
+   udelay(OUTB_DELAY);
+   }
break;
case STAT_INPUT:
if (mode == DMA_MODE) {
@@ -617,6 +624,7 @@ static u_int xd_command (u_char *command,u_char mode,u_char 
*indata,u_char *outd
break;
case STAT_COMMAND:
outb(command ? *command++ : 0,XD_DATA);
+   udelay(OUTB_DELAY);
break;
case STAT_COMMAND | STAT_INPUT:
complete = 1;
@@ -680,6 +688,7 @@ static void __init xd_dtc_init_controller (unsigned int 
address)
xd_maxsectors = 0x01;   /* my card seems to have trouble doing 
multi-block transfers? */
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 
@@ -773,6 +782,7 @@ static void __init xd_wd_init_controller (unsigned int 
address)
xd_maxsectors = 0x01;   /* this one doesn't wrap properly 
either... */
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 
msleep(XD_INIT_DISK_DELAY);
 }
@@ -875,6 +885,7 @@ static void __init xd_seagate_init_controller (unsigned int 
address)
xd_maxsectors = 0x40;
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 static void __init xd_seagate_init_drive (u_char drive)
@@ -908,6 +919,7 @@ static void __init xd_omti_init_controller (unsigned int 
address)
xd_maxsectors = 0x40;
 
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 }
 
 static void __init xd_omti_init_drive (u_char drive)
@@ -947,6 +959,7 @@ If you need non-standard settings use the xd=... command */
 
xd_maxsectors = 0x01;
outb(0,XD_RESET);   /* reset the controller */
+   udelay(OUTB_DELAY);
 
msleep(XD_INIT_DISK_DELAY);
 }
-- 
1.8.1.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/