]> Zhao Yanbai Git Server - minix.git/commitdiff
Made timeout and no. of errors in at_wini dynamically settable
authorBen Gras <ben@minix3.org>
Wed, 13 Jul 2005 14:58:21 +0000 (14:58 +0000)
committerBen Gras <ben@minix3.org>
Wed, 13 Jul 2005 14:58:21 +0000 (14:58 +0000)
by ioctl; made catch-all function in driver table also called when
unrecognized ioctl called, so drivers can add their own ioctl codes.

drivers/at_wini/at_wini.c
drivers/libdriver/driver.c
drivers/libdriver/drvlib.c

index f108cb959e7c73994d3ee891d1a5f03aec758d92..78d077229efd32935709ecb5fad8643ae29012f8 100644 (file)
@@ -16,6 +16,7 @@
 #include "at_wini.h"
 #include <minix/utils.h>
 #include <minix/keymap.h>
+#include <sys/ioc_disk.h>
 
 #if ENABLE_AT_WINI
 
@@ -140,6 +141,8 @@ struct command {
 /* Some controllers don't interrupt, the clock will wake us up. */
 #define WAKEUP         (32*HZ) /* drive may be out for 31 seconds max */
 
+int wakeup_ticks = WAKEUP;
+
 /* Miscellaneous. */
 #define MAX_DRIVES         4   /* this driver supports 4 drives (d0 - d3) */
 #if _WORD_SIZE > 2
@@ -153,8 +156,7 @@ struct command {
 #define NR_SUBDEVS     (MAX_DRIVES * SUB_PER_DRIVE)
 #define DELAY_USECS     1000   /* controller timeout in microseconds */
 #define DELAY_TICKS    1       /* controller timeout in ticks */
-#define TIMEOUT_USECS   5000000        /* controller timeout in microseconds */
-#define TIMEOUT_TICKS  300     /* controller timeout in ticks */
+#define DEF_TIMEOUT_TICKS      300     /* controller timeout in ticks */
 #define RECOVERY_USECS  500000 /* controller recovery time in microseconds */
 #define RECOVERY_TICKS  30     /* controller recovery time in ticks */
 #define INITIALIZED    0x01    /* drive is initialized */
@@ -166,6 +168,7 @@ struct command {
 #define ATAPI             0    /* don't bother with ATAPI; optimise out */
 #endif
 
+int timeout_ticks = DEF_TIMEOUT_TICKS, max_errors = MAX_ERRORS;
 
 /* Variables. */
 PRIVATE struct wini {          /* main drive struct, one entry per drive */
@@ -205,6 +208,7 @@ FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, off_t position,
 FORWARD _PROTOTYPE( int com_out, (struct command *cmd) );
 FORWARD _PROTOTYPE( void w_need_reset, (void) );
 FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
+FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr) );
 FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) );
 FORWARD _PROTOTYPE( void w_timeout, (void) );
 FORWARD _PROTOTYPE( int w_reset, (void) );
@@ -237,7 +241,7 @@ PRIVATE struct driver w_dtab = {
   nop_fkey,            
   nop_cancel,
   nop_select,
-  NULL
+  w_other              /* catch-all for unrecognized commands and ioctls */
 };
 
 
@@ -640,7 +644,7 @@ unsigned nr_req;            /* length of request vector */
        /* Any errors? */
        if (r != OK) {
                /* Don't retry if sector marked bad or too many errors. */
-               if (r == ERR_BAD_SECTOR || ++errors == MAX_ERRORS) {
+               if (r == ERR_BAD_SECTOR || ++errors == max_errors) {
                        w_command = CMD_IDLE;
                        return(EIO);
                }
@@ -685,7 +689,7 @@ struct command *cmd;                /* Command block */
    * controller was not able to execute the command. Leftover timeouts are
    * simply ignored by the main loop. 
    */
-  sys_syncalrm(SELF, WAKEUP, 0);
+  sys_syncalrm(SELF, wakeup_ticks, 0);
 
   w_status = STATUS_ADMBSY;
   w_command = cmd->command;
@@ -894,7 +898,7 @@ int value;                  /* required status */
        if ((w_status & mask) == value) {
                return 1;
        }
-  } while ((s=getuptime(&t1)) == OK && (t1-t0) < TIMEOUT_TICKS );
+  } while ((s=getuptime(&t1)) == OK && (t1-t0) < timeout_ticks );
   if (OK != s) printf("AT_WINI: warning, get_uptime failed: %d\n",s);
 
   w_need_reset();                      /* controller gone deaf */
@@ -1064,7 +1068,7 @@ unsigned nr_req;          /* length of request vector */
 
        if (r < 0) {
   err:         /* Don't retry if too many errors. */
-               if (++errors == MAX_ERRORS) {
+               if (++errors == max_errors) {
                        w_command = CMD_IDLE;
                        return(EIO);
                }
@@ -1103,7 +1107,7 @@ unsigned cnt;
    * controller was not able to execute the command. Leftover timeouts are
    * simply ignored by the main loop. 
    */
-  sys_syncalrm(SELF, WAKEUP, 0);
+  sys_syncalrm(SELF, wakeup_ticks, 0);
 
 #if _WORD_SIZE > 2
   if (cnt > 0xFFFE) cnt = 0xFFFE;      /* Max data per interrupt. */
@@ -1131,6 +1135,39 @@ unsigned cnt;
   return(OK);
 }
 
+/*============================================================================*
+ *                             w_other                                       *
+ *============================================================================*/
+PRIVATE int w_other(dr, m)
+struct driver *dr;
+message *m;
+{
+       int r, timeout, prev;
+
+       if(m->m_type != DEV_IOCTL || m->REQUEST != DIOCTIMEOUT)
+               return EINVAL;
+
+       if((r=sys_datacopy(m->PROC_NR, (vir_bytes)m->ADDRESS,
+               SELF, (vir_bytes)&timeout, sizeof(timeout))) != OK)
+               return r;
+
+       if(timeout < 1)
+               return EINVAL;
+
+       prev = wakeup_ticks;
+       wakeup_ticks = timeout;
+       if(timeout_ticks > timeout)
+               timeout_ticks = timeout;
+
+       if((r=sys_datacopy(SELF, (vir_bytes)&prev, 
+               m->PROC_NR, (vir_bytes)m->ADDRESS, sizeof(prev))) != OK)
+               return r;
+
+       max_errors = 2;
+
+       return OK;
+}
+
 /*============================================================================*
  *                             atapi_intr_wait                               *
  *============================================================================*/
index adedb0a27da05796e2c86e5a00c91ad6c11696d2..bfd360e62d019bea910831b066989bbb33354428 100644 (file)
@@ -375,7 +375,11 @@ message *mp;                       /* pointer to ioctl request */
   struct partition entry;
   int s;
 
-  if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) return(ENOTTY);
+  if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) {
+       if(dp->dr_other) {
+               return dp->dr_other(dp, mp);
+       } else return(ENOTTY);
+  }
 
   /* Decode the message parameters. */
   if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NIL_DEV) return(ENXIO);
index b5fef949d0ab1002820a0f466743b1e1c1ea0b81..82b68f6ecdb03b4f547b88f141bc97ddaa24d0f7 100644 (file)
@@ -14,7 +14,7 @@
 FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
                                                unsigned long extbase) );
 FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
-                       unsigned long offset, struct part_entry *table) );
+                       unsigned long offset, struct part_entry *table, int *io) );
 FORWARD _PROTOTYPE( int get_iso_fake_part_table, (struct driver *dp, int device,
                        unsigned long offset, struct part_entry *table) );
 FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
@@ -36,7 +36,7 @@ int style;            /* partitioning style: floppy, primary, sub. */
  * systems that expect this.
  */
   struct part_entry table[NR_PARTITIONS], *pe;
-  int disk, par;
+  int disk, par, io;
   struct device *dv;
   unsigned long base, limit, part_limit;
 
@@ -47,8 +47,8 @@ int style;            /* partitioning style: floppy, primary, sub. */
   limit = base + div64u(dv->dv_size, SECTOR_SIZE);
 
   /* Read the partition table for the device. */
-  if (!get_part_table(dp, device, 0L, table))
-         if(!get_iso_fake_part_table(dp, device, 0L, table))
+  if (!get_part_table(dp, device, 0L, table, &io))
+         if(!io || !get_iso_fake_part_table(dp, device, 0L, table))
                return;
 
   /* Compute the device number of the first partition. */
@@ -116,7 +116,7 @@ unsigned long extbase;      /* sector offset of the base extended partition */
 
   offset = 0;
   do {
-       if (!get_part_table(dp, extdev, offset, table)) return;
+       if (!get_part_table(dp, extdev, offset, table, NULL)) return;
        sort(table);
 
        /* The table should contain one logical partition and optionally
@@ -146,11 +146,12 @@ unsigned long extbase;    /* sector offset of the base extended partition */
 /*============================================================================*
  *                             get_part_table                                *
  *============================================================================*/
-PRIVATE int get_part_table(dp, device, offset, table)
+PRIVATE int get_part_table(dp, device, offset, table, io_ok)
 struct driver *dp;
 int device;
 unsigned long offset;          /* sector offset to the table */
 struct part_entry *table;      /* four entries */
+int *io_ok;
 {
 /* Read the partition table for the device, return true iff there were no
  * errors.
@@ -159,6 +160,9 @@ struct part_entry *table;   /* four entries */
   off_t position;
   int s;
 
+  if(io_ok)
+       *io_ok = 0;
+
   position = offset << SECTOR_SHIFT;
   iovec1.iov_addr = (vir_bytes) tmp_buf;
   iovec1.iov_size = SECTOR_SIZE;
@@ -169,6 +173,8 @@ struct part_entry *table;   /* four entries */
        printf("%s: can't read partition table\n", (*dp->dr_name)());
        return 0;
   }
+  if(io_ok)
+       *io_ok = 1;
   if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
        /* Invalid partition table. */
        return 0;