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 <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 *
|
||||
*============================================================================*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue