Get soft reset at initialization working again.

Remove reset_time code.  (Re-add timeouts some time later.)
Eliminate remaining sleep_on() calls.
Encapsulate access to esdi attention register.
Correct some formatting in config display.
Correct soft reset logic.

Also...
http://www.sound.net/~hald/projects/ps2esdi/ps2esdi-2.4.4-patch4

Hal Duston
[EMAIL PROTECTED]
Get soft reset at initialization working again.

Remove reset_time code.  (Re-add timeouts some time later.)
Eliminate remaining sleep_on() calls.
Encapsulate access to esdi attention register.
Correct some formatting in config display.
Correct soft reset logic.

--- linux-2.4.5-pre4/drivers/block/ps2esdi.c.3  Mon May 21 00:07:38 2001
+++ linux-2.4.5-pre4/drivers/block/ps2esdi.c.4  Mon May 21 00:16:49 2001
@@ -107,6 +107,8 @@
 
 static void ps2esdi_reset_timer(unsigned long unused);
 
+static int ps2esdi_attention(u_int device, u_int request);
+
 static u_int dma_arb_level;            /* DMA arbitration level */
 
 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
@@ -460,19 +462,8 @@
        current_int_handler = ps2esdi_initial_reset_int_handler;
        reset_ctrl();
        reset_status = 0;
-       reset_start = jiffies;
-       while (!reset_status) {
-               init_timer(&esdi_timer);
-               esdi_timer.expires = jiffies + HZ;
-               esdi_timer.data = 0;
-               add_timer(&esdi_timer);
-               sleep_on(&ps2esdi_int);
-       }
-       reset_end = jiffies;
+       wait_event(ps2esdi_int, reset_status);
        LITE_OFF;
-       printk("%s: reset interrupt after %d jiffies,  %u.%02u secs\n",
-              DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
-              (reset_end - reset_start) % HZ);
 
 
        /* Integrated ESDI Disk and Controller has only one drive! */
@@ -522,8 +513,7 @@
                cmd_blk[1] = 0;
                no_int_yet = TRUE;
                ps2esdi_out_cmd_blk(cmd_blk);
-               if (no_int_yet)
-                       sleep_on(&ps2esdi_int);
+               wait_event(ps2esdi_int, !no_int_yet);
        }
        return;
 }
@@ -597,32 +587,20 @@
 {
 
        u_long expire;
-       u_short status;
-
-       /* enable interrupts on the controller */
-       status = inb(ESDI_INTRPT);
-       outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);     /* to be sure we don't have
-                                                          any interrupt pending... */
-       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 
-       /* read the ESDI status port - if the controller is not busy,
-          simply do a soft reset (fast) - otherwise we'll have to do a
-          hard (slow) reset.  */
-       if (!(inb(ESDI_STATUS) & STATUS_BUSY)) {
+       if(!ps2esdi_attention(0x07, 0x04)) {
                /*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
-               outb(CTRL_SOFT_RESET, ESDI_ATTN);
        }
-       /* soft reset */ 
+       /* soft reset */
        else {
                /*BA */
                printk("%s: hard reset...\n", DEVICE_NAME);
                outb(CTRL_HARD_RESET, ESDI_CONTROL);
-               expire = jiffies + 2*HZ;
-               while (time_before(jiffies, expire));
-               outb(1, ESDI_CONTROL);
+               expire = jiffies + 2 * HZ;
+               while(time_before(jiffies, expire))
+               {}
+               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
        }                       /* hard reset */
-
-
 }                              /* reset the controller */
 
 /* called by the strategy routine to handle read and write requests */
@@ -695,13 +673,10 @@
        printk("%s: i(1)=%d\n", DEVICE_NAME, i);
 #endif
 
-       /* if device is still busy - then just time out */
-       if (inb(ESDI_STATUS) & STATUS_BUSY) {
-               printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
+       if(ps2esdi_attention((cmd_blk[0] & 0xe0) >> 5, 0x01)) {
+               printk("%s: ps2esdi_out_cmd timed out (%x)\n", DEVICE_NAME, 
+(cmd_blk[0] & 0xe0) >> 5);
                return ERROR;
-       }                       /* timeout ??? */
-       /* Set up the attention register in the controller */
-       outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
+       }
 
 #if 0
        printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 
14) + 1) << 1);
@@ -774,25 +749,25 @@
 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
 {
 
+       reset_status = int_ret_code;
        switch (int_ret_code & 0xf) {
        case INT_RESET:
                /*BA */
                printk("%s: initial reset completed.\n", DEVICE_NAME);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                wake_up(&ps2esdi_int);
                break;
        case INT_ATTN_ERROR:
-               printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+               printk("%s: Attention error during reset. interrupt status : %02X\n", 
+DEVICE_NAME,
                       int_ret_code);
                printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
                break;
        default:
                printk("%s: initial reset handler received interrupt: %02X\n",
                       DEVICE_NAME, int_ret_code);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                break;
        }
-       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 }
 
 
@@ -821,10 +796,10 @@
                                printk("%s: Device Configuration Status for drive 
%u\n",
                                       DEVICE_NAME, drive_num);
 
-                               printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 
8);
+                               printk("%s: Spares/cyls: %u\n", DEVICE_NAME, reply[0] 
+>> 8);
 
                                printk
-                                   ("Config bits: %s%s%s%s%s\n",
+                                   ("%s: Config bits: %s%s%s%s%s\n", DEVICE_NAME,
                                     (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : 
"",
                                     ((reply[0] & CONFIG_ZD) && !(reply[0] & 
CONFIG_IS))
                                 ? "Zero Defect, " : "Defects Present, ",
@@ -877,11 +852,11 @@
                        printk("%s: command %02X unknown by geometry handler\n",
                               DEVICE_NAME, status & 0x1f);
 
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                break;
 
        case INT_ATTN_ERROR:
-               printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+               printk("%s: Attention error during geometry. interrupt status : 
+%02X\n", DEVICE_NAME,
                       int_ret_code);
                printk("%s: Device not available\n", DEVICE_NAME);
                --ps2esdi_drives;
@@ -896,19 +871,18 @@
        case INT_CMD_BLK_ERR:
                /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
                dump_cmd_complete_status(int_ret_code);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                --ps2esdi_drives;
                break;
        default:
                printk("%s: Unknown interrupt reason: %02X\n",
                       DEVICE_NAME, int_ret_code & 0xf);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                break;
        }
 
        wake_up(&ps2esdi_int);
        no_int_yet = FALSE;
-       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 
 }
 
@@ -930,7 +904,7 @@
                break;
 
        case INT_ATTN_ERROR:
-               printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+               printk("%s: Attention error during normal. interrupt status : %02X\n", 
+DEVICE_NAME,
                       int_ret_code);
                outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
                ending = FAIL;
@@ -940,8 +914,7 @@
                for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); 
i--);
                if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
                        printk("%s: timeout reading status word\n", DEVICE_NAME);
-                       outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-                       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+                       ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                        if ((++CURRENT->errors) >= MAX_RETRIES)
                                ending = FAIL;
                        else
@@ -953,8 +926,7 @@
                case (CMD_READ & 0xff):
                case (CMD_WRITE & 0xff):
                        LITE_OFF;
-                       outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-                       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+                       ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 #if 0
                        printk("ps2esdi: cmd_complete b_wait: %p\n", 
&CURRENT->bh->b_wait);
 #endif
@@ -963,8 +935,7 @@
                default:
                        printk("%s: interrupt for unknown command %02X\n",
                               DEVICE_NAME, status & 0x1f);
-                       outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-                       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+                       ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                        ending = -1;
                        break;
                }
@@ -974,8 +945,7 @@
        case INT_CMD_ECC_RETRY:
                LITE_OFF;
                dump_cmd_complete_status(int_ret_code);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                ending = SUCCES;
                break;
        case INT_CMD_WARNING:
@@ -984,8 +954,7 @@
        case INT_DMA_ERR:
                LITE_OFF;
                dump_cmd_complete_status(int_ret_code);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                if ((++CURRENT->errors) >= MAX_RETRIES)
                        ending = FAIL;
                else
@@ -994,31 +963,27 @@
 
        case INT_CMD_BLK_ERR:
                dump_cmd_complete_status(int_ret_code);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                ending = FAIL;
                break;
 
        case INT_CMD_FORMAT:
                printk("%s: huh ? Who issued this format command ?\n"
                       ,DEVICE_NAME);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                ending = -1;
                break;
 
        case INT_RESET:
                /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                ending = -1;
                break;
 
        default:
                printk("%s: Unknown interrupt reason: %02X\n",
                       DEVICE_NAME, int_ret_code & 0xf);
-               outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+               ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
                ending = -1;
                break;
        }
@@ -1125,8 +1090,7 @@
        int dev = DEVICE_NR(inode->i_rdev);
 
        if (dev < ps2esdi_drives) {
-               while (!ps2esdi_valid[dev])
-                       sleep_on(&ps2esdi_wait_open);
+               wait_event(ps2esdi_wait_open, ps2esdi_valid[dev]);
 
                access_count[dev]++;
 
@@ -1236,11 +1200,34 @@
 
        status = inb(ESDI_INTRPT);
        if ((status & 0xf) == INT_RESET) {
-               outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
-               outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-               reset_status = 1;
+               ps2esdi_attention((status & 0xe0) >> 5, ATT_EOI);
+               reset_status = -1;
        }
        wake_up(&ps2esdi_int);
 }
 
+static int ps2esdi_attention(u_int device, u_int request)
+{
+       int busy;
+       u_char status;
+
+       outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
+       if(request == ATT_EOI || !(status = inb(ESDI_STATUS) & 0x50)) {
+               outb((device << 5) | request, ESDI_ATTN);
+               busy = 0;
+       }
+       else {
+               if(status & 0x10) {
+                       printk("%s: Attention port in use (0x%x)\n",
+                               DEVICE_NAME, status);
+               }
+               if(status & 0x40) {
+                       printk("%s: Interrupt pending (0x%x)\n",
+                               DEVICE_NAME, status);
+               }
+               busy = 1;
+       }
+       outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+       return busy;
+}
 #endif

Reply via email to