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 <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 *
*============================================================================*/

View 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);

View 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;