Made timeout and no. of errors in at_wini dynamically settable

by ioctl; made catch-all function in driver table also called when
unrecognized ioctl called, so drivers can add their own ioctl codes.
This commit is contained in:
Ben Gras 2005-07-13 14:58:21 +00:00
parent f96645a4eb
commit c389801a5f
3 changed files with 62 additions and 15 deletions

View file

@ -16,6 +16,7 @@
#include "at_wini.h" #include "at_wini.h"
#include <minix/utils.h> #include <minix/utils.h>
#include <minix/keymap.h> #include <minix/keymap.h>
#include <sys/ioc_disk.h>
#if ENABLE_AT_WINI #if ENABLE_AT_WINI
@ -140,6 +141,8 @@ struct command {
/* Some controllers don't interrupt, the clock will wake us up. */ /* Some controllers don't interrupt, the clock will wake us up. */
#define WAKEUP (32*HZ) /* drive may be out for 31 seconds max */ #define WAKEUP (32*HZ) /* drive may be out for 31 seconds max */
int wakeup_ticks = WAKEUP;
/* Miscellaneous. */ /* Miscellaneous. */
#define MAX_DRIVES 4 /* this driver supports 4 drives (d0 - d3) */ #define MAX_DRIVES 4 /* this driver supports 4 drives (d0 - d3) */
#if _WORD_SIZE > 2 #if _WORD_SIZE > 2
@ -153,8 +156,7 @@ struct command {
#define NR_SUBDEVS (MAX_DRIVES * SUB_PER_DRIVE) #define NR_SUBDEVS (MAX_DRIVES * SUB_PER_DRIVE)
#define DELAY_USECS 1000 /* controller timeout in microseconds */ #define DELAY_USECS 1000 /* controller timeout in microseconds */
#define DELAY_TICKS 1 /* controller timeout in ticks */ #define DELAY_TICKS 1 /* controller timeout in ticks */
#define TIMEOUT_USECS 5000000 /* controller timeout in microseconds */ #define DEF_TIMEOUT_TICKS 300 /* controller timeout in ticks */
#define TIMEOUT_TICKS 300 /* controller timeout in ticks */
#define RECOVERY_USECS 500000 /* controller recovery time in microseconds */ #define RECOVERY_USECS 500000 /* controller recovery time in microseconds */
#define RECOVERY_TICKS 30 /* controller recovery time in ticks */ #define RECOVERY_TICKS 30 /* controller recovery time in ticks */
#define INITIALIZED 0x01 /* drive is initialized */ #define INITIALIZED 0x01 /* drive is initialized */
@ -166,6 +168,7 @@ struct command {
#define ATAPI 0 /* don't bother with ATAPI; optimise out */ #define ATAPI 0 /* don't bother with ATAPI; optimise out */
#endif #endif
int timeout_ticks = DEF_TIMEOUT_TICKS, max_errors = MAX_ERRORS;
/* Variables. */ /* Variables. */
PRIVATE struct wini { /* main drive struct, one entry per drive */ 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( int com_out, (struct command *cmd) );
FORWARD _PROTOTYPE( void w_need_reset, (void) ); FORWARD _PROTOTYPE( void w_need_reset, (void) );
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) ); 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( int com_simple, (struct command *cmd) );
FORWARD _PROTOTYPE( void w_timeout, (void) ); FORWARD _PROTOTYPE( void w_timeout, (void) );
FORWARD _PROTOTYPE( int w_reset, (void) ); FORWARD _PROTOTYPE( int w_reset, (void) );
@ -237,7 +241,7 @@ PRIVATE struct driver w_dtab = {
nop_fkey, nop_fkey,
nop_cancel, nop_cancel,
nop_select, 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? */ /* Any errors? */
if (r != OK) { if (r != OK) {
/* Don't retry if sector marked bad or too many errors. */ /* 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; w_command = CMD_IDLE;
return(EIO); return(EIO);
} }
@ -685,7 +689,7 @@ struct command *cmd; /* Command block */
* controller was not able to execute the command. Leftover timeouts are * controller was not able to execute the command. Leftover timeouts are
* simply ignored by the main loop. * simply ignored by the main loop.
*/ */
sys_syncalrm(SELF, WAKEUP, 0); sys_syncalrm(SELF, wakeup_ticks, 0);
w_status = STATUS_ADMBSY; w_status = STATUS_ADMBSY;
w_command = cmd->command; w_command = cmd->command;
@ -894,7 +898,7 @@ int value; /* required status */
if ((w_status & mask) == value) { if ((w_status & mask) == value) {
return 1; 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); if (OK != s) printf("AT_WINI: warning, get_uptime failed: %d\n",s);
w_need_reset(); /* controller gone deaf */ w_need_reset(); /* controller gone deaf */
@ -1064,7 +1068,7 @@ unsigned nr_req; /* length of request vector */
if (r < 0) { if (r < 0) {
err: /* Don't retry if too many errors. */ err: /* Don't retry if too many errors. */
if (++errors == MAX_ERRORS) { if (++errors == max_errors) {
w_command = CMD_IDLE; w_command = CMD_IDLE;
return(EIO); return(EIO);
} }
@ -1103,7 +1107,7 @@ unsigned cnt;
* controller was not able to execute the command. Leftover timeouts are * controller was not able to execute the command. Leftover timeouts are
* simply ignored by the main loop. * simply ignored by the main loop.
*/ */
sys_syncalrm(SELF, WAKEUP, 0); sys_syncalrm(SELF, wakeup_ticks, 0);
#if _WORD_SIZE > 2 #if _WORD_SIZE > 2
if (cnt > 0xFFFE) cnt = 0xFFFE; /* Max data per interrupt. */ if (cnt > 0xFFFE) cnt = 0xFFFE; /* Max data per interrupt. */
@ -1131,6 +1135,39 @@ unsigned cnt;
return(OK); 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 * * atapi_intr_wait *
*============================================================================*/ *============================================================================*/

View file

@ -375,7 +375,11 @@ message *mp; /* pointer to ioctl request */
struct partition entry; struct partition entry;
int s; 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. */ /* Decode the message parameters. */
if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NIL_DEV) return(ENXIO); if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NIL_DEV) return(ENXIO);

View file

@ -14,7 +14,7 @@
FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev, FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
unsigned long extbase) ); unsigned long extbase) );
FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device, 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, FORWARD _PROTOTYPE( int get_iso_fake_part_table, (struct driver *dp, int device,
unsigned long offset, struct part_entry *table) ); unsigned long offset, struct part_entry *table) );
FORWARD _PROTOTYPE( void sort, (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. * systems that expect this.
*/ */
struct part_entry table[NR_PARTITIONS], *pe; struct part_entry table[NR_PARTITIONS], *pe;
int disk, par; int disk, par, io;
struct device *dv; struct device *dv;
unsigned long base, limit, part_limit; 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); limit = base + div64u(dv->dv_size, SECTOR_SIZE);
/* Read the partition table for the device. */ /* Read the partition table for the device. */
if (!get_part_table(dp, device, 0L, table)) if (!get_part_table(dp, device, 0L, table, &io))
if(!get_iso_fake_part_table(dp, device, 0L, table)) if(!io || !get_iso_fake_part_table(dp, device, 0L, table))
return; return;
/* Compute the device number of the first partition. */ /* Compute the device number of the first partition. */
@ -116,7 +116,7 @@ unsigned long extbase; /* sector offset of the base extended partition */
offset = 0; offset = 0;
do { do {
if (!get_part_table(dp, extdev, offset, table)) return; if (!get_part_table(dp, extdev, offset, table, NULL)) return;
sort(table); sort(table);
/* The table should contain one logical partition and optionally /* 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 * * 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; struct driver *dp;
int device; int device;
unsigned long offset; /* sector offset to the table */ unsigned long offset; /* sector offset to the table */
struct part_entry *table; /* four entries */ struct part_entry *table; /* four entries */
int *io_ok;
{ {
/* Read the partition table for the device, return true iff there were no /* Read the partition table for the device, return true iff there were no
* errors. * errors.
@ -159,6 +160,9 @@ struct part_entry *table; /* four entries */
off_t position; off_t position;
int s; int s;
if(io_ok)
*io_ok = 0;
position = offset << SECTOR_SHIFT; position = offset << SECTOR_SHIFT;
iovec1.iov_addr = (vir_bytes) tmp_buf; iovec1.iov_addr = (vir_bytes) tmp_buf;
iovec1.iov_size = SECTOR_SIZE; 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)()); printf("%s: can't read partition table\n", (*dp->dr_name)());
return 0; return 0;
} }
if(io_ok)
*io_ok = 1;
if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) { if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
/* Invalid partition table. */ /* Invalid partition table. */
return 0; return 0;