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:
parent
f96645a4eb
commit
c389801a5f
3 changed files with 62 additions and 15 deletions
|
@ -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 *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue