2005-04-21 16:53:53 +02:00
|
|
|
/* This file contains the device dependent part of a driver for the IBM-AT
|
|
|
|
* winchester controller. Written by Adri Koppes.
|
|
|
|
*
|
|
|
|
* The file contains one entry point:
|
|
|
|
*
|
|
|
|
* at_winchester_task: main entry when system is brought up
|
|
|
|
*
|
|
|
|
* Changes:
|
2005-10-20 22:26:02 +02:00
|
|
|
* Aug 19, 2005 ATA PCI support, supports SATA (Ben Gras)
|
2005-04-21 16:53:53 +02:00
|
|
|
* Nov 18, 2004 moved AT disk driver to user-space (Jorrit N. Herder)
|
|
|
|
* Aug 20, 2004 watchdogs replaced by sync alarms (Jorrit N. Herder)
|
|
|
|
* Mar 23, 2000 added ATAPI CDROM support (Michael Temari)
|
|
|
|
* May 14, 2000 d-d/i rewrite (Kees J. Bot)
|
|
|
|
* Apr 13, 1992 device dependent/independent split (Kees J. Bot)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "at_wini.h"
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2005-07-19 15:21:51 +02:00
|
|
|
#include <minix/sysutil.h>
|
2008-11-19 13:26:10 +01:00
|
|
|
#include <minix/type.h>
|
2009-09-29 20:47:56 +02:00
|
|
|
#include <minix/endpoint.h>
|
2005-07-13 16:58:21 +02:00
|
|
|
#include <sys/ioc_disk.h>
|
2010-03-08 12:04:59 +01:00
|
|
|
#include <machine/pci.h>
|
2008-11-19 13:26:10 +01:00
|
|
|
#include <sys/mman.h>
|
2010-04-08 15:41:35 +02:00
|
|
|
#include <sys/svrctl.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
/* Variables. */
|
2005-08-26 21:39:00 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Common command block */
|
|
|
|
struct command {
|
|
|
|
u8_t precomp; /* REG_PRECOMP, etc. */
|
|
|
|
u8_t count;
|
|
|
|
u8_t sector;
|
|
|
|
u8_t cyl_lo;
|
|
|
|
u8_t cyl_hi;
|
|
|
|
u8_t ldh;
|
|
|
|
u8_t command;
|
2006-02-24 13:55:47 +01:00
|
|
|
|
|
|
|
/* The following at for LBA48 */
|
|
|
|
u8_t count_prev;
|
|
|
|
u8_t sector_prev;
|
|
|
|
u8_t cyl_lo_prev;
|
|
|
|
u8_t cyl_hi_prev;
|
2005-04-21 16:53:53 +02:00
|
|
|
};
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
/* Timeouts and max retries. */
|
2010-07-13 01:14:40 +02:00
|
|
|
PRIVATE int timeout_usecs = DEF_TIMEOUT_USECS;
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE int max_errors = MAX_ERRORS;
|
|
|
|
PRIVATE long w_standard_timeouts = 0;
|
|
|
|
PRIVATE long w_pci_debug = 0;
|
|
|
|
PRIVATE long w_instance = 0;
|
|
|
|
PRIVATE long disable_dma = 0;
|
|
|
|
PRIVATE long atapi_debug = 0;
|
|
|
|
PRIVATE long w_identify_wakeup_ticks;
|
|
|
|
PRIVATE long wakeup_ticks;
|
|
|
|
PRIVATE long w_atapi_dma;
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE int w_testing = 0;
|
|
|
|
PRIVATE int w_silent = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE int w_next_drive = 0;
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE u32_t system_hz;
|
2009-12-02 10:57:48 +01:00
|
|
|
|
2005-10-20 22:26:02 +02:00
|
|
|
/* The struct wini is indexed by controller first, then drive (0-3).
|
|
|
|
* Controller 0 is always the 'compatability' ide controller, at
|
2005-08-25 10:19:11 +02:00
|
|
|
* the fixed locations, whether present or not.
|
|
|
|
*/
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE struct wini { /* main drive struct, one entry per drive */
|
|
|
|
unsigned state; /* drive state: deaf, initialized, dead */
|
2006-02-24 13:55:47 +01:00
|
|
|
unsigned short w_status; /* device status register */
|
2005-08-25 18:25:19 +02:00
|
|
|
unsigned base_cmd; /* command base register */
|
|
|
|
unsigned base_ctl; /* control base register */
|
2006-03-03 16:37:51 +01:00
|
|
|
unsigned base_dma; /* dma base register */
|
2009-10-19 16:23:04 +02:00
|
|
|
int dma_intseen;
|
2005-04-21 16:53:53 +02:00
|
|
|
unsigned irq; /* interrupt request line */
|
2005-08-25 10:19:11 +02:00
|
|
|
unsigned irq_need_ack; /* irq needs to be acknowledged */
|
2005-05-02 16:30:04 +02:00
|
|
|
int irq_hook_id; /* id of irq hook at the kernel */
|
2005-08-25 18:25:19 +02:00
|
|
|
int lba48; /* supports lba48 */
|
2006-03-03 16:37:51 +01:00
|
|
|
int dma; /* supports dma */
|
2005-04-21 16:53:53 +02:00
|
|
|
unsigned lcylinders; /* logical number of cylinders (BIOS) */
|
|
|
|
unsigned lheads; /* logical number of heads */
|
|
|
|
unsigned lsectors; /* logical number of sectors per track */
|
|
|
|
unsigned pcylinders; /* physical number of cylinders (translated) */
|
|
|
|
unsigned pheads; /* physical number of heads */
|
|
|
|
unsigned psectors; /* physical number of sectors per track */
|
|
|
|
unsigned ldhpref; /* top four bytes of the LDH (head) register */
|
|
|
|
unsigned precomp; /* write precompensation cylinder / 4 */
|
|
|
|
unsigned max_count; /* max request for this drive */
|
|
|
|
unsigned open_ct; /* in-use count */
|
|
|
|
struct device part[DEV_PER_DRIVE]; /* disks and partitions */
|
|
|
|
struct device subpart[SUB_PER_DRIVE]; /* subpartitions */
|
|
|
|
} wini[MAX_DRIVES], *w_wn;
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
PRIVATE int w_device = -1;
|
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
PUBLIC int w_command; /* current command in execution */
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int w_drive; /* selected drive */
|
|
|
|
PRIVATE struct device *w_dv; /* device's base and size */
|
|
|
|
|
2011-11-02 17:31:38 +01:00
|
|
|
PRIVATE u8_t *tmp_buf;
|
|
|
|
|
2006-03-06 11:42:51 +01:00
|
|
|
#define ATA_DMA_SECTORS 64
|
|
|
|
#define ATA_DMA_BUF_SIZE (ATA_DMA_SECTORS*SECTOR_SIZE)
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
PRIVATE char *dma_buf;
|
2006-03-03 16:37:51 +01:00
|
|
|
PRIVATE phys_bytes dma_buf_phys;
|
|
|
|
|
|
|
|
#define N_PRDTE 1024 /* Should be enough for large requests */
|
|
|
|
|
2010-08-24 14:45:37 +02:00
|
|
|
struct prdte
|
2006-03-03 16:37:51 +01:00
|
|
|
{
|
2010-03-30 16:07:15 +02:00
|
|
|
phys_bytes prdte_base;
|
2006-03-03 16:37:51 +01:00
|
|
|
u16_t prdte_count;
|
|
|
|
u8_t prdte_reserved;
|
|
|
|
u8_t prdte_flags;
|
2008-11-19 13:26:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#define PRDT_BYTES (sizeof(struct prdte) * N_PRDTE)
|
|
|
|
PRIVATE struct prdte *prdt;
|
2006-03-03 16:37:51 +01:00
|
|
|
PRIVATE phys_bytes prdt_phys;
|
|
|
|
|
|
|
|
#define PRDTE_FL_EOT 0x80 /* End of table */
|
|
|
|
|
2010-04-28 13:52:28 +02:00
|
|
|
/* IDE devices we trust are IDE devices. */
|
|
|
|
PRIVATE struct quirk
|
2006-04-04 14:27:28 +02:00
|
|
|
{
|
2010-04-28 13:52:28 +02:00
|
|
|
int pci_class, pci_subclass, pci_interface;
|
2006-04-04 14:27:28 +02:00
|
|
|
u16_t vendor;
|
|
|
|
u16_t device;
|
2010-04-28 13:52:28 +02:00
|
|
|
} quirk_table[]=
|
2006-04-04 14:27:28 +02:00
|
|
|
{
|
2010-04-28 13:52:28 +02:00
|
|
|
{ 0x01, 0x04, 0x00, 0x1106, 0x3149 }, /* VIA VT6420 */
|
|
|
|
{ 0x01, 0x04, 0x00, 0x1095, 0x3512 },
|
|
|
|
{ 0x01, 0x80, -1, 0x1095, 0x3114 }, /* Silicon Image SATA */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
{ 0, 0, 0, 0, 0 } /* end of list */
|
2006-04-04 14:27:28 +02:00
|
|
|
};
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( void init_params, (void) );
|
2006-03-03 16:37:51 +01:00
|
|
|
FORWARD _PROTOTYPE( void init_drive, (struct wini *w, int base_cmd,
|
|
|
|
int base_ctl, int base_dma, int irq, int ack, int hook,
|
|
|
|
int drive) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( void init_params_pci, (int) );
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( int w_do_open, (dev_t minor, int access) );
|
|
|
|
FORWARD _PROTOTYPE( struct device *w_prepare, (dev_t dev) );
|
|
|
|
FORWARD _PROTOTYPE( struct device *w_part, (dev_t minor) );
|
2007-02-09 16:58:33 +01:00
|
|
|
FORWARD _PROTOTYPE( int w_identify, (void) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( char *w_name, (void) );
|
|
|
|
FORWARD _PROTOTYPE( int w_specify, (void) );
|
|
|
|
FORWARD _PROTOTYPE( int w_io_test, (void) );
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( ssize_t w_transfer, (dev_t minor, int do_write,
|
|
|
|
u64_t position, endpoint_t proc_nr, iovec_t *iov,
|
|
|
|
unsigned int nr_req, int flags) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( int com_out, (struct command *cmd) );
|
2006-02-24 13:55:47 +01:00
|
|
|
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) );
|
2011-06-08 21:24:41 +02:00
|
|
|
FORWARD _PROTOTYPE( int setup_dma, (unsigned *sizep, endpoint_t proc_nr,
|
|
|
|
iovec_t *iov, size_t addr_offset, int do_write) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( void w_need_reset, (void) );
|
|
|
|
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) );
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( int w_do_close, (dev_t minor) );
|
|
|
|
FORWARD _PROTOTYPE( int w_ioctl, (dev_t minor, unsigned int request,
|
|
|
|
endpoint_t endpt, cp_grant_id_t grant) );
|
|
|
|
FORWARD _PROTOTYPE( void w_hw_int, (unsigned int irqs) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) );
|
|
|
|
FORWARD _PROTOTYPE( void w_timeout, (void) );
|
|
|
|
FORWARD _PROTOTYPE( int w_reset, (void) );
|
|
|
|
FORWARD _PROTOTYPE( void w_intr_wait, (void) );
|
|
|
|
FORWARD _PROTOTYPE( int at_intr_wait, (void) );
|
|
|
|
FORWARD _PROTOTYPE( int w_waitfor, (int mask, int value) );
|
2006-03-03 16:37:51 +01:00
|
|
|
FORWARD _PROTOTYPE( int w_waitfor_dma, (int mask, int value) );
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( void w_geometry, (dev_t minor,
|
|
|
|
struct partition *entry) );
|
2005-04-21 16:53:53 +02:00
|
|
|
#if ENABLE_ATAPI
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( int atapi_sendpacket, (u8_t *packet, unsigned cnt,
|
|
|
|
int do_dma) );
|
2009-10-19 17:45:14 +02:00
|
|
|
FORWARD _PROTOTYPE( int atapi_intr_wait, (int dma, size_t max) );
|
2005-09-11 19:09:11 +02:00
|
|
|
FORWARD _PROTOTYPE( int atapi_open, (void) );
|
|
|
|
FORWARD _PROTOTYPE( void atapi_close, (void) );
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
FORWARD _PROTOTYPE( int atapi_transfer, (int do_write, u64_t position,
|
|
|
|
endpoint_t endpt, iovec_t *iov, unsigned int nr_req) );
|
2005-04-21 16:53:53 +02:00
|
|
|
#endif
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
#define sys_voutb(out, n) at_voutb((out), (n))
|
|
|
|
FORWARD _PROTOTYPE( int at_voutb, (pvb_pair_t *, int n));
|
|
|
|
#define sys_vinb(in, n) at_vinb((in), (n))
|
|
|
|
FORWARD _PROTOTYPE( int at_vinb, (pvb_pair_t *, int n));
|
2007-02-23 19:21:19 +01:00
|
|
|
|
|
|
|
#undef sys_outb
|
|
|
|
#undef sys_inb
|
|
|
|
#undef sys_outl
|
|
|
|
|
2012-03-05 00:11:41 +01:00
|
|
|
FORWARD _PROTOTYPE( int at_out, (int line, u32_t port, u32_t value,
|
2007-02-23 19:21:19 +01:00
|
|
|
char *typename, int type));
|
2012-03-05 00:11:41 +01:00
|
|
|
FORWARD _PROTOTYPE( int at_in, (int line, u32_t port, u32_t *value,
|
2007-02-23 19:21:19 +01:00
|
|
|
char *typename, int type));
|
|
|
|
|
|
|
|
#define sys_outb(p, v) at_out(__LINE__, (p), (v), "outb", _DIO_BYTE)
|
|
|
|
#define sys_inb(p, v) at_in(__LINE__, (p), (v), "inb", _DIO_BYTE)
|
|
|
|
#define sys_outl(p, v) at_out(__LINE__, (p), (v), "outl", _DIO_LONG)
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Entry points to this driver. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE struct blockdriver w_dtab = {
|
2011-11-25 14:56:46 +01:00
|
|
|
BLOCKDRIVER_TYPE_DISK,/* handle partition requests */
|
2005-04-21 16:53:53 +02:00
|
|
|
w_do_open, /* open or mount request, initialize device */
|
|
|
|
w_do_close, /* release device */
|
|
|
|
w_transfer, /* do the I/O */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
w_ioctl, /* I/O control requests */
|
|
|
|
NULL, /* nothing to clean up */
|
|
|
|
w_part, /* return partition information */
|
2005-04-21 16:53:53 +02:00
|
|
|
w_geometry, /* tell the geometry of the disk */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
w_hw_int, /* leftover hardware interrupts */
|
|
|
|
NULL, /* ignore leftover alarms */
|
|
|
|
NULL, /* ignore unrecognized messages */
|
|
|
|
NULL /* no multithreading support */
|
2005-04-21 16:53:53 +02:00
|
|
|
};
|
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
/* SEF functions and variables. */
|
|
|
|
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
|
New RS and new signal handling for system processes.
UPDATING INFO:
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.
PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.
SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.
VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().
RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.
DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.
DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
2010-03-17 02:15:29 +01:00
|
|
|
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
|
|
|
|
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* at_winchester_task *
|
|
|
|
*===========================================================================*/
|
2007-02-08 15:23:03 +01:00
|
|
|
PUBLIC int main(int argc, char *argv[])
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
/* SEF local startup. */
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
env_setargs(argc, argv);
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
sef_local_startup();
|
|
|
|
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
/* Call the generic receive loop. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
blockdriver_task(&w_dtab);
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
|
2005-08-25 15:14:02 +02:00
|
|
|
return(OK);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* sef_local_startup *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void sef_local_startup(void)
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
{
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
/* Register init callbacks. */
|
|
|
|
sef_setcb_init_fresh(sef_cb_init_fresh);
|
|
|
|
sef_setcb_init_lu(sef_cb_init_fresh);
|
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
/* Register live update callbacks. */
|
|
|
|
sef_setcb_lu_prepare(sef_cb_lu_prepare);
|
|
|
|
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
|
|
|
|
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
|
|
|
|
|
|
|
|
/* Let SEF perform startup. */
|
|
|
|
sef_startup();
|
|
|
|
}
|
|
|
|
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* sef_cb_init_fresh *
|
|
|
|
*===========================================================================*/
|
2011-12-11 22:36:19 +01:00
|
|
|
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
{
|
|
|
|
/* Initialize the at_wini driver. */
|
|
|
|
system_hz = sys_hz();
|
|
|
|
|
2011-11-02 17:31:38 +01:00
|
|
|
if (!(tmp_buf = alloc_contig(2*DMA_BUF_SIZE, AC_ALIGN4K, NULL)))
|
|
|
|
panic("unable to allocate temporary buffer");
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
|
|
|
|
w_identify_wakeup_ticks = WAKEUP_TICKS;
|
|
|
|
wakeup_ticks = WAKEUP_TICKS;
|
|
|
|
|
|
|
|
/* Set special disk parameters. */
|
|
|
|
init_params();
|
|
|
|
|
2010-04-08 15:41:35 +02:00
|
|
|
/* Announce we are up! */
|
2011-12-11 22:36:19 +01:00
|
|
|
blockdriver_announce(type);
|
2010-04-08 15:41:35 +02:00
|
|
|
|
Initialization protocol for system services.
SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.
SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic
registration / deregistration of system services.
VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.
RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
2010-01-08 02:20:42 +01:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* init_params *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void init_params(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* This routine is called at startup to initialize the drive parameters. */
|
|
|
|
|
|
|
|
u16_t parv[2];
|
|
|
|
unsigned int vector, size;
|
|
|
|
int drive, nr_drives;
|
|
|
|
struct wini *wn;
|
|
|
|
u8_t params[16];
|
2005-08-25 15:14:02 +02:00
|
|
|
int s;
|
2007-02-16 16:56:00 +01:00
|
|
|
long wakeup_secs = WAKEUP_SECS;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Boot variables. */
|
2010-07-03 19:51:12 +02:00
|
|
|
env_parse("instance", "d", 0, &w_instance, 0, 8);
|
2005-08-25 10:19:11 +02:00
|
|
|
env_parse("ata_std_timeout", "d", 0, &w_standard_timeouts, 0, 1);
|
|
|
|
env_parse("ata_pci_debug", "d", 0, &w_pci_debug, 0, 1);
|
2009-04-27 13:53:11 +02:00
|
|
|
env_parse(NO_DMA_VAR, "d", 0, &disable_dma, 0, 1);
|
2009-05-10 18:58:23 +02:00
|
|
|
env_parse("ata_id_timeout", "d", 0, &wakeup_secs, 1, 60);
|
2005-08-26 21:39:00 +02:00
|
|
|
env_parse("atapi_debug", "d", 0, &atapi_debug, 0, 1);
|
2009-10-19 17:45:14 +02:00
|
|
|
env_parse("atapi_dma", "d", 0, &w_atapi_dma, 0, 1);
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2008-12-11 15:42:23 +01:00
|
|
|
w_identify_wakeup_ticks = wakeup_secs * system_hz;
|
2007-02-09 16:58:33 +01:00
|
|
|
|
2007-02-23 19:21:19 +01:00
|
|
|
if(atapi_debug)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("atapi_debug");
|
2007-02-23 19:21:19 +01:00
|
|
|
|
2007-02-09 16:58:33 +01:00
|
|
|
if(w_identify_wakeup_ticks <= 0) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("changing wakeup from %ld to %d ticks.\n",
|
2007-02-09 16:58:33 +01:00
|
|
|
w_identify_wakeup_ticks, WAKEUP_TICKS);
|
|
|
|
w_identify_wakeup_ticks = WAKEUP_TICKS;
|
|
|
|
}
|
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
if (disable_dma) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: DMA for ATA devices is disabled.\n", w_instance);
|
2008-11-19 13:26:10 +01:00
|
|
|
} else {
|
|
|
|
/* Ask for anonymous memory for DMA, that is physically contiguous. */
|
2010-02-10 14:56:26 +01:00
|
|
|
dma_buf = alloc_contig(ATA_DMA_BUF_SIZE, 0, &dma_buf_phys);
|
|
|
|
prdt = alloc_contig(PRDT_BYTES, 0, &prdt_phys);
|
|
|
|
if(!dma_buf || !prdt) {
|
2008-11-19 13:26:10 +01:00
|
|
|
disable_dma = 1;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: no dma\n", w_instance);
|
2008-11-19 13:26:10 +01:00
|
|
|
}
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_instance == 0) {
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Get the number of drives from the BIOS data area */
|
2006-07-10 14:34:41 +02:00
|
|
|
s=sys_readbios(NR_HD_DRIVES_ADDR, params, NR_HD_DRIVES_SIZE);
|
|
|
|
if (s != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't read BIOS: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
if ((nr_drives = params[0]) > 2) nr_drives = 2;
|
|
|
|
|
|
|
|
for (drive = 0, wn = wini; drive < COMPAT_DRIVES; drive++, wn++) {
|
|
|
|
if (drive < nr_drives) {
|
|
|
|
/* Copy the BIOS parameter vector */
|
2006-07-10 14:34:41 +02:00
|
|
|
vector = (drive == 0) ? BIOS_HD0_PARAMS_ADDR :
|
|
|
|
BIOS_HD1_PARAMS_ADDR;
|
|
|
|
size = (drive == 0) ? BIOS_HD0_PARAMS_SIZE :
|
|
|
|
BIOS_HD1_PARAMS_SIZE;
|
|
|
|
s=sys_readbios(vector, parv, size);
|
|
|
|
if (s != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't read BIOS: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2006-07-10 14:34:41 +02:00
|
|
|
/* Calculate the address of the parameters and copy them */
|
|
|
|
s=sys_readbios(hclick_to_physb(parv[1]) + parv[0],
|
|
|
|
params, 16L);
|
|
|
|
if (s != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't copy parameters: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2006-07-10 14:34:41 +02:00
|
|
|
/* Copy the parameters to the structures of the drive */
|
|
|
|
wn->lcylinders = bp_cylinders(params);
|
|
|
|
wn->lheads = bp_heads(params);
|
|
|
|
wn->lsectors = bp_sectors(params);
|
|
|
|
wn->precomp = bp_precomp(params) >> 2;
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Fill in non-BIOS parameters. */
|
2005-08-25 18:25:19 +02:00
|
|
|
init_drive(wn,
|
|
|
|
drive < 2 ? REG_CMD_BASE0 : REG_CMD_BASE1,
|
|
|
|
drive < 2 ? REG_CTL_BASE0 : REG_CTL_BASE1,
|
2006-03-03 16:37:51 +01:00
|
|
|
0 /* no DMA */, NO_IRQ, 0, 0, drive);
|
2005-08-25 10:19:11 +02:00
|
|
|
w_next_drive++;
|
|
|
|
}
|
2008-11-19 13:26:10 +01:00
|
|
|
}
|
2005-08-09 14:42:53 +02:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Look for controllers on the pci bus. Skip none the first instance,
|
|
|
|
* skip one and then 2 for every instance, for every next instance.
|
|
|
|
*/
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_instance == 0)
|
2005-08-25 10:19:11 +02:00
|
|
|
init_params_pci(0);
|
|
|
|
else
|
|
|
|
init_params_pci(w_instance*2-1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ATA_IF_NOTCOMPAT1 (1L << 0)
|
|
|
|
#define ATA_IF_NOTCOMPAT2 (1L << 2)
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* init_drive *
|
|
|
|
*===========================================================================*/
|
2006-03-03 16:37:51 +01:00
|
|
|
PRIVATE void init_drive(struct wini *w, int base_cmd, int base_ctl,
|
|
|
|
int base_dma, int irq, int ack, int hook, int drive)
|
2005-08-25 10:19:11 +02:00
|
|
|
{
|
|
|
|
w->state = 0;
|
|
|
|
w->w_status = 0;
|
2005-08-25 18:25:19 +02:00
|
|
|
w->base_cmd = base_cmd;
|
|
|
|
w->base_ctl = base_ctl;
|
2006-03-03 16:37:51 +01:00
|
|
|
w->base_dma = base_dma;
|
2007-02-21 18:49:35 +01:00
|
|
|
if(w_pci_debug)
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: drive %d: base_cmd 0x%x, base_ctl 0x%x, base_dma 0x%x\n",
|
2007-02-21 18:49:35 +01:00
|
|
|
w_instance, w-wini, w->base_cmd, w->base_ctl, w->base_dma);
|
2005-08-25 10:19:11 +02:00
|
|
|
w->irq = irq;
|
|
|
|
w->irq_need_ack = ack;
|
|
|
|
w->irq_hook_id = hook;
|
|
|
|
w->ldhpref = ldh_init(drive);
|
|
|
|
w->max_count = MAX_SECS << SECTOR_SHIFT;
|
2005-08-25 18:25:19 +02:00
|
|
|
w->lba48 = 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
w->dma = 0;
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
|
|
|
|
2010-04-28 13:52:28 +02:00
|
|
|
PRIVATE int quirkmatch(struct quirk *table, u8_t bcr, u8_t scr, u8_t interface, u16_t vid, u16_t did) {
|
|
|
|
while(table->vendor) {
|
|
|
|
if(table->vendor == vid && table->device == did &&
|
|
|
|
table->pci_class == bcr &&
|
|
|
|
table->pci_subclass == scr &&
|
|
|
|
(table->pci_interface == -1 ||
|
|
|
|
table->pci_interface == interface)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
table++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* init_params_pci *
|
|
|
|
*===========================================================================*/
|
2005-08-25 10:19:11 +02:00
|
|
|
PRIVATE void init_params_pci(int skip)
|
|
|
|
{
|
2007-02-20 19:42:43 +01:00
|
|
|
int i, r, devind, drive, pci_compat = 0;
|
2010-04-28 13:52:28 +02:00
|
|
|
int irq, irq_hook;
|
2006-04-04 14:27:28 +02:00
|
|
|
u8_t bcr, scr, interface;
|
2005-08-25 10:19:11 +02:00
|
|
|
u16_t vid, did;
|
2006-04-04 14:27:28 +02:00
|
|
|
u32_t base_dma, t3;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
pci_init();
|
|
|
|
for(drive = w_next_drive; drive < MAX_DRIVES; drive++)
|
|
|
|
wini[drive].state = IGNORING;
|
2006-03-03 16:37:51 +01:00
|
|
|
for(r = pci_first_dev(&devind, &vid, &did); r != 0;
|
|
|
|
r = pci_next_dev(&devind, &vid, &did)) {
|
2010-04-28 13:52:28 +02:00
|
|
|
int quirk = 0;
|
2006-04-04 14:27:28 +02:00
|
|
|
|
|
|
|
/* Except class 01h (mass storage), subclass be 01h (ATA).
|
|
|
|
* Also check listed RAID controllers.
|
2005-08-25 10:19:11 +02:00
|
|
|
*/
|
2006-04-04 14:27:28 +02:00
|
|
|
bcr= pci_attr_r8(devind, PCI_BCR);
|
|
|
|
scr= pci_attr_r8(devind, PCI_SCR);
|
|
|
|
interface= pci_attr_r8(devind, PCI_PIFR);
|
|
|
|
t3= ((bcr << 16) | (scr << 8) | interface);
|
|
|
|
if (bcr == PCI_BCR_MASS_STORAGE && scr == PCI_MS_IDE)
|
|
|
|
; /* Okay */
|
2010-04-28 13:52:28 +02:00
|
|
|
else if(quirkmatch(quirk_table, bcr, scr, interface, vid, did)) {
|
|
|
|
quirk = 1;
|
|
|
|
} else
|
2006-04-04 14:27:28 +02:00
|
|
|
continue; /* Unsupported device class */
|
2005-12-02 15:45:10 +01:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Found a controller.
|
|
|
|
* Programming interface register tells us more.
|
|
|
|
*/
|
|
|
|
irq = pci_attr_r8(devind, PCI_ILR);
|
|
|
|
|
|
|
|
/* Any non-compat drives? */
|
2010-04-28 13:52:28 +02:00
|
|
|
if (quirk || (interface & (ATA_IF_NOTCOMPAT1 | ATA_IF_NOTCOMPAT2))) {
|
2006-03-03 16:37:51 +01:00
|
|
|
if (w_next_drive >= MAX_DRIVES)
|
|
|
|
{
|
|
|
|
/* We can't accept more drives, but have to search for
|
|
|
|
* controllers operating in compatibility mode.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
irq_hook = irq;
|
2005-09-11 19:09:11 +02:00
|
|
|
if (skip > 0) {
|
2006-04-04 14:27:28 +02:00
|
|
|
if (w_pci_debug)
|
|
|
|
{
|
|
|
|
printf(
|
|
|
|
"atapci skipping controller (remain %d)\n",
|
|
|
|
skip);
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
skip--;
|
|
|
|
continue;
|
|
|
|
}
|
2007-02-20 18:09:19 +01:00
|
|
|
if(pci_reserve_ok(devind) != OK) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: pci_reserve %d failed - "
|
2007-02-20 18:09:19 +01:00
|
|
|
"ignoring controller!\n",
|
|
|
|
w_instance, devind);
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-15 22:45:30 +01:00
|
|
|
if (sys_irqsetpolicy(irq, 0, &irq_hook) != OK) {
|
2005-08-25 10:19:11 +02:00
|
|
|
printf("atapci: couldn't set IRQ policy %d\n", irq);
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-15 22:45:30 +01:00
|
|
|
if (sys_irqenable(&irq_hook) != OK) {
|
2005-08-25 10:19:11 +02:00
|
|
|
printf("atapci: couldn't enable IRQ line %d\n", irq);
|
|
|
|
continue;
|
|
|
|
}
|
2010-04-28 13:52:28 +02:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2006-03-07 15:16:13 +01:00
|
|
|
base_dma = pci_attr_r32(devind, PCI_BAR_5) & 0xfffffffc;
|
2005-08-25 10:19:11 +02:00
|
|
|
|
|
|
|
/* Primary channel not in compatability mode? */
|
2010-04-28 13:52:28 +02:00
|
|
|
if (quirk || (interface & ATA_IF_NOTCOMPAT1)) {
|
2005-08-25 18:25:19 +02:00
|
|
|
u32_t base_cmd, base_ctl;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2006-03-07 15:16:13 +01:00
|
|
|
base_cmd = pci_attr_r32(devind, PCI_BAR) & 0xfffffffc;
|
|
|
|
base_ctl = pci_attr_r32(devind, PCI_BAR_2) & 0xfffffffc;
|
2005-09-11 19:09:11 +02:00
|
|
|
if (base_cmd != REG_CMD_BASE0 && base_cmd != REG_CMD_BASE1) {
|
2005-08-25 18:25:19 +02:00
|
|
|
init_drive(&wini[w_next_drive],
|
2006-02-24 13:55:47 +01:00
|
|
|
base_cmd, base_ctl+PCI_CTL_OFF,
|
2006-03-03 16:37:51 +01:00
|
|
|
base_dma, irq, 1, irq_hook, 0);
|
2005-08-25 18:25:19 +02:00
|
|
|
init_drive(&wini[w_next_drive+1],
|
2006-02-24 13:55:47 +01:00
|
|
|
base_cmd, base_ctl+PCI_CTL_OFF,
|
2006-03-03 16:37:51 +01:00
|
|
|
base_dma, irq, 1, irq_hook, 1);
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_pci_debug)
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: atapci %d: 0x%x 0x%x irq %d\n",
|
|
|
|
w_instance, devind, base_cmd, base_ctl, irq);
|
2006-03-07 15:16:13 +01:00
|
|
|
w_next_drive += 2;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
} else printf("at_wini%ld: atapci: ignored drives on primary channel, base %x\n", w_instance, base_cmd);
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Update base_dma for compatibility device */
|
|
|
|
for (i= 0; i<MAX_DRIVES; i++)
|
|
|
|
{
|
2007-02-20 19:42:43 +01:00
|
|
|
if (wini[i].base_cmd == REG_CMD_BASE0) {
|
2006-03-03 16:37:51 +01:00
|
|
|
wini[i].base_dma= base_dma;
|
2007-02-21 18:49:35 +01:00
|
|
|
if(w_pci_debug)
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: drive %d: base_dma 0x%x\n",
|
2007-02-21 18:49:35 +01:00
|
|
|
w_instance, i, wini[i].base_dma);
|
2007-02-20 19:42:43 +01:00
|
|
|
pci_compat = 1;
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
|
|
|
|
/* Secondary channel not in compatability mode? */
|
2010-04-28 13:52:28 +02:00
|
|
|
if (quirk || (interface & ATA_IF_NOTCOMPAT2)) {
|
2005-08-25 18:25:19 +02:00
|
|
|
u32_t base_cmd, base_ctl;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2006-03-07 15:16:13 +01:00
|
|
|
base_cmd = pci_attr_r32(devind, PCI_BAR_3) & 0xfffffffc;
|
|
|
|
base_ctl = pci_attr_r32(devind, PCI_BAR_4) & 0xfffffffc;
|
2006-03-03 16:37:51 +01:00
|
|
|
if (base_dma != 0)
|
|
|
|
base_dma += PCI_DMA_2ND_OFF;
|
2005-09-11 19:09:11 +02:00
|
|
|
if (base_cmd != REG_CMD_BASE0 && base_cmd != REG_CMD_BASE1) {
|
2006-03-07 15:16:13 +01:00
|
|
|
init_drive(&wini[w_next_drive],
|
2006-03-03 16:37:51 +01:00
|
|
|
base_cmd, base_ctl+PCI_CTL_OFF, base_dma,
|
|
|
|
irq, 1, irq_hook, 2);
|
2006-03-07 15:16:13 +01:00
|
|
|
init_drive(&wini[w_next_drive+1],
|
2006-03-03 16:37:51 +01:00
|
|
|
base_cmd, base_ctl+PCI_CTL_OFF, base_dma,
|
|
|
|
irq, 1, irq_hook, 3);
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_pci_debug)
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: atapci %d: 0x%x 0x%x irq %d\n",
|
2007-02-21 18:49:35 +01:00
|
|
|
w_instance, devind, base_cmd, base_ctl, irq);
|
2006-03-07 15:16:13 +01:00
|
|
|
w_next_drive += 2;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
} else printf("at_wini%ld: atapci: ignored drives on "
|
2007-02-21 18:49:35 +01:00
|
|
|
"secondary channel, base %x\n", w_instance, base_cmd);
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Update base_dma for compatibility device */
|
|
|
|
for (i= 0; i<MAX_DRIVES; i++)
|
|
|
|
{
|
2007-02-20 19:42:43 +01:00
|
|
|
if (wini[i].base_cmd == REG_CMD_BASE1 && base_dma != 0) {
|
2006-03-03 16:37:51 +01:00
|
|
|
wini[i].base_dma= base_dma+PCI_DMA_2ND_OFF;
|
2007-02-21 18:49:35 +01:00
|
|
|
if (w_pci_debug)
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: drive %d: base_dma 0x%x\n",
|
2007-02-21 18:49:35 +01:00
|
|
|
w_instance, i, wini[i].base_dma);
|
2007-02-20 19:42:43 +01:00
|
|
|
pci_compat = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pci_compat) {
|
|
|
|
if(pci_reserve_ok(devind) != OK) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld (compat): pci_reserve %d failed!\n",
|
2007-02-20 19:42:43 +01:00
|
|
|
w_instance, devind);
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_do_open *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_do_open(dev_t minor, int access)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Device open: Initialize the controller and read the partition table. */
|
|
|
|
|
|
|
|
struct wini *wn;
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (w_prepare(minor) == NULL) return(ENXIO);
|
2005-07-26 15:11:16 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
wn = w_wn;
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
/* If we've probed it before and it failed, don't probe it again. */
|
|
|
|
if (wn->state & IGNORING) return ENXIO;
|
|
|
|
|
|
|
|
/* If we haven't identified it yet, or it's gone deaf,
|
|
|
|
* (re-)identify it.
|
|
|
|
*/
|
|
|
|
if (!(wn->state & IDENTIFIED) || (wn->state & DEAF)) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Try to identify the device. */
|
|
|
|
if (w_identify() != OK) {
|
2005-08-08 14:16:59 +02:00
|
|
|
#if VERBOSE
|
2005-07-26 15:11:16 +02:00
|
|
|
printf("%s: probe failed\n", w_name());
|
2005-08-08 14:16:59 +02:00
|
|
|
#endif
|
2010-02-09 16:23:38 +01:00
|
|
|
if (wn->state & DEAF){
|
|
|
|
int err = w_reset();
|
|
|
|
if( err != OK ){
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
2005-08-04 10:08:58 +02:00
|
|
|
wn->state = IGNORING;
|
2005-04-21 16:53:53 +02:00
|
|
|
return(ENXIO);
|
|
|
|
}
|
2005-08-04 10:08:58 +02:00
|
|
|
/* Do a test transaction unless it's a CD drive (then
|
|
|
|
* we can believe the controller, and a test may fail
|
|
|
|
* due to no CD being in the drive). If it fails, ignore
|
|
|
|
* the device forever.
|
|
|
|
*/
|
2005-09-11 19:09:11 +02:00
|
|
|
if (!(wn->state & ATAPI) && w_io_test() != OK) {
|
2005-08-04 10:08:58 +02:00
|
|
|
wn->state |= IGNORING;
|
|
|
|
return(ENXIO);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2005-08-09 14:18:15 +02:00
|
|
|
#if ENABLE_ATAPI
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if ((wn->state & ATAPI) && (access & W_BIT))
|
2005-08-09 14:18:15 +02:00
|
|
|
return(EACCES);
|
|
|
|
#endif
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
/* Partition the drive if it's being opened for the first time,
|
|
|
|
* or being opened after being closed.
|
|
|
|
*/
|
2005-04-21 16:53:53 +02:00
|
|
|
if (wn->open_ct == 0) {
|
|
|
|
#if ENABLE_ATAPI
|
|
|
|
if (wn->state & ATAPI) {
|
|
|
|
int r;
|
|
|
|
if ((r = atapi_open()) != OK) return(r);
|
|
|
|
}
|
|
|
|
#endif
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Partition the disk. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
partition(&w_dtab, w_drive * DEV_PER_DRIVE, P_PRIMARY,
|
|
|
|
wn->state & ATAPI);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2005-08-12 18:42:36 +02:00
|
|
|
wn->open_ct++;
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* w_prepare *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE struct device *w_prepare(dev_t device)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2010-01-15 22:45:30 +01:00
|
|
|
/* Prepare for I/O on a device. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
w_device = (int) device;
|
2005-08-26 21:39:00 +02:00
|
|
|
|
2005-08-04 11:26:36 +02:00
|
|
|
if (device < NR_MINORS) { /* d0, d0p[0-3], d1, ... */
|
2005-04-21 16:53:53 +02:00
|
|
|
w_drive = device / DEV_PER_DRIVE; /* save drive number */
|
|
|
|
w_wn = &wini[w_drive];
|
|
|
|
w_dv = &w_wn->part[device % DEV_PER_DRIVE];
|
|
|
|
} else
|
|
|
|
if ((unsigned) (device -= MINOR_d0p0s0) < NR_SUBDEVS) {/*d[0-7]p[0-3]s[0-3]*/
|
|
|
|
w_drive = device / SUB_PER_DRIVE;
|
|
|
|
w_wn = &wini[w_drive];
|
|
|
|
w_dv = &w_wn->subpart[device % SUB_PER_DRIVE];
|
|
|
|
} else {
|
2005-08-04 10:08:58 +02:00
|
|
|
w_device = -1;
|
2010-05-10 15:26:00 +02:00
|
|
|
return(NULL);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
return(w_dv);
|
|
|
|
}
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_part *
|
|
|
|
*===========================================================================*/
|
|
|
|
PRIVATE struct device *w_part(dev_t device)
|
|
|
|
{
|
|
|
|
/* Return a pointer to the partition information of the given minor device. */
|
|
|
|
|
|
|
|
return w_prepare(device);
|
|
|
|
}
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
#define id_byte(n) (&tmp_buf[2 * (n)])
|
|
|
|
#define id_word(n) (((u16_t) id_byte(n)[0] << 0) \
|
|
|
|
|((u16_t) id_byte(n)[1] << 8))
|
|
|
|
#define id_longword(n) (((u32_t) id_byte(n)[0] << 0) \
|
|
|
|
|((u32_t) id_byte(n)[1] << 8) \
|
|
|
|
|((u32_t) id_byte(n)[2] << 16) \
|
|
|
|
|((u32_t) id_byte(n)[3] << 24))
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* check_dma *
|
|
|
|
*===========================================================================*/
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE void
|
2009-10-19 17:45:14 +02:00
|
|
|
check_dma(struct wini *wn)
|
|
|
|
{
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t dma_status, dma_base;
|
2009-10-19 17:45:14 +02:00
|
|
|
int id_dma, ultra_dma;
|
|
|
|
u16_t w;
|
|
|
|
|
|
|
|
wn->dma= 0;
|
|
|
|
|
|
|
|
if (disable_dma)
|
|
|
|
return;
|
|
|
|
|
|
|
|
w= id_word(ID_CAPABILITIES);
|
|
|
|
id_dma= !!(w & ID_CAP_DMA);
|
|
|
|
w= id_byte(ID_FIELD_VALIDITY)[0];
|
|
|
|
ultra_dma= !!(w & ID_FV_88);
|
|
|
|
dma_base= wn->base_dma;
|
|
|
|
|
|
|
|
if (dma_base) {
|
|
|
|
if (sys_inb(dma_base + DMA_STATUS, &dma_status) != OK) {
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("unable to read DMA status register");
|
2009-10-19 17:45:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id_dma && dma_base) {
|
|
|
|
w= id_word(ID_MULTIWORD_DMA);
|
|
|
|
if (w_pci_debug &&
|
|
|
|
(w & (ID_MWDMA_2_SUP|ID_MWDMA_1_SUP|ID_MWDMA_0_SUP))) {
|
|
|
|
printf(
|
|
|
|
"%s: multiword DMA modes supported:%s%s%s\n",
|
|
|
|
w_name(),
|
|
|
|
(w & ID_MWDMA_0_SUP) ? " 0" : "",
|
|
|
|
(w & ID_MWDMA_1_SUP) ? " 1" : "",
|
|
|
|
(w & ID_MWDMA_2_SUP) ? " 2" : "");
|
|
|
|
}
|
|
|
|
if (w_pci_debug &&
|
|
|
|
(w & (ID_MWDMA_0_SEL|ID_MWDMA_1_SEL|ID_MWDMA_2_SEL))) {
|
|
|
|
printf(
|
|
|
|
"%s: multiword DMA mode selected:%s%s%s\n",
|
|
|
|
w_name(),
|
|
|
|
(w & ID_MWDMA_0_SEL) ? " 0" : "",
|
|
|
|
(w & ID_MWDMA_1_SEL) ? " 1" : "",
|
|
|
|
(w & ID_MWDMA_2_SEL) ? " 2" : "");
|
|
|
|
}
|
|
|
|
if (w_pci_debug && ultra_dma) {
|
|
|
|
w= id_word(ID_ULTRA_DMA);
|
|
|
|
if (w & (ID_UDMA_0_SUP|ID_UDMA_1_SUP|
|
|
|
|
ID_UDMA_2_SUP|ID_UDMA_3_SUP|
|
|
|
|
ID_UDMA_4_SUP|ID_UDMA_5_SUP)) {
|
|
|
|
printf(
|
|
|
|
"%s: Ultra DMA modes supported:%s%s%s%s%s%s\n",
|
|
|
|
w_name(),
|
|
|
|
(w & ID_UDMA_0_SUP) ? " 0" : "",
|
|
|
|
(w & ID_UDMA_1_SUP) ? " 1" : "",
|
|
|
|
(w & ID_UDMA_2_SUP) ? " 2" : "",
|
|
|
|
(w & ID_UDMA_3_SUP) ? " 3" : "",
|
|
|
|
(w & ID_UDMA_4_SUP) ? " 4" : "",
|
|
|
|
(w & ID_UDMA_5_SUP) ? " 5" : "");
|
|
|
|
}
|
|
|
|
if (w & (ID_UDMA_0_SEL|ID_UDMA_1_SEL|
|
|
|
|
ID_UDMA_2_SEL|ID_UDMA_3_SEL|
|
|
|
|
ID_UDMA_4_SEL|ID_UDMA_5_SEL)) {
|
|
|
|
printf(
|
|
|
|
"%s: Ultra DMA mode selected:%s%s%s%s%s%s\n",
|
|
|
|
w_name(),
|
|
|
|
(w & ID_UDMA_0_SEL) ? " 0" : "",
|
|
|
|
(w & ID_UDMA_1_SEL) ? " 1" : "",
|
|
|
|
(w & ID_UDMA_2_SEL) ? " 2" : "",
|
|
|
|
(w & ID_UDMA_3_SEL) ? " 3" : "",
|
|
|
|
(w & ID_UDMA_4_SEL) ? " 4" : "",
|
|
|
|
(w & ID_UDMA_5_SEL) ? " 5" : "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wn->dma= 1;
|
|
|
|
} else if (id_dma || dma_base) {
|
|
|
|
printf("id_dma %d, dma_base 0x%x\n", id_dma, dma_base);
|
|
|
|
} else
|
|
|
|
printf("no DMA support\n");
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_identify *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_identify(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Find out if a device exists, if it is an old AT disk, or a newer ATA
|
|
|
|
* drive, a removable media device, etc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
struct command cmd;
|
2010-01-22 23:01:08 +01:00
|
|
|
int s;
|
2006-02-24 13:55:47 +01:00
|
|
|
u16_t w;
|
2005-04-21 16:53:53 +02:00
|
|
|
unsigned long size;
|
2007-02-09 16:58:33 +01:00
|
|
|
int prev_wakeup;
|
|
|
|
int r;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Try to identify the device. */
|
|
|
|
cmd.ldh = wn->ldhpref;
|
|
|
|
cmd.command = ATA_IDENTIFY;
|
2007-02-09 16:58:33 +01:00
|
|
|
|
2007-02-12 14:35:33 +01:00
|
|
|
/* In testing mode, a drive will get ignored at the first timeout. */
|
|
|
|
w_testing = 1;
|
|
|
|
|
2007-02-09 16:58:33 +01:00
|
|
|
/* Execute *_IDENTIFY with configured *_IDENTIFY timeout. */
|
|
|
|
prev_wakeup = wakeup_ticks;
|
|
|
|
wakeup_ticks = w_identify_wakeup_ticks;
|
|
|
|
r = com_simple(&cmd);
|
|
|
|
|
|
|
|
if (r == OK && w_waitfor(STATUS_DRQ, STATUS_DRQ) &&
|
2006-03-09 16:05:43 +01:00
|
|
|
!(wn->w_status & (STATUS_ERR|STATUS_WF))) {
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Device information. */
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2006-11-27 15:21:43 +01:00
|
|
|
#if 0
|
2006-03-09 16:05:43 +01:00
|
|
|
if (id_word(0) & ID_GEN_NOT_ATA)
|
|
|
|
{
|
|
|
|
printf("%s: not an ATA device?\n", w_name());
|
2007-02-09 16:58:33 +01:00
|
|
|
wakeup_ticks = prev_wakeup;
|
2007-02-12 14:35:33 +01:00
|
|
|
w_testing = 0;
|
2006-03-09 16:05:43 +01:00
|
|
|
return ERR;
|
|
|
|
}
|
2006-11-27 15:21:43 +01:00
|
|
|
#endif
|
2006-03-09 16:05:43 +01:00
|
|
|
|
|
|
|
/* This is an ATA device. */
|
|
|
|
wn->state |= SMART;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Preferred CHS translation mode. */
|
|
|
|
wn->pcylinders = id_word(1);
|
|
|
|
wn->pheads = id_word(3);
|
|
|
|
wn->psectors = id_word(6);
|
|
|
|
size = (u32_t) wn->pcylinders * wn->pheads * wn->psectors;
|
|
|
|
|
2006-02-24 13:55:47 +01:00
|
|
|
w= id_word(ID_CAPABILITIES);
|
|
|
|
if ((w & ID_CAP_LBA) && size > 512L*1024*2) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Drive is LBA capable and is big enough to trust it to
|
|
|
|
* not make a mess of it.
|
|
|
|
*/
|
|
|
|
wn->ldhpref |= LDH_LBA;
|
|
|
|
size = id_longword(60);
|
2005-08-25 18:25:19 +02:00
|
|
|
|
2006-02-24 13:55:47 +01:00
|
|
|
w= id_word(ID_CSS);
|
|
|
|
if (size < LBA48_CHECK_SIZE)
|
|
|
|
{
|
|
|
|
/* No need to check for LBA48 */
|
|
|
|
}
|
|
|
|
else if (w & ID_CSS_LBA48) {
|
2005-08-25 18:25:19 +02:00
|
|
|
/* Drive is LBA48 capable (and LBA48 is turned on). */
|
2006-02-24 13:55:47 +01:00
|
|
|
if (id_longword(102)) {
|
2005-08-25 18:25:19 +02:00
|
|
|
/* If no. of sectors doesn't fit in 32 bits,
|
|
|
|
* trunacte to this. So it's LBA32 for now.
|
|
|
|
* This can still address devices up to 2TB
|
|
|
|
* though.
|
|
|
|
*/
|
|
|
|
size = ULONG_MAX;
|
|
|
|
} else {
|
|
|
|
/* Actual number of sectors fits in 32 bits. */
|
|
|
|
size = id_longword(100);
|
|
|
|
}
|
|
|
|
wn->lba48 = 1;
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
check_dma(wn);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2007-05-30 18:13:52 +02:00
|
|
|
if (wn->lcylinders == 0 || wn->lheads == 0 || wn->lsectors == 0) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* No BIOS parameters? Then make some up. */
|
|
|
|
wn->lcylinders = wn->pcylinders;
|
|
|
|
wn->lheads = wn->pheads;
|
|
|
|
wn->lsectors = wn->psectors;
|
|
|
|
while (wn->lcylinders > 1024) {
|
|
|
|
wn->lheads *= 2;
|
|
|
|
wn->lcylinders /= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if ENABLE_ATAPI
|
|
|
|
} else
|
2006-03-09 16:05:43 +01:00
|
|
|
if (cmd.command = ATAPI_IDENTIFY,
|
|
|
|
com_simple(&cmd) == OK && w_waitfor(STATUS_DRQ, STATUS_DRQ) &&
|
|
|
|
!(wn->w_status & (STATUS_ERR|STATUS_WF))) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* An ATAPI device. */
|
|
|
|
wn->state |= ATAPI;
|
|
|
|
|
|
|
|
/* Device information. */
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, 512)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
size = 0; /* Size set later. */
|
2009-10-19 17:45:14 +02:00
|
|
|
check_dma(wn);
|
2005-04-21 16:53:53 +02:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
/* Not an ATA device; no translations, no special features. Don't
|
|
|
|
* touch it unless the BIOS knows about it.
|
|
|
|
*/
|
2007-02-09 16:58:33 +01:00
|
|
|
if (wn->lcylinders == 0) {
|
|
|
|
wakeup_ticks = prev_wakeup;
|
2007-02-12 14:35:33 +01:00
|
|
|
w_testing = 0;
|
2007-02-09 16:58:33 +01:00
|
|
|
return(ERR);
|
|
|
|
} /* no BIOS parameters */
|
2005-04-21 16:53:53 +02:00
|
|
|
wn->pcylinders = wn->lcylinders;
|
|
|
|
wn->pheads = wn->lheads;
|
|
|
|
wn->psectors = wn->lsectors;
|
|
|
|
size = (u32_t) wn->pcylinders * wn->pheads * wn->psectors;
|
|
|
|
}
|
|
|
|
|
2007-02-12 14:35:33 +01:00
|
|
|
/* Restore wakeup_ticks and unset testing mode. */
|
2007-02-09 16:58:33 +01:00
|
|
|
wakeup_ticks = prev_wakeup;
|
2007-02-12 14:35:33 +01:00
|
|
|
w_testing = 0;
|
2007-02-09 16:58:33 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Size of the whole drive */
|
|
|
|
wn->part[0].dv_size = mul64u(size, SECTOR_SIZE);
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
/* Reset/calibrate (where necessary) */
|
2005-07-26 15:11:16 +02:00
|
|
|
if (w_specify() != OK && w_specify() != OK) {
|
|
|
|
return(ERR);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (wn->irq == NO_IRQ) {
|
2005-08-25 10:19:11 +02:00
|
|
|
/* Everything looks OK; register IRQ so we can stop polling. */
|
|
|
|
wn->irq = w_drive < 2 ? AT_WINI_0_IRQ : AT_WINI_1_IRQ;
|
|
|
|
wn->irq_hook_id = wn->irq; /* id to be returned if interrupt occurs */
|
|
|
|
if ((s=sys_irqsetpolicy(wn->irq, IRQ_REENABLE, &wn->irq_hook_id)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("couldn't set IRQ policy: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
if ((s=sys_irqenable(&wn->irq_hook_id)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("couldn't enable IRQ line: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
2005-07-26 15:11:16 +02:00
|
|
|
wn->state |= IDENTIFIED;
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* w_name *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE char *w_name(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Return a name for the current device. */
|
2007-02-08 16:56:58 +01:00
|
|
|
static char name[] = "AT0-D0";
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2007-02-08 16:56:58 +01:00
|
|
|
name[2] = '0' + w_instance;
|
|
|
|
name[5] = '0' + w_drive;
|
2005-04-21 16:53:53 +02:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_io_test *
|
|
|
|
*===========================================================================*/
|
|
|
|
PRIVATE int w_io_test(void)
|
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
int save_dev;
|
2005-08-04 10:08:58 +02:00
|
|
|
int save_timeout, save_errors, save_wakeup;
|
|
|
|
iovec_t iov;
|
2008-11-19 13:26:10 +01:00
|
|
|
static char *buf;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
ssize_t r;
|
2008-11-19 13:26:10 +01:00
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
#ifdef CD_SECTOR_SIZE
|
2008-11-19 13:26:10 +01:00
|
|
|
#define BUFSIZE CD_SECTOR_SIZE
|
2005-08-04 10:08:58 +02:00
|
|
|
#else
|
2008-11-19 13:26:10 +01:00
|
|
|
#define BUFSIZE SECTOR_SIZE
|
2005-08-04 10:08:58 +02:00
|
|
|
#endif
|
2008-11-19 13:26:10 +01:00
|
|
|
STATICINIT(buf, BUFSIZE);
|
2005-08-04 10:08:58 +02:00
|
|
|
|
|
|
|
iov.iov_addr = (vir_bytes) buf;
|
2008-11-19 13:26:10 +01:00
|
|
|
iov.iov_size = BUFSIZE;
|
2005-08-04 10:08:58 +02:00
|
|
|
save_dev = w_device;
|
|
|
|
|
|
|
|
/* Reduce timeout values for this test transaction. */
|
2010-07-13 01:14:40 +02:00
|
|
|
save_timeout = timeout_usecs;
|
2005-08-04 10:08:58 +02:00
|
|
|
save_errors = max_errors;
|
|
|
|
save_wakeup = wakeup_ticks;
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (!w_standard_timeouts) {
|
2010-07-13 01:14:40 +02:00
|
|
|
timeout_usecs = 4000000;
|
2008-12-11 15:42:23 +01:00
|
|
|
wakeup_ticks = system_hz * 6;
|
2005-08-09 18:59:29 +02:00
|
|
|
max_errors = 3;
|
2005-08-09 14:42:53 +02:00
|
|
|
}
|
|
|
|
|
2005-08-04 10:08:58 +02:00
|
|
|
w_testing = 1;
|
|
|
|
|
|
|
|
/* Try I/O on the actual drive (not any (sub)partition). */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
r = w_transfer(w_drive * DEV_PER_DRIVE, FALSE /*do_write*/, cvu64(0),
|
|
|
|
SELF, &iov, 1, BDEV_NOFLAGS);
|
2005-08-04 10:08:58 +02:00
|
|
|
|
|
|
|
/* Switch back. */
|
2010-05-10 15:26:00 +02:00
|
|
|
if (w_prepare(save_dev) == NULL)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't switch back devices");
|
2005-08-04 10:08:58 +02:00
|
|
|
|
|
|
|
/* Restore parameters. */
|
2010-07-13 01:14:40 +02:00
|
|
|
timeout_usecs = save_timeout;
|
2005-08-04 10:08:58 +02:00
|
|
|
max_errors = save_errors;
|
|
|
|
wakeup_ticks = save_wakeup;
|
|
|
|
w_testing = 0;
|
|
|
|
|
|
|
|
/* Test if everything worked. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (r != BUFSIZE) {
|
2005-08-04 10:08:58 +02:00
|
|
|
return ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Everything worked. */
|
|
|
|
return OK;
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* w_specify *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_specify(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Routine to initialize the drive after boot or when a reset is needed. */
|
|
|
|
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
struct command cmd;
|
|
|
|
|
2005-05-03 10:59:13 +02:00
|
|
|
if ((wn->state & DEAF) && w_reset() != OK) {
|
|
|
|
return(ERR);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (!(wn->state & ATAPI)) {
|
|
|
|
/* Specify parameters: precompensation, number of heads and sectors. */
|
|
|
|
cmd.precomp = wn->precomp;
|
|
|
|
cmd.count = wn->psectors;
|
|
|
|
cmd.ldh = w_wn->ldhpref | (wn->pheads - 1);
|
|
|
|
cmd.command = CMD_SPECIFY; /* Specify some parameters */
|
|
|
|
|
|
|
|
/* Output command block and see if controller accepts the parameters. */
|
|
|
|
if (com_simple(&cmd) != OK) return(ERR);
|
|
|
|
|
|
|
|
if (!(wn->state & SMART)) {
|
|
|
|
/* Calibrate an old disk. */
|
|
|
|
cmd.sector = 0;
|
|
|
|
cmd.cyl_lo = 0;
|
|
|
|
cmd.cyl_hi = 0;
|
|
|
|
cmd.ldh = w_wn->ldhpref;
|
|
|
|
cmd.command = CMD_RECALIBRATE;
|
|
|
|
|
|
|
|
if (com_simple(&cmd) != OK) return(ERR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wn->state |= INITIALIZED;
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2005-08-25 18:25:19 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* do_transfer *
|
|
|
|
*===========================================================================*/
|
2010-04-01 14:51:31 +02:00
|
|
|
PRIVATE int do_transfer(const struct wini *wn, unsigned int precomp,
|
2006-03-03 16:37:51 +01:00
|
|
|
unsigned int count, unsigned int sector,
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
unsigned int do_write, int do_dma)
|
2005-08-25 18:25:19 +02:00
|
|
|
{
|
|
|
|
struct command cmd;
|
2006-02-24 13:55:47 +01:00
|
|
|
unsigned int sector_high;
|
2005-08-25 18:25:19 +02:00
|
|
|
unsigned secspcyl = wn->pheads * wn->psectors;
|
2006-02-24 13:55:47 +01:00
|
|
|
int do_lba48;
|
|
|
|
|
|
|
|
sector_high= 0; /* For future extensions */
|
|
|
|
|
|
|
|
do_lba48= 0;
|
|
|
|
if (sector >= LBA48_CHECK_SIZE || sector_high != 0)
|
|
|
|
{
|
|
|
|
if (wn->lba48)
|
|
|
|
do_lba48= 1;
|
|
|
|
else if (sector > LBA_MAX_SIZE || sector_high != 0)
|
|
|
|
{
|
|
|
|
/* Strange sector count for LBA device */
|
|
|
|
return EIO;
|
|
|
|
}
|
|
|
|
}
|
2005-08-25 18:25:19 +02:00
|
|
|
|
|
|
|
cmd.precomp = precomp;
|
|
|
|
cmd.count = count;
|
2006-03-03 16:37:51 +01:00
|
|
|
if (do_dma)
|
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
cmd.command = do_write ? CMD_WRITE_DMA : CMD_READ_DMA;
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
else
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
cmd.command = do_write ? CMD_WRITE : CMD_READ;
|
2006-02-24 13:55:47 +01:00
|
|
|
|
|
|
|
if (do_lba48) {
|
2006-03-03 16:37:51 +01:00
|
|
|
if (do_dma)
|
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
cmd.command = (do_write ?
|
2006-03-03 16:37:51 +01:00
|
|
|
CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
cmd.command = (do_write ?
|
2006-03-03 16:37:51 +01:00
|
|
|
CMD_WRITE_EXT : CMD_READ_EXT);
|
|
|
|
}
|
2006-02-24 13:55:47 +01:00
|
|
|
cmd.count_prev= (count >> 8);
|
|
|
|
cmd.sector = (sector >> 0) & 0xFF;
|
|
|
|
cmd.cyl_lo = (sector >> 8) & 0xFF;
|
|
|
|
cmd.cyl_hi = (sector >> 16) & 0xFF;
|
|
|
|
cmd.sector_prev= (sector >> 24) & 0xFF;
|
|
|
|
cmd.cyl_lo_prev= (sector_high) & 0xFF;
|
|
|
|
cmd.cyl_hi_prev= (sector_high >> 8) & 0xFF;
|
|
|
|
cmd.ldh = wn->ldhpref;
|
|
|
|
|
|
|
|
return com_out_ext(&cmd);
|
|
|
|
} else if (wn->ldhpref & LDH_LBA) {
|
2005-08-25 18:25:19 +02:00
|
|
|
cmd.sector = (sector >> 0) & 0xFF;
|
|
|
|
cmd.cyl_lo = (sector >> 8) & 0xFF;
|
|
|
|
cmd.cyl_hi = (sector >> 16) & 0xFF;
|
|
|
|
cmd.ldh = wn->ldhpref | ((sector >> 24) & 0xF);
|
|
|
|
} else {
|
|
|
|
int cylinder, head, sec;
|
|
|
|
cylinder = sector / secspcyl;
|
|
|
|
head = (sector % secspcyl) / wn->psectors;
|
|
|
|
sec = sector % wn->psectors;
|
|
|
|
cmd.sector = sec + 1;
|
|
|
|
cmd.cyl_lo = cylinder & BYTE;
|
|
|
|
cmd.cyl_hi = (cylinder >> 8) & BYTE;
|
|
|
|
cmd.ldh = wn->ldhpref | head;
|
|
|
|
}
|
|
|
|
|
|
|
|
return com_out(&cmd);
|
|
|
|
}
|
|
|
|
|
2010-04-01 14:51:31 +02:00
|
|
|
PRIVATE void stop_dma(const struct wini *wn)
|
2009-10-19 16:23:04 +02:00
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
/* Stop bus master operation */
|
|
|
|
r= sys_outb(wn->base_dma + DMA_COMMAND, 0);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("stop_dma: sys_outb failed: %d", r);
|
2009-10-19 16:23:04 +02:00
|
|
|
}
|
|
|
|
|
2010-04-01 14:51:31 +02:00
|
|
|
PRIVATE void start_dma(const struct wini *wn, int do_write)
|
2009-10-19 16:23:04 +02:00
|
|
|
{
|
|
|
|
u32_t v;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
/* Assume disk reads. Start DMA */
|
|
|
|
v= DMA_CMD_START;
|
|
|
|
if (!do_write)
|
|
|
|
{
|
|
|
|
/* Disk reads generate PCI write cycles. */
|
|
|
|
v |= DMA_CMD_WRITE;
|
|
|
|
}
|
|
|
|
r= sys_outb(wn->base_dma + DMA_COMMAND, v);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("start_dma: sys_outb failed: %d", r);
|
2009-10-19 17:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-04-01 14:51:31 +02:00
|
|
|
PRIVATE int error_dma(const struct wini *wn)
|
2009-10-19 17:45:14 +02:00
|
|
|
{
|
|
|
|
int r;
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t v;
|
2009-10-19 17:45:14 +02:00
|
|
|
|
|
|
|
#define DMAERR(msg) \
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: bad DMA: %s. Disabling DMA for drive %d.\n", \
|
2009-10-19 17:45:14 +02:00
|
|
|
w_instance, msg, wn - wini); \
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: workaround: set %s=1 in boot monitor.\n", \
|
2009-10-19 17:45:14 +02:00
|
|
|
w_instance, NO_DMA_VAR); \
|
|
|
|
return 1; \
|
|
|
|
|
|
|
|
r= sys_inb(wn->base_dma + DMA_STATUS, &v);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("w_transfer: sys_inb failed: %d", r);
|
2009-10-19 17:45:14 +02:00
|
|
|
|
|
|
|
if (!wn->dma_intseen) {
|
|
|
|
/* DMA did not complete successfully */
|
|
|
|
if (v & DMA_ST_BM_ACTIVE) {
|
|
|
|
DMAERR("DMA did not complete");
|
|
|
|
} else if (v & DMA_ST_ERROR) {
|
|
|
|
DMAERR("DMA error");
|
|
|
|
} else {
|
|
|
|
DMAERR("DMA buffer too small");
|
|
|
|
}
|
|
|
|
} else if ((v & DMA_ST_BM_ACTIVE)) {
|
|
|
|
DMAERR("DMA buffer too large");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2009-10-19 16:23:04 +02:00
|
|
|
}
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_transfer *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE ssize_t w_transfer(
|
|
|
|
dev_t minor, /* minor device to perform the transfer on */
|
|
|
|
int do_write, /* read or write? */
|
|
|
|
u64_t position, /* offset on device to read or write */
|
|
|
|
endpoint_t proc_nr, /* process doing the request */
|
|
|
|
iovec_t *iov, /* pointer to read or write request vector */
|
|
|
|
unsigned int nr_req, /* length of request vector */
|
|
|
|
int UNUSED(flags) /* transfer flags */
|
|
|
|
)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
struct wini *wn;
|
2005-04-21 16:53:53 +02:00
|
|
|
iovec_t *iop, *iov_end = iov + nr_req;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
int n, r, s, errors, do_dma;
|
2012-03-05 00:11:41 +01:00
|
|
|
unsigned long block;
|
|
|
|
u32_t w_status;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
u64_t dv_size;
|
2010-01-22 23:01:08 +01:00
|
|
|
unsigned nbytes;
|
2006-03-03 16:37:51 +01:00
|
|
|
unsigned dma_buf_offset;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
ssize_t total = 0;
|
2006-06-20 10:51:24 +02:00
|
|
|
size_t addr_offset = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (w_prepare(minor) == NULL) return(ENXIO);
|
|
|
|
|
|
|
|
wn = w_wn;
|
|
|
|
dv_size = w_dv->dv_size;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
#if ENABLE_ATAPI
|
|
|
|
if (w_wn->state & ATAPI) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
return atapi_transfer(do_write, position, proc_nr, iov, nr_req);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check disk address. */
|
2006-11-27 15:21:43 +01:00
|
|
|
if (rem64u(position, SECTOR_SIZE) != 0) return(EINVAL);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
errors = 0;
|
|
|
|
|
|
|
|
while (nr_req > 0) {
|
|
|
|
/* How many bytes to transfer? */
|
|
|
|
nbytes = 0;
|
|
|
|
for (iop = iov; iop < iov_end; iop++) nbytes += iop->iov_size;
|
|
|
|
if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
|
|
|
|
|
|
|
|
/* Which block on disk and how close to EOF? */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (cmp64(position, dv_size) >= 0) return(total); /* At EOF */
|
2006-11-27 15:21:43 +01:00
|
|
|
if (cmp64(add64ul(position, nbytes), dv_size) > 0)
|
|
|
|
nbytes = diff64(dv_size, position);
|
|
|
|
block = div64u(add64(w_dv->dv_base, position), SECTOR_SIZE);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
do_dma= wn->dma;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
if (nbytes >= wn->max_count) {
|
|
|
|
/* The drive can't do more then max_count at once. */
|
|
|
|
nbytes = wn->max_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* First check to see if a reinitialization is needed. */
|
|
|
|
if (!(wn->state & INITIALIZED) && w_specify() != OK) return(EIO);
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if (do_dma) {
|
|
|
|
stop_dma(wn);
|
2011-06-08 21:24:41 +02:00
|
|
|
if (!setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write)) {
|
|
|
|
do_dma = 0;
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
#if 0
|
|
|
|
printf("nbytes = %d\n", nbytes);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Tell the controller to transfer nbytes bytes. */
|
2006-02-24 13:55:47 +01:00
|
|
|
r = do_transfer(wn, wn->precomp, (nbytes >> SECTOR_SHIFT),
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
block, do_write, do_dma);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if (do_dma)
|
|
|
|
start_dma(wn, do_write);
|
2009-10-19 16:23:04 +02:00
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (do_write) {
|
2006-02-24 13:55:47 +01:00
|
|
|
/* The specs call for a 400 ns wait after issuing the command.
|
|
|
|
* Reading the alternate status register is the suggested
|
|
|
|
* way to implement this wait.
|
|
|
|
*/
|
|
|
|
if (sys_inb((wn->base_ctl+REG_CTL_ALTSTAT), &w_status) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("couldn't get status");
|
2006-02-24 13:55:47 +01:00
|
|
|
}
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if (do_dma) {
|
2006-03-03 16:37:51 +01:00
|
|
|
/* Wait for the interrupt, check DMA status and optionally
|
|
|
|
* copy out.
|
|
|
|
*/
|
|
|
|
|
2009-10-19 16:23:04 +02:00
|
|
|
wn->dma_intseen = 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
if ((r = at_intr_wait()) != OK)
|
|
|
|
{
|
|
|
|
/* Don't retry if sector marked bad or too many
|
|
|
|
* errors.
|
|
|
|
*/
|
|
|
|
if (r == ERR_BAD_SECTOR || ++errors == max_errors) {
|
|
|
|
w_command = CMD_IDLE;
|
|
|
|
return(EIO);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Wait for DMA_ST_INT to get set */
|
2009-10-19 16:23:04 +02:00
|
|
|
if(!wn->dma_intseen) {
|
|
|
|
if(w_waitfor_dma(DMA_ST_INT, DMA_ST_INT))
|
|
|
|
wn->dma_intseen = 1;
|
2009-10-19 17:45:14 +02:00
|
|
|
}
|
2009-04-27 13:53:11 +02:00
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if(error_dma(wn)) {
|
|
|
|
wn->dma = 0;
|
|
|
|
continue;
|
2009-04-27 13:53:11 +02:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
2009-10-19 16:23:04 +02:00
|
|
|
stop_dma(wn);
|
|
|
|
|
2006-03-03 16:37:51 +01:00
|
|
|
dma_buf_offset= 0;
|
|
|
|
while (r == OK && nbytes > 0)
|
|
|
|
{
|
|
|
|
n= iov->iov_size;
|
|
|
|
if (n > nbytes)
|
|
|
|
n= nbytes;
|
|
|
|
|
|
|
|
/* Book the bytes successfully transferred. */
|
|
|
|
nbytes -= n;
|
2006-11-27 15:21:43 +01:00
|
|
|
position= add64ul(position, n);
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
total += n;
|
2009-05-08 14:29:57 +02:00
|
|
|
addr_offset += n;
|
2006-06-20 10:51:24 +02:00
|
|
|
if ((iov->iov_size -= n) == 0) {
|
|
|
|
iov++; nr_req--; addr_offset = 0;
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
dma_buf_offset += n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
while (r == OK && nbytes > 0) {
|
|
|
|
/* For each sector, wait for an interrupt and fetch the data
|
|
|
|
* (read), or supply data to the controller and wait for an
|
|
|
|
* interrupt (write).
|
|
|
|
*/
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (!do_write) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* First an interrupt, then data. */
|
|
|
|
if ((r = at_intr_wait()) != OK) {
|
|
|
|
/* An error, send data to the bit bucket. */
|
2005-08-25 10:19:11 +02:00
|
|
|
if (w_wn->w_status & STATUS_DRQ) {
|
2006-02-24 13:55:47 +01:00
|
|
|
if ((s=sys_insw(wn->base_cmd+REG_DATA,
|
|
|
|
SELF, tmp_buf,
|
2010-03-05 16:05:11 +01:00
|
|
|
SECTOR_SIZE)) != OK) {
|
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2006-02-24 13:55:47 +01:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-24 13:55:47 +01:00
|
|
|
/* Wait for busy to clear. */
|
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) { r = ERR; break; }
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Wait for data transfer requested. */
|
|
|
|
if (!w_waitfor(STATUS_DRQ, STATUS_DRQ)) { r = ERR; break; }
|
|
|
|
|
|
|
|
/* Copy bytes to or from the device's buffer. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (!do_write) {
|
2009-12-02 10:57:48 +01:00
|
|
|
if(proc_nr != SELF) {
|
2006-06-20 10:51:24 +02:00
|
|
|
s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
|
|
|
|
(void *) (iov->iov_addr), addr_offset,
|
|
|
|
SECTOR_SIZE);
|
|
|
|
} else {
|
|
|
|
s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
|
|
|
|
(void *) (iov->iov_addr + addr_offset),
|
|
|
|
SECTOR_SIZE);
|
2009-12-02 10:57:48 +01:00
|
|
|
}
|
2006-06-20 10:51:24 +02:00
|
|
|
if(s != OK) {
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2006-06-20 10:51:24 +02:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
} else {
|
2009-12-02 10:57:48 +01:00
|
|
|
if(proc_nr != SELF) {
|
2006-06-20 10:51:24 +02:00
|
|
|
s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr,
|
|
|
|
(void *) (iov->iov_addr), addr_offset,
|
|
|
|
SECTOR_SIZE);
|
|
|
|
} else {
|
|
|
|
s=sys_outsw(wn->base_cmd + REG_DATA, proc_nr,
|
|
|
|
(void *) (iov->iov_addr + addr_offset),
|
|
|
|
SECTOR_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(s != OK) {
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_outsw() failed: %d", s);
|
2006-06-20 10:51:24 +02:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2009-12-02 10:57:48 +01:00
|
|
|
/* Data sent, wait for an interrupt. */
|
|
|
|
if ((r = at_intr_wait()) != OK) break;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Book the bytes successfully transferred. */
|
|
|
|
nbytes -= SECTOR_SIZE;
|
2006-11-27 15:21:43 +01:00
|
|
|
position= add64u(position, SECTOR_SIZE);
|
2006-06-20 10:51:24 +02:00
|
|
|
addr_offset += SECTOR_SIZE;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
total += SECTOR_SIZE;
|
2006-06-20 10:51:24 +02:00
|
|
|
if ((iov->iov_size -= SECTOR_SIZE) == 0) {
|
|
|
|
iov++;
|
|
|
|
nr_req--;
|
|
|
|
addr_offset = 0;
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Any errors? */
|
|
|
|
if (r != OK) {
|
|
|
|
/* Don't retry if sector marked bad or too many errors. */
|
2005-07-13 16:58:21 +02:00
|
|
|
if (r == ERR_BAD_SECTOR || ++errors == max_errors) {
|
2005-04-21 16:53:53 +02:00
|
|
|
w_command = CMD_IDLE;
|
|
|
|
return(EIO);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w_command = CMD_IDLE;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
return(total);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* com_out *
|
|
|
|
*===========================================================================*/
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int com_out(cmd)
|
|
|
|
struct command *cmd; /* Command block */
|
|
|
|
{
|
|
|
|
/* Output the command block to the winchester controller and return status */
|
|
|
|
|
|
|
|
struct wini *wn = w_wn;
|
2005-08-25 18:25:19 +02:00
|
|
|
unsigned base_cmd = wn->base_cmd;
|
|
|
|
unsigned base_ctl = wn->base_ctl;
|
2005-04-21 16:53:53 +02:00
|
|
|
pvb_pair_t outbyte[7]; /* vector for sys_voutb() */
|
|
|
|
int s; /* status for sys_(v)outb() */
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_wn->state & IGNORING) return ERR;
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) {
|
|
|
|
printf("%s: controller not ready\n", w_name());
|
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select drive. */
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_outb(base_cmd + REG_LDH, cmd->ldh)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't write register to select drive: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) {
|
2005-05-03 10:59:13 +02:00
|
|
|
printf("%s: com_out: drive not ready\n", w_name());
|
2005-04-21 16:53:53 +02:00
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
2009-09-29 20:47:56 +02:00
|
|
|
/* Schedule a wakeup call, some controllers are flaky. This is done with a
|
|
|
|
* synchronous alarm. If a timeout occurs a notify from CLOCK is sent, so that
|
|
|
|
* w_intr_wait() can call w_timeout() in case the controller was not able to
|
|
|
|
* execute the command. Leftover timeouts are simply ignored by the main loop.
|
2005-04-21 16:53:53 +02:00
|
|
|
*/
|
2005-07-29 17:00:22 +02:00
|
|
|
sys_setalarm(wakeup_ticks, 0);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->w_status = STATUS_ADMBSY;
|
2005-04-21 16:53:53 +02:00
|
|
|
w_command = cmd->command;
|
2005-08-25 18:25:19 +02:00
|
|
|
pv_set(outbyte[0], base_ctl + REG_CTL, wn->pheads >= 8 ? CTL_EIGHTHEADS : 0);
|
|
|
|
pv_set(outbyte[1], base_cmd + REG_PRECOMP, cmd->precomp);
|
|
|
|
pv_set(outbyte[2], base_cmd + REG_COUNT, cmd->count);
|
|
|
|
pv_set(outbyte[3], base_cmd + REG_SECTOR, cmd->sector);
|
|
|
|
pv_set(outbyte[4], base_cmd + REG_CYL_LO, cmd->cyl_lo);
|
|
|
|
pv_set(outbyte[5], base_cmd + REG_CYL_HI, cmd->cyl_hi);
|
|
|
|
pv_set(outbyte[6], base_cmd + REG_COMMAND, cmd->command);
|
2005-04-21 16:53:53 +02:00
|
|
|
if ((s=sys_voutb(outbyte,7)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't write registers with sys_voutb(): %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2006-02-24 13:55:47 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* com_out_ext *
|
|
|
|
*===========================================================================*/
|
|
|
|
PRIVATE int com_out_ext(cmd)
|
|
|
|
struct command *cmd; /* Command block */
|
|
|
|
{
|
|
|
|
/* Output the command block to the winchester controller and return status */
|
|
|
|
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
unsigned base_cmd = wn->base_cmd;
|
|
|
|
unsigned base_ctl = wn->base_ctl;
|
|
|
|
pvb_pair_t outbyte[11]; /* vector for sys_voutb() */
|
|
|
|
int s; /* status for sys_(v)outb() */
|
|
|
|
|
|
|
|
if (w_wn->state & IGNORING) return ERR;
|
|
|
|
|
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) {
|
|
|
|
printf("%s: controller not ready\n", w_name());
|
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select drive. */
|
|
|
|
if ((s=sys_outb(base_cmd + REG_LDH, cmd->ldh)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't write register to select drive: %d", s);
|
2006-02-24 13:55:47 +01:00
|
|
|
|
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) {
|
|
|
|
printf("%s: com_out: drive not ready\n", w_name());
|
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
2009-09-29 20:47:56 +02:00
|
|
|
/* Schedule a wakeup call, some controllers are flaky. This is done with a
|
|
|
|
* synchronous alarm. If a timeout occurs a notify from CLOCK is sent, so that
|
|
|
|
* w_intr_wait() can call w_timeout() in case the controller was not able to
|
|
|
|
* execute the command. Leftover timeouts are simply ignored by the main loop.
|
2006-02-24 13:55:47 +01:00
|
|
|
*/
|
|
|
|
sys_setalarm(wakeup_ticks, 0);
|
|
|
|
|
|
|
|
wn->w_status = STATUS_ADMBSY;
|
|
|
|
w_command = cmd->command;
|
|
|
|
pv_set(outbyte[0], base_ctl + REG_CTL, 0);
|
|
|
|
pv_set(outbyte[1], base_cmd + REG_COUNT, cmd->count_prev);
|
|
|
|
pv_set(outbyte[2], base_cmd + REG_SECTOR, cmd->sector_prev);
|
|
|
|
pv_set(outbyte[3], base_cmd + REG_CYL_LO, cmd->cyl_lo_prev);
|
|
|
|
pv_set(outbyte[4], base_cmd + REG_CYL_HI, cmd->cyl_hi_prev);
|
|
|
|
pv_set(outbyte[5], base_cmd + REG_COUNT, cmd->count);
|
|
|
|
pv_set(outbyte[6], base_cmd + REG_SECTOR, cmd->sector);
|
|
|
|
pv_set(outbyte[7], base_cmd + REG_CYL_LO, cmd->cyl_lo);
|
|
|
|
pv_set(outbyte[8], base_cmd + REG_CYL_HI, cmd->cyl_hi);
|
2007-02-23 21:58:10 +01:00
|
|
|
pv_set(outbyte[9], base_cmd + REG_COMMAND, cmd->command);
|
|
|
|
if ((s=sys_voutb(outbyte, 10)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't write registers with sys_voutb(): %d", s);
|
2006-02-24 13:55:47 +01:00
|
|
|
|
|
|
|
return(OK);
|
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* setup_dma *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int setup_dma(
|
|
|
|
unsigned *sizep,
|
|
|
|
endpoint_t proc_nr,
|
|
|
|
iovec_t *iov,
|
|
|
|
size_t addr_offset,
|
|
|
|
int UNUSED(do_write)
|
|
|
|
)
|
2006-03-03 16:37:51 +01:00
|
|
|
{
|
2011-06-08 21:24:41 +02:00
|
|
|
phys_bytes user_phys;
|
2006-03-03 16:37:51 +01:00
|
|
|
unsigned n, offset, size;
|
2011-06-08 21:24:41 +02:00
|
|
|
int i, j, r;
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t v;
|
2006-03-03 16:37:51 +01:00
|
|
|
struct wini *wn = w_wn;
|
2009-10-19 17:45:14 +02:00
|
|
|
int verbose = 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
/* First try direct scatter/gather to the supplied buffers */
|
|
|
|
size= *sizep;
|
|
|
|
i= 0; /* iov index */
|
|
|
|
j= 0; /* prdt index */
|
|
|
|
offset= 0; /* Offset in current iov */
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if(verbose)
|
|
|
|
printf("at_wini: setup_dma: proc_nr %d\n", proc_nr);
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
while (size > 0)
|
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if(verbose) {
|
|
|
|
printf(
|
|
|
|
"at_wini: setup_dma: iov[%d]: addr 0x%lx, size %ld offset %d, size %d\n",
|
2006-03-03 16:37:51 +01:00
|
|
|
i, iov[i].iov_addr, iov[i].iov_size, offset, size);
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
n= iov[i].iov_size-offset;
|
|
|
|
if (n > size)
|
|
|
|
n= size;
|
|
|
|
if (n == 0 || (n & 1))
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("bad size in iov: %d", iov[i].iov_size);
|
2009-12-02 10:57:48 +01:00
|
|
|
if(proc_nr != SELF) {
|
|
|
|
r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,
|
|
|
|
&user_phys);
|
|
|
|
if (r != 0)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("can't map user buffer (VM_GRANT): %d", r);
|
2009-12-02 10:57:48 +01:00
|
|
|
user_phys += offset + addr_offset;
|
2006-06-20 10:51:24 +02:00
|
|
|
} else {
|
2009-12-02 10:57:48 +01:00
|
|
|
r= sys_umap(proc_nr, VM_D,
|
|
|
|
iov[i].iov_addr+offset+addr_offset, n,
|
|
|
|
&user_phys);
|
|
|
|
if (r != 0)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("can't map user buffer (VM_D): %d", r);
|
2008-11-19 13:26:10 +01:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
if (user_phys & 1)
|
|
|
|
{
|
|
|
|
/* Buffer is not aligned */
|
|
|
|
printf("setup_dma: user buffer is not aligned\n");
|
2011-06-08 21:24:41 +02:00
|
|
|
return 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* vector is not allowed to cross a 64K boundary */
|
|
|
|
if (user_phys/0x10000 != (user_phys+n-1)/0x10000)
|
|
|
|
n= ((user_phys/0x10000)+1)*0x10000 - user_phys;
|
|
|
|
|
|
|
|
/* vector is not allowed to be bigger than 64K, but we get that
|
|
|
|
* for free.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (j >= N_PRDTE)
|
|
|
|
{
|
|
|
|
/* Too many entries */
|
2011-06-08 21:24:41 +02:00
|
|
|
printf("setup_dma: user buffer has too many entries\n");
|
|
|
|
return 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
prdt[j].prdte_base= user_phys;
|
|
|
|
prdt[j].prdte_count= n;
|
|
|
|
prdt[j].prdte_reserved= 0;
|
|
|
|
prdt[j].prdte_flags= 0;
|
|
|
|
j++;
|
|
|
|
|
|
|
|
offset += n;
|
|
|
|
if (offset >= iov[i].iov_size)
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
offset= 0;
|
2009-05-08 14:29:57 +02:00
|
|
|
addr_offset= 0;
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
size -= n;
|
|
|
|
}
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (j <= 0 || j > N_PRDTE)
|
|
|
|
panic("bad prdt index: %d", j);
|
|
|
|
prdt[j-1].prdte_flags |= PRDTE_FL_EOT;
|
2006-03-03 16:37:51 +01:00
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if(verbose) {
|
2009-10-19 17:45:14 +02:00
|
|
|
printf("dma not bad\n");
|
|
|
|
for (i= 0; i<j; i++) {
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("prdt[%d]: base 0x%lx, size %d, flags 0x%x\n",
|
2006-03-03 16:37:51 +01:00
|
|
|
i, prdt[i].prdte_base, prdt[i].prdte_count,
|
|
|
|
prdt[i].prdte_flags);
|
|
|
|
}
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
/* Verify that the bus master is not active */
|
|
|
|
r= sys_inb(wn->base_dma + DMA_STATUS, &v);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("setup_dma: sys_inb failed: %d", r);
|
2006-03-03 16:37:51 +01:00
|
|
|
if (v & DMA_ST_BM_ACTIVE)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Bus master IDE active");
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
if (prdt_phys & 3)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("prdt not aligned: %d", prdt_phys);
|
2006-03-03 16:37:51 +01:00
|
|
|
r= sys_outl(wn->base_dma + DMA_PRDTP, prdt_phys);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("setup_dma: sys_outl failed: %d", r);
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
/* Clear interrupt and error flags */
|
|
|
|
r= sys_outb(wn->base_dma + DMA_STATUS, DMA_ST_INT | DMA_ST_ERROR);
|
2010-03-05 16:05:11 +01:00
|
|
|
if (r != 0) panic("setup_dma: sys_outb failed: %d", r);
|
2009-10-19 17:45:14 +02:00
|
|
|
|
2011-06-08 21:24:41 +02:00
|
|
|
return 1;
|
2006-03-03 16:37:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_need_reset *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void w_need_reset(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* The controller needs to be reset. */
|
|
|
|
struct wini *wn;
|
|
|
|
|
2010-02-19 11:00:32 +01:00
|
|
|
for (wn = wini; wn < &wini[MAX_DRIVES]; wn++) {
|
2005-08-25 18:25:19 +02:00
|
|
|
if (wn->base_cmd == w_wn->base_cmd) {
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->state |= DEAF;
|
|
|
|
wn->state &= ~INITIALIZED;
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_do_close *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_do_close(dev_t minor)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Device close: Release a device. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (w_prepare(minor) == NULL)
|
2005-08-25 10:19:11 +02:00
|
|
|
return(ENXIO);
|
2005-04-21 16:53:53 +02:00
|
|
|
w_wn->open_ct--;
|
|
|
|
#if ENABLE_ATAPI
|
|
|
|
if (w_wn->open_ct == 0 && (w_wn->state & ATAPI)) atapi_close();
|
|
|
|
#endif
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* com_simple *
|
|
|
|
*===========================================================================*/
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int com_simple(cmd)
|
|
|
|
struct command *cmd; /* Command block */
|
|
|
|
{
|
|
|
|
/* A simple controller command, only one interrupt and no data-out phase. */
|
|
|
|
int r;
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_wn->state & IGNORING) return ERR;
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
if ((r = com_out(cmd)) == OK) r = at_intr_wait();
|
|
|
|
w_command = CMD_IDLE;
|
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* w_timeout *
|
|
|
|
*===========================================================================*/
|
|
|
|
PRIVATE void w_timeout(void)
|
|
|
|
{
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
|
|
|
|
switch (w_command) {
|
|
|
|
case CMD_IDLE:
|
|
|
|
break; /* fine */
|
|
|
|
case CMD_READ:
|
2006-02-24 13:55:47 +01:00
|
|
|
case CMD_READ_EXT:
|
2005-04-21 16:53:53 +02:00
|
|
|
case CMD_WRITE:
|
2006-02-24 13:55:47 +01:00
|
|
|
case CMD_WRITE_EXT:
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Impossible, but not on PC's: The controller does not respond. */
|
|
|
|
|
|
|
|
/* Limiting multisector I/O seems to help. */
|
|
|
|
if (wn->max_count > 8 * SECTOR_SIZE) {
|
|
|
|
wn->max_count = 8 * SECTOR_SIZE;
|
|
|
|
} else {
|
|
|
|
wn->max_count = SECTOR_SIZE;
|
|
|
|
}
|
|
|
|
/*FALL THROUGH*/
|
|
|
|
default:
|
|
|
|
/* Some other command. */
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_testing) wn->state |= IGNORING; /* Kick out this drive. */
|
2006-02-24 13:55:47 +01:00
|
|
|
else if (!w_silent) printf("%s: timeout on command 0x%02x\n",
|
|
|
|
w_name(), w_command);
|
2005-04-21 16:53:53 +02:00
|
|
|
w_need_reset();
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->w_status = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* w_reset *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_reset(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Issue a reset to the controller. This is done after any catastrophe,
|
|
|
|
* like the controller refusing to respond.
|
|
|
|
*/
|
|
|
|
int s;
|
2005-08-04 10:08:58 +02:00
|
|
|
struct wini *wn = w_wn;
|
|
|
|
|
|
|
|
/* Don't bother if this drive is forgotten. */
|
2005-09-11 19:09:11 +02:00
|
|
|
if (w_wn->state & IGNORING) return ERR;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Wait for any internal drive recovery. */
|
2005-06-01 16:31:00 +02:00
|
|
|
tickdelay(RECOVERY_TICKS);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Strobe reset bit */
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_outb(wn->base_ctl + REG_CTL, CTL_RESET)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't strobe reset bit: %d", s);
|
2005-06-01 16:31:00 +02:00
|
|
|
tickdelay(DELAY_TICKS);
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_outb(wn->base_ctl + REG_CTL, 0)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't strobe reset bit: %d", s);
|
2005-06-01 16:31:00 +02:00
|
|
|
tickdelay(DELAY_TICKS);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Wait for controller ready */
|
|
|
|
if (!w_waitfor(STATUS_BSY, 0)) {
|
|
|
|
printf("%s: reset failed, drive busy\n", w_name());
|
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The error register should be checked now, but some drives mess it up. */
|
|
|
|
|
|
|
|
for (wn = wini; wn < &wini[MAX_DRIVES]; wn++) {
|
2005-08-25 18:25:19 +02:00
|
|
|
if (wn->base_cmd == w_wn->base_cmd) {
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->state &= ~DEAF;
|
|
|
|
if (w_wn->irq_need_ack) {
|
|
|
|
/* Make sure irq is actually enabled.. */
|
|
|
|
sys_irqenable(&w_wn->irq_hook_id);
|
|
|
|
}
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_intr_wait *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void w_intr_wait(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Wait for a task completion interrupt. */
|
|
|
|
|
2006-02-24 13:55:47 +01:00
|
|
|
int r;
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t w_status;
|
2005-04-21 16:53:53 +02:00
|
|
|
message m;
|
2010-04-08 15:41:35 +02:00
|
|
|
int ipc_status;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (w_wn->irq != NO_IRQ) {
|
2007-01-12 14:33:12 +01:00
|
|
|
/* Wait for an interrupt that sets w_status to "not busy".
|
|
|
|
* (w_timeout() also clears w_status.)
|
|
|
|
*/
|
2005-08-25 10:19:11 +02:00
|
|
|
while (w_wn->w_status & (STATUS_ADMBSY|STATUS_BSY)) {
|
2006-03-07 16:45:14 +01:00
|
|
|
int rr;
|
2010-04-08 15:41:35 +02:00
|
|
|
if((rr=driver_receive(ANY, &m, &ipc_status)) != OK)
|
|
|
|
panic("driver_receive failed: %d", rr);
|
|
|
|
if (is_ipc_notify(ipc_status)) {
|
2009-09-29 20:47:56 +02:00
|
|
|
switch (_ENDPOINT_P(m.m_source)) {
|
|
|
|
case CLOCK:
|
|
|
|
/* Timeout. */
|
|
|
|
w_timeout(); /* a.o. set w_status */
|
|
|
|
break;
|
|
|
|
case HARDWARE:
|
|
|
|
/* Interrupt. */
|
|
|
|
r= sys_inb(w_wn->base_cmd +
|
|
|
|
REG_STATUS, &w_status);
|
|
|
|
if (r != 0)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_inb failed: %d", r);
|
2009-09-29 20:47:56 +02:00
|
|
|
w_wn->w_status= w_status;
|
|
|
|
ack_irqs(m.NOTIFY_ARG);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* unhandled message. queue it and
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
* handle it in the blockdriver loop.
|
2009-09-29 20:47:56 +02:00
|
|
|
*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
blockdriver_mq_queue(&m, ipc_status);
|
2009-09-29 20:47:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* unhandled message. queue it and handle it in the
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
* blockdriver loop.
|
2007-01-12 14:33:12 +01:00
|
|
|
*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
blockdriver_mq_queue(&m, ipc_status);
|
2006-03-07 16:45:14 +01:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Interrupt not yet allocated; use polling. */
|
|
|
|
(void) w_waitfor(STATUS_BSY, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* at_intr_wait *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int at_intr_wait(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Wait for an interrupt, study the status bits and return error/success. */
|
2006-02-24 13:55:47 +01:00
|
|
|
int r, s;
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t inbval;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
w_intr_wait();
|
2005-08-25 10:19:11 +02:00
|
|
|
if ((w_wn->w_status & (STATUS_BSY | STATUS_WF | STATUS_ERR)) == 0) {
|
2005-04-21 16:53:53 +02:00
|
|
|
r = OK;
|
|
|
|
} else {
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_inb(w_wn->base_cmd + REG_ERROR, &inbval)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't read register: %d", s);
|
2005-08-25 10:19:11 +02:00
|
|
|
if ((w_wn->w_status & STATUS_ERR) && (inbval & ERROR_BB)) {
|
2005-04-21 16:53:53 +02:00
|
|
|
r = ERR_BAD_SECTOR; /* sector marked bad, retries won't help */
|
|
|
|
} else {
|
|
|
|
r = ERR; /* any other error */
|
|
|
|
}
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
w_wn->w_status |= STATUS_ADMBSY; /* assume still busy with I/O */
|
2005-04-21 16:53:53 +02:00
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_waitfor *
|
|
|
|
*===========================================================================*/
|
2005-04-21 16:53:53 +02:00
|
|
|
PRIVATE int w_waitfor(mask, value)
|
|
|
|
int mask; /* status mask */
|
|
|
|
int value; /* required status */
|
|
|
|
{
|
|
|
|
/* Wait until controller is in the required state. Return zero on timeout.
|
|
|
|
*/
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t w_status;
|
2010-07-13 01:14:40 +02:00
|
|
|
spin_t spin;
|
2005-04-21 16:53:53 +02:00
|
|
|
int s;
|
2006-02-24 13:55:47 +01:00
|
|
|
|
2010-07-13 01:14:40 +02:00
|
|
|
SPIN_FOR(&spin, timeout_usecs) {
|
2006-02-24 13:55:47 +01:00
|
|
|
if ((s=sys_inb(w_wn->base_cmd + REG_STATUS, &w_status)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't read register: %d", s);
|
2006-02-24 13:55:47 +01:00
|
|
|
w_wn->w_status= w_status;
|
2005-08-25 10:19:11 +02:00
|
|
|
if ((w_wn->w_status & mask) == value) {
|
2005-04-21 16:53:53 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2010-07-13 01:14:40 +02:00
|
|
|
}
|
2005-05-31 16:43:04 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
w_need_reset(); /* controller gone deaf */
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2006-03-03 16:37:51 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_waitfor_dma *
|
|
|
|
*===========================================================================*/
|
|
|
|
PRIVATE int w_waitfor_dma(mask, value)
|
|
|
|
int mask; /* status mask */
|
|
|
|
int value; /* required status */
|
|
|
|
{
|
|
|
|
/* Wait until controller is in the required state. Return zero on timeout.
|
|
|
|
*/
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t w_status;
|
2010-07-13 01:14:40 +02:00
|
|
|
spin_t spin;
|
2006-03-03 16:37:51 +01:00
|
|
|
int s;
|
|
|
|
|
2010-07-13 01:14:40 +02:00
|
|
|
SPIN_FOR(&spin, timeout_usecs) {
|
2006-03-03 16:37:51 +01:00
|
|
|
if ((s=sys_inb(w_wn->base_dma + DMA_STATUS, &w_status)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't read register: %d", s);
|
2006-03-03 16:37:51 +01:00
|
|
|
if ((w_status & mask) == value) {
|
|
|
|
return 1;
|
|
|
|
}
|
2010-07-13 01:14:40 +02:00
|
|
|
}
|
2006-03-03 16:37:51 +01:00
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_geometry *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void w_geometry(dev_t minor, struct partition *entry)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
struct wini *wn;
|
|
|
|
|
|
|
|
if (w_prepare(minor) == NULL) return;
|
|
|
|
|
|
|
|
wn = w_wn;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (wn->state & ATAPI) { /* Make up some numbers. */
|
|
|
|
entry->cylinders = div64u(wn->part[0].dv_size, SECTOR_SIZE) / (64*32);
|
|
|
|
entry->heads = 64;
|
|
|
|
entry->sectors = 32;
|
|
|
|
} else { /* Return logical geometry. */
|
|
|
|
entry->cylinders = wn->lcylinders;
|
|
|
|
entry->heads = wn->lheads;
|
|
|
|
entry->sectors = wn->lsectors;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if ENABLE_ATAPI
|
|
|
|
/*===========================================================================*
|
|
|
|
* atapi_open *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int atapi_open(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Should load and lock the device and obtain its size. For now just set the
|
|
|
|
* size of the device to something big. What is really needed is a generic
|
|
|
|
* SCSI layer that does all this stuff for ATAPI and SCSI devices (kjb). (XXX)
|
|
|
|
*/
|
|
|
|
w_wn->part[0].dv_size = mul64u(800L*1024, 1024);
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* atapi_close *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void atapi_close(void)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Should unlock the device. For now do nothing. (XXX) */
|
|
|
|
}
|
|
|
|
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE void sense_request(void)
|
2005-08-26 21:39:00 +02:00
|
|
|
{
|
|
|
|
int r, i;
|
|
|
|
static u8_t sense[100], packet[ATAPI_PACKETSIZE];
|
|
|
|
|
|
|
|
packet[0] = SCSI_SENSE;
|
|
|
|
packet[1] = 0;
|
|
|
|
packet[2] = 0;
|
|
|
|
packet[3] = 0;
|
|
|
|
packet[4] = SENSE_PACKETSIZE;
|
|
|
|
packet[5] = 0;
|
|
|
|
packet[7] = 0;
|
|
|
|
packet[8] = 0;
|
|
|
|
packet[9] = 0;
|
|
|
|
packet[10] = 0;
|
|
|
|
packet[11] = 0;
|
|
|
|
|
|
|
|
for(i = 0; i < SENSE_PACKETSIZE; i++) sense[i] = 0xff;
|
2009-10-19 17:45:14 +02:00
|
|
|
r = atapi_sendpacket(packet, SENSE_PACKETSIZE, 0);
|
2005-08-26 21:39:00 +02:00
|
|
|
if (r != OK) { printf("request sense command failed\n"); return; }
|
2009-10-19 17:45:14 +02:00
|
|
|
if (atapi_intr_wait(0, 0) <= 0) { printf("WARNING: request response failed\n"); }
|
2005-08-26 21:39:00 +02:00
|
|
|
|
|
|
|
if (sys_insw(w_wn->base_cmd + REG_DATA, SELF, (void *) sense, SENSE_PACKETSIZE) != OK)
|
|
|
|
printf("WARNING: sense reading failed\n");
|
|
|
|
|
|
|
|
printf("sense data:");
|
|
|
|
for(i = 0; i < SENSE_PACKETSIZE; i++) printf(" %02x", sense[i]);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* atapi_transfer *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int atapi_transfer(
|
|
|
|
int do_write, /* read or write? */
|
|
|
|
u64_t position, /* offset on device to read or write */
|
|
|
|
endpoint_t proc_nr, /* process doing the request */
|
|
|
|
iovec_t *iov, /* pointer to read or write request vector */
|
|
|
|
unsigned int nr_req /* length of request vector */
|
|
|
|
)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
iovec_t *iop, *iov_end = iov + nr_req;
|
|
|
|
int r, s, errors, fresh;
|
|
|
|
u64_t pos;
|
|
|
|
unsigned long block;
|
2006-11-27 15:21:43 +01:00
|
|
|
u64_t dv_size = w_dv->dv_size;
|
2009-10-19 17:45:14 +02:00
|
|
|
unsigned nbytes, nblocks, before, chunk;
|
2005-08-26 21:39:00 +02:00
|
|
|
static u8_t packet[ATAPI_PACKETSIZE];
|
2006-06-20 10:51:24 +02:00
|
|
|
size_t addr_offset = 0;
|
2009-10-19 17:45:14 +02:00
|
|
|
int dmabytes = 0, piobytes = 0;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
ssize_t total = 0;
|
|
|
|
|
|
|
|
if (do_write) return(EINVAL);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
errors = fresh = 0;
|
|
|
|
|
|
|
|
while (nr_req > 0 && !fresh) {
|
2009-10-19 17:45:14 +02:00
|
|
|
int do_dma = wn->dma && w_atapi_dma;
|
2005-04-21 16:53:53 +02:00
|
|
|
/* The Minix block size is smaller than the CD block size, so we
|
|
|
|
* may have to read extra before or after the good data.
|
|
|
|
*/
|
2006-11-27 15:21:43 +01:00
|
|
|
pos = add64(w_dv->dv_base, position);
|
2005-04-21 16:53:53 +02:00
|
|
|
block = div64u(pos, CD_SECTOR_SIZE);
|
|
|
|
before = rem64u(pos, CD_SECTOR_SIZE);
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if(before)
|
|
|
|
do_dma = 0;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* How many bytes to transfer? */
|
2009-10-19 17:45:14 +02:00
|
|
|
nbytes = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
for (iop = iov; iop < iov_end; iop++) {
|
|
|
|
nbytes += iop->iov_size;
|
2009-10-19 17:45:14 +02:00
|
|
|
if(iop->iov_size % CD_SECTOR_SIZE)
|
|
|
|
do_dma = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Data comes in as words, so we have to enforce even byte counts. */
|
|
|
|
if ((before | nbytes) & 1) return(EINVAL);
|
|
|
|
|
|
|
|
/* Which block on disk and how close to EOF? */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (cmp64(position, dv_size) >= 0) return(total); /* At EOF */
|
2006-11-27 15:21:43 +01:00
|
|
|
if (cmp64(add64ul(position, nbytes), dv_size) > 0)
|
|
|
|
nbytes = diff64(dv_size, position);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
nblocks = (before + nbytes + CD_SECTOR_SIZE - 1) / CD_SECTOR_SIZE;
|
|
|
|
|
|
|
|
/* First check to see if a reinitialization is needed. */
|
|
|
|
if (!(wn->state & INITIALIZED) && w_specify() != OK) return(EIO);
|
|
|
|
|
|
|
|
/* Build an ATAPI command packet. */
|
|
|
|
packet[0] = SCSI_READ10;
|
|
|
|
packet[1] = 0;
|
|
|
|
packet[2] = (block >> 24) & 0xFF;
|
|
|
|
packet[3] = (block >> 16) & 0xFF;
|
|
|
|
packet[4] = (block >> 8) & 0xFF;
|
|
|
|
packet[5] = (block >> 0) & 0xFF;
|
2006-08-28 17:10:10 +02:00
|
|
|
packet[6] = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
packet[7] = (nblocks >> 8) & 0xFF;
|
|
|
|
packet[8] = (nblocks >> 0) & 0xFF;
|
|
|
|
packet[9] = 0;
|
|
|
|
packet[10] = 0;
|
|
|
|
packet[11] = 0;
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if(do_dma) {
|
|
|
|
stop_dma(wn);
|
2011-06-08 21:24:41 +02:00
|
|
|
if (!setup_dma(&nbytes, proc_nr, iov, addr_offset, 0)) {
|
|
|
|
do_dma = 0;
|
|
|
|
} else if(nbytes != nblocks * CD_SECTOR_SIZE) {
|
2009-10-19 17:45:14 +02:00
|
|
|
stop_dma(wn);
|
|
|
|
do_dma = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Tell the controller to execute the packet command. */
|
2009-10-19 17:45:14 +02:00
|
|
|
r = atapi_sendpacket(packet, nblocks * CD_SECTOR_SIZE, do_dma);
|
2005-04-21 16:53:53 +02:00
|
|
|
if (r != OK) goto err;
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if(do_dma) {
|
|
|
|
wn->dma_intseen = 0;
|
|
|
|
start_dma(wn, 0);
|
|
|
|
w_intr_wait();
|
|
|
|
if(!wn->dma_intseen) {
|
|
|
|
if(w_waitfor_dma(DMA_ST_INT, DMA_ST_INT)) {
|
|
|
|
wn->dma_intseen = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(error_dma(wn)) {
|
|
|
|
printf("Disabling DMA (ATAPI)\n");
|
|
|
|
wn->dma = 0;
|
|
|
|
} else {
|
|
|
|
dmabytes += nbytes;
|
|
|
|
while (nbytes > 0) {
|
2010-03-30 16:07:15 +02:00
|
|
|
vir_bytes chunk = nbytes;
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
if (chunk > iov->iov_size)
|
|
|
|
chunk = iov->iov_size;
|
|
|
|
position= add64ul(position, chunk);
|
|
|
|
nbytes -= chunk;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
total += chunk;
|
2009-10-19 17:45:14 +02:00
|
|
|
if ((iov->iov_size -= chunk) == 0) {
|
|
|
|
iov++;
|
|
|
|
nr_req--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Read chunks of data. */
|
2009-10-19 17:45:14 +02:00
|
|
|
while ((r = atapi_intr_wait(do_dma, nblocks * CD_SECTOR_SIZE)) > 0) {
|
|
|
|
size_t count;
|
2005-04-21 16:53:53 +02:00
|
|
|
count = r;
|
|
|
|
|
|
|
|
while (before > 0 && count > 0) { /* Discard before. */
|
|
|
|
chunk = before;
|
|
|
|
if (chunk > count) chunk = count;
|
|
|
|
if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
|
2009-10-19 17:45:14 +02:00
|
|
|
if ((s=sys_insw(wn->base_cmd + REG_DATA,
|
|
|
|
SELF, tmp_buf, chunk)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
before -= chunk;
|
|
|
|
count -= chunk;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nbytes > 0 && count > 0) { /* Requested data. */
|
|
|
|
chunk = nbytes;
|
|
|
|
if (chunk > count) chunk = count;
|
|
|
|
if (chunk > iov->iov_size) chunk = iov->iov_size;
|
2009-12-02 10:57:48 +01:00
|
|
|
if(proc_nr != SELF) {
|
|
|
|
s=sys_safe_insw(wn->base_cmd + REG_DATA,
|
|
|
|
proc_nr, (void *) iov->iov_addr,
|
|
|
|
addr_offset, chunk);
|
2006-06-20 10:51:24 +02:00
|
|
|
} else {
|
|
|
|
s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
|
2009-12-02 10:57:48 +01:00
|
|
|
(void *) (iov->iov_addr + addr_offset),
|
|
|
|
chunk);
|
2006-06-20 10:51:24 +02:00
|
|
|
}
|
|
|
|
if (s != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2006-11-27 15:21:43 +01:00
|
|
|
position= add64ul(position, chunk);
|
2005-04-21 16:53:53 +02:00
|
|
|
nbytes -= chunk;
|
|
|
|
count -= chunk;
|
2006-06-20 10:51:24 +02:00
|
|
|
addr_offset += chunk;
|
2009-10-19 17:45:14 +02:00
|
|
|
piobytes += chunk;
|
2005-04-21 16:53:53 +02:00
|
|
|
fresh = 0;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
total += chunk;
|
2005-04-21 16:53:53 +02:00
|
|
|
if ((iov->iov_size -= chunk) == 0) {
|
|
|
|
iov++;
|
|
|
|
nr_req--;
|
|
|
|
fresh = 1; /* new element is optional */
|
2006-06-20 10:51:24 +02:00
|
|
|
addr_offset = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2009-10-19 17:45:14 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
while (count > 0) { /* Excess data. */
|
|
|
|
chunk = count;
|
|
|
|
if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
|
2009-10-19 17:45:14 +02:00
|
|
|
if ((s=sys_insw(wn->base_cmd + REG_DATA,
|
|
|
|
SELF, tmp_buf, chunk)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Call to sys_insw() failed: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
count -= chunk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r < 0) {
|
|
|
|
err: /* Don't retry if too many errors. */
|
2005-09-11 19:09:11 +02:00
|
|
|
if (atapi_debug) sense_request();
|
2005-07-13 16:58:21 +02:00
|
|
|
if (++errors == max_errors) {
|
2005-04-21 16:53:53 +02:00
|
|
|
w_command = CMD_IDLE;
|
2005-09-11 19:09:11 +02:00
|
|
|
if (atapi_debug) printf("giving up (%d)\n", errors);
|
2005-04-21 16:53:53 +02:00
|
|
|
return(EIO);
|
|
|
|
}
|
2005-09-11 19:09:11 +02:00
|
|
|
if (atapi_debug) printf("retry (%d)\n", errors);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-19 17:45:14 +02:00
|
|
|
#if 0
|
|
|
|
if(dmabytes) printf("dmabytes %d ", dmabytes);
|
|
|
|
if(piobytes) printf("piobytes %d", piobytes);
|
|
|
|
if(dmabytes || piobytes) printf("\n");
|
|
|
|
#endif
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
w_command = CMD_IDLE;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
return(total);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* atapi_sendpacket *
|
|
|
|
*===========================================================================*/
|
2009-10-19 17:45:14 +02:00
|
|
|
PRIVATE int atapi_sendpacket(packet, cnt, do_dma)
|
2005-04-21 16:53:53 +02:00
|
|
|
u8_t *packet;
|
|
|
|
unsigned cnt;
|
2009-10-19 17:45:14 +02:00
|
|
|
int do_dma;
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Send an Atapi Packet Command */
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
pvb_pair_t outbyte[6]; /* vector for sys_voutb() */
|
|
|
|
int s;
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (wn->state & IGNORING) return ERR;
|
2005-08-04 10:08:58 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Select Master/Slave drive */
|
2005-08-25 18:25:19 +02:00
|
|
|
if ((s=sys_outb(wn->base_cmd + REG_DRIVE, wn->ldhpref)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't select master/ slave drive: %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (!w_waitfor(STATUS_BSY | STATUS_DRQ, 0)) {
|
2005-05-03 10:59:13 +02:00
|
|
|
printf("%s: atapi_sendpacket: drive not ready\n", w_name());
|
2005-04-21 16:53:53 +02:00
|
|
|
return(ERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Schedule a wakeup call, some controllers are flaky. This is done with
|
|
|
|
* a synchronous alarm. If a timeout occurs a SYN_ALARM message is sent
|
|
|
|
* from HARDWARE, so that w_intr_wait() can call w_timeout() in case the
|
|
|
|
* controller was not able to execute the command. Leftover timeouts are
|
|
|
|
* simply ignored by the main loop.
|
|
|
|
*/
|
2005-07-29 17:00:22 +02:00
|
|
|
sys_setalarm(wakeup_ticks, 0);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
#if _WORD_SIZE > 2
|
|
|
|
if (cnt > 0xFFFE) cnt = 0xFFFE; /* Max data per interrupt. */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
w_command = ATAPI_PACKETCMD;
|
2009-10-19 17:45:14 +02:00
|
|
|
pv_set(outbyte[0], wn->base_cmd + REG_FEAT, do_dma ? FEAT_DMA : 0);
|
2005-08-25 18:25:19 +02:00
|
|
|
pv_set(outbyte[1], wn->base_cmd + REG_IRR, 0);
|
|
|
|
pv_set(outbyte[2], wn->base_cmd + REG_SAMTAG, 0);
|
|
|
|
pv_set(outbyte[3], wn->base_cmd + REG_CNT_LO, (cnt >> 0) & 0xFF);
|
|
|
|
pv_set(outbyte[4], wn->base_cmd + REG_CNT_HI, (cnt >> 8) & 0xFF);
|
|
|
|
pv_set(outbyte[5], wn->base_cmd + REG_COMMAND, w_command);
|
2005-09-11 19:09:11 +02:00
|
|
|
if (atapi_debug) printf("cmd: %x ", w_command);
|
2005-04-21 16:53:53 +02:00
|
|
|
if ((s=sys_voutb(outbyte,6)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("Couldn't write registers with sys_voutb(): %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (!w_waitfor(STATUS_BSY | STATUS_DRQ, STATUS_DRQ)) {
|
2005-08-25 15:14:02 +02:00
|
|
|
printf("%s: timeout (BSY|DRQ -> DRQ)\n", w_name());
|
2005-04-21 16:53:53 +02:00
|
|
|
return(ERR);
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->w_status |= STATUS_ADMBSY; /* Command not at all done yet. */
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Send the command packet to the device. */
|
2005-08-26 21:39:00 +02:00
|
|
|
if ((s=sys_outsw(wn->base_cmd + REG_DATA, SELF, packet, ATAPI_PACKETSIZE)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_outsw() failed: %d", s);
|
2005-08-26 21:39:00 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
2005-09-16 11:43:02 +02:00
|
|
|
|
|
|
|
#endif /* ENABLE_ATAPI */
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
* w_ioctl *
|
2005-09-11 19:09:11 +02:00
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int w_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
|
|
|
|
cp_grant_id_t grant)
|
2005-07-13 16:58:21 +02:00
|
|
|
{
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
int r, timeout, prev, count;
|
2010-08-12 16:09:34 +02:00
|
|
|
struct command cmd;
|
2005-07-13 16:58:21 +02:00
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
switch (request) {
|
|
|
|
case DIOCTIMEOUT:
|
|
|
|
r= sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&timeout,
|
|
|
|
sizeof(timeout), D);
|
2006-06-20 10:51:24 +02:00
|
|
|
|
|
|
|
if(r != OK)
|
|
|
|
return r;
|
2005-08-25 11:47:31 +02:00
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (timeout == 0) {
|
2005-08-25 11:47:31 +02:00
|
|
|
/* Restore defaults. */
|
2010-07-13 01:14:40 +02:00
|
|
|
timeout_usecs = DEF_TIMEOUT_USECS;
|
2005-08-25 11:47:31 +02:00
|
|
|
max_errors = MAX_ERRORS;
|
2007-02-09 16:58:33 +01:00
|
|
|
wakeup_ticks = WAKEUP_TICKS;
|
2005-08-25 11:47:31 +02:00
|
|
|
w_silent = 0;
|
2005-09-11 19:09:11 +02:00
|
|
|
} else if (timeout < 0) {
|
2005-08-25 11:47:31 +02:00
|
|
|
return EINVAL;
|
|
|
|
} else {
|
|
|
|
prev = wakeup_ticks;
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
if (!w_standard_timeouts) {
|
2005-08-25 11:47:31 +02:00
|
|
|
/* Set (lower) timeout, lower error
|
|
|
|
* tolerance and set silent mode.
|
|
|
|
*/
|
|
|
|
wakeup_ticks = timeout;
|
|
|
|
max_errors = 3;
|
|
|
|
w_silent = 1;
|
2010-07-13 01:14:40 +02:00
|
|
|
|
|
|
|
timeout = timeout * 1000000 / sys_hz();
|
2005-08-25 11:47:31 +02:00
|
|
|
|
2010-07-13 01:14:40 +02:00
|
|
|
if (timeout_usecs > timeout)
|
|
|
|
timeout_usecs = timeout;
|
2005-08-25 11:47:31 +02:00
|
|
|
}
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&prev,
|
|
|
|
sizeof(prev), D);
|
2006-06-20 10:51:24 +02:00
|
|
|
|
|
|
|
if(r != OK)
|
2005-08-25 11:47:31 +02:00
|
|
|
return r;
|
2005-08-09 14:42:53 +02:00
|
|
|
}
|
2005-08-25 11:47:31 +02:00
|
|
|
|
|
|
|
return OK;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
|
|
|
|
case DIOCOPENCT:
|
|
|
|
if (w_prepare(minor) == NULL) return ENXIO;
|
2005-08-25 11:47:31 +02:00
|
|
|
count = w_wn->open_ct;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&count,
|
|
|
|
sizeof(count), D);
|
2006-06-20 10:51:24 +02:00
|
|
|
|
|
|
|
if(r != OK)
|
2005-08-05 15:50:50 +02:00
|
|
|
return r;
|
2006-06-20 10:51:24 +02:00
|
|
|
|
2005-08-25 11:47:31 +02:00
|
|
|
return OK;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
|
|
|
|
case DIOCFLUSH:
|
|
|
|
if (w_prepare(minor) == NULL) return ENXIO;
|
2010-08-12 16:09:34 +02:00
|
|
|
|
|
|
|
if (w_wn->state & ATAPI) return EINVAL;
|
|
|
|
|
|
|
|
if (!(w_wn->state & INITIALIZED) && w_specify() != OK)
|
|
|
|
return EIO;
|
|
|
|
|
|
|
|
cmd.command = CMD_FLUSH_CACHE;
|
|
|
|
|
|
|
|
if (com_simple(&cmd) != OK || !w_waitfor(STATUS_BSY, 0))
|
|
|
|
return EIO;
|
|
|
|
|
|
|
|
return (w_wn->w_status & (STATUS_ERR|STATUS_WF)) ? EIO : OK;
|
2005-08-05 15:50:50 +02:00
|
|
|
}
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
|
2005-08-25 11:47:31 +02:00
|
|
|
return EINVAL;
|
2005-07-13 16:58:21 +02:00
|
|
|
}
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* w_hw_int *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE void w_hw_int(unsigned int irqs)
|
2005-08-25 10:19:11 +02:00
|
|
|
{
|
|
|
|
/* Leftover interrupt(s) received; ack it/them. */
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
ack_irqs(irqs);
|
2005-08-25 10:19:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* ack_irqs *
|
|
|
|
*===========================================================================*/
|
2005-08-25 10:19:11 +02:00
|
|
|
PRIVATE void ack_irqs(unsigned int irqs)
|
|
|
|
{
|
|
|
|
unsigned int drive;
|
2012-03-05 00:11:41 +01:00
|
|
|
u32_t w_status;
|
2006-02-24 13:55:47 +01:00
|
|
|
|
2009-10-19 16:23:04 +02:00
|
|
|
for (drive = 0; drive < MAX_DRIVES; drive++) {
|
2005-09-11 19:09:11 +02:00
|
|
|
if (!(wini[drive].state & IGNORING) && wini[drive].irq_need_ack &&
|
2009-10-19 16:23:04 +02:00
|
|
|
((1L << wini[drive].irq) & irqs)) {
|
2006-02-24 13:55:47 +01:00
|
|
|
if (sys_inb((wini[drive].base_cmd + REG_STATUS),
|
|
|
|
&w_status) != OK)
|
|
|
|
{
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("couldn't ack irq on drive: %d", drive);
|
2006-02-24 13:55:47 +01:00
|
|
|
}
|
|
|
|
wini[drive].w_status= w_status;
|
2009-10-19 16:23:04 +02:00
|
|
|
sys_inb(wini[drive].base_dma + DMA_STATUS, &w_status);
|
|
|
|
if(w_status & DMA_ST_INT) {
|
|
|
|
sys_outb(wini[drive].base_dma + DMA_STATUS, DMA_ST_INT);
|
|
|
|
wini[drive].dma_intseen = 1;
|
|
|
|
}
|
2005-08-25 10:19:11 +02:00
|
|
|
if (sys_irqenable(&wini[drive].irq_hook_id) != OK)
|
|
|
|
printf("couldn't re-enable drive %d\n", drive);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-26 21:39:00 +02:00
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
#define STSTR(a) if (status & STATUS_ ## a) { strcat(str, #a); strcat(str, " "); }
|
|
|
|
#define ERRSTR(a) if (e & ERROR_ ## a) { strcat(str, #a); strcat(str, " "); }
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE char *strstatus(int status)
|
2005-08-26 21:39:00 +02:00
|
|
|
{
|
|
|
|
static char str[200];
|
|
|
|
str[0] = '\0';
|
|
|
|
|
|
|
|
STSTR(BSY);
|
|
|
|
STSTR(DRDY);
|
|
|
|
STSTR(DMADF);
|
|
|
|
STSTR(SRVCDSC);
|
|
|
|
STSTR(DRQ);
|
|
|
|
STSTR(CORR);
|
|
|
|
STSTR(CHECK);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2010-02-09 16:23:38 +01:00
|
|
|
PRIVATE char *strerr(int e)
|
2005-08-26 21:39:00 +02:00
|
|
|
{
|
|
|
|
static char str[200];
|
|
|
|
str[0] = '\0';
|
|
|
|
|
|
|
|
ERRSTR(BB);
|
|
|
|
ERRSTR(ECC);
|
|
|
|
ERRSTR(ID);
|
|
|
|
ERRSTR(AC);
|
|
|
|
ERRSTR(TK);
|
|
|
|
ERRSTR(DM);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2005-09-16 11:43:02 +02:00
|
|
|
#if ENABLE_ATAPI
|
|
|
|
|
2005-09-11 19:09:11 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* atapi_intr_wait *
|
|
|
|
*===========================================================================*/
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int atapi_intr_wait(int UNUSED(do_dma), size_t UNUSED(max))
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Wait for an interrupt and study the results. Returns a number of bytes
|
|
|
|
* that need to be transferred, or an error code.
|
|
|
|
*/
|
|
|
|
struct wini *wn = w_wn;
|
|
|
|
pvb_pair_t inbyte[4]; /* vector for sys_vinb() */
|
|
|
|
int s; /* status for sys_vinb() */
|
|
|
|
int e;
|
|
|
|
int len;
|
|
|
|
int irr;
|
|
|
|
int r;
|
|
|
|
int phase;
|
|
|
|
|
|
|
|
w_intr_wait();
|
|
|
|
|
|
|
|
/* Request series of device I/O. */
|
2005-08-25 18:25:19 +02:00
|
|
|
inbyte[0].port = wn->base_cmd + REG_ERROR;
|
|
|
|
inbyte[1].port = wn->base_cmd + REG_CNT_LO;
|
|
|
|
inbyte[2].port = wn->base_cmd + REG_CNT_HI;
|
|
|
|
inbyte[3].port = wn->base_cmd + REG_IRR;
|
2005-04-21 16:53:53 +02:00
|
|
|
if ((s=sys_vinb(inbyte, 4)) != OK)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("ATAPI failed sys_vinb(): %d", s);
|
2005-04-21 16:53:53 +02:00
|
|
|
e = inbyte[0].value;
|
|
|
|
len = inbyte[1].value;
|
|
|
|
len |= inbyte[2].value << 8;
|
|
|
|
irr = inbyte[3].value;
|
|
|
|
|
2005-08-26 21:39:00 +02:00
|
|
|
if (wn->w_status & (STATUS_BSY | STATUS_CHECK)) {
|
2005-09-11 19:09:11 +02:00
|
|
|
if (atapi_debug) {
|
2005-08-26 21:39:00 +02:00
|
|
|
printf("atapi fail: S=%x=%s E=%02x=%s L=%04x I=%02x\n", wn->w_status, strstatus(wn->w_status), e, strerr(e), len, irr);
|
|
|
|
}
|
|
|
|
return ERR;
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
phase = (wn->w_status & STATUS_DRQ) | (irr & (IRR_COD | IRR_IO));
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
switch (phase) {
|
|
|
|
case IRR_COD | IRR_IO:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Command Complete\n");
|
|
|
|
r = OK;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Command Aborted\n");
|
|
|
|
r = ERR;
|
|
|
|
break;
|
|
|
|
case STATUS_DRQ | IRR_COD:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Command Out\n");
|
|
|
|
r = ERR;
|
|
|
|
break;
|
|
|
|
case STATUS_DRQ:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Data Out %d\n", len);
|
|
|
|
r = len;
|
|
|
|
break;
|
|
|
|
case STATUS_DRQ | IRR_IO:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Data In %d\n", len);
|
|
|
|
r = len;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (ATAPI_DEBUG) printf("ACD: Phase Unknown\n");
|
|
|
|
r = ERR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-08-25 10:19:11 +02:00
|
|
|
wn->w_status |= STATUS_ADMBSY; /* Assume not done yet. */
|
2005-04-21 16:53:53 +02:00
|
|
|
return(r);
|
|
|
|
}
|
2007-01-12 14:33:12 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
#endif /* ENABLE_ATAPI */
|
2007-01-12 14:33:12 +01:00
|
|
|
|
2007-02-23 19:21:19 +01:00
|
|
|
#undef sys_voutb
|
|
|
|
#undef sys_vinb
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int at_voutb(pvb_pair_t *pvb, int n)
|
2007-02-23 19:21:19 +01:00
|
|
|
{
|
|
|
|
int s, i;
|
|
|
|
if ((s=sys_voutb(pvb,n)) == OK)
|
|
|
|
return OK;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: sys_voutb failed: %d pvb (%d):\n", w_instance, s, n);
|
2007-02-23 19:21:19 +01:00
|
|
|
for(i = 0; i < n; i++)
|
|
|
|
printf("%2d: %4x -> %4x\n", i, pvb[i].value, pvb[i].port);
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_voutb failed");
|
2007-02-23 19:21:19 +01:00
|
|
|
}
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
PRIVATE int at_vinb(pvb_pair_t *pvb, int n)
|
2007-02-23 19:21:19 +01:00
|
|
|
{
|
|
|
|
int s, i;
|
|
|
|
if ((s=sys_vinb(pvb,n)) == OK)
|
|
|
|
return OK;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: sys_vinb failed: %d pvb (%d):\n", w_instance, s, n);
|
2007-02-23 19:21:19 +01:00
|
|
|
for(i = 0; i < n; i++)
|
|
|
|
printf("%2d: %4x\n", i, pvb[i].port);
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_vinb failed");
|
2007-02-23 19:21:19 +01:00
|
|
|
}
|
2007-02-21 18:49:35 +01:00
|
|
|
|
2012-03-05 00:11:41 +01:00
|
|
|
PRIVATE int at_out(int line, u32_t port, u32_t value, char *typename, int type)
|
2007-02-23 19:21:19 +01:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
s = sys_out(port, value, type);
|
|
|
|
if(s == OK)
|
|
|
|
return OK;
|
2012-03-05 00:11:41 +01:00
|
|
|
printf("at_wini%ld: line %d: %s failed: %d; %x -> %x\n",
|
2007-02-23 19:21:19 +01:00
|
|
|
w_instance, line, typename, s, value, port);
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_out failed");
|
2007-02-23 19:21:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-05 00:11:41 +01:00
|
|
|
PRIVATE int at_in(int line, u32_t port, u32_t *value, char *typename, int type)
|
2007-02-23 19:21:19 +01:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
s = sys_in(port, value, type);
|
|
|
|
if(s == OK)
|
|
|
|
return OK;
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
printf("at_wini%ld: line %d: %s failed: %d; port %x\n",
|
2010-04-01 16:30:36 +02:00
|
|
|
w_instance, line, typename, s, port);
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("sys_in failed");
|
2007-02-23 19:21:19 +01:00
|
|
|
}
|
|
|
|
|
Basic System Event Framework (SEF) with ping and live update.
SYSLIB CHANGES:
- SEF must be used by every system process and is thereby part of the system
library.
- The framework provides a receive() interface (sef_receive) for system
processes to automatically catch known system even messages and process them.
- SEF provides a default behavior for each type of system event, but allows
system processes to register callbacks to override the default behavior.
- Custom (local to the process) or predefined (provided by SEF) callback
implementations can be registered to SEF.
- SEF currently includes support for 2 types of system events:
1. SEF Ping. The event occurs every time RS sends a ping to figure out
whether a system process is still alive. The default callback implementation
provided by SEF is to notify RS back to let it know the process is alive
and kicking.
2. SEF Live update. The event occurs every time RS sends a prepare to update
message to let a system process know an update is available and to prepare
for it. The live update support is very basic for now. SEF only deals with
verifying if the prepare state can be supported by the process, dumping the
state for debugging purposes, and providing an event-driven programming
model to the process to react to state changes check-in when ready to update.
- SEF should be extended in the future to integrate support for more types of
system events. Ideally, all the cross-cutting concerns should be integrated into
SEF to avoid duplicating code and ease extensibility. Examples include:
* PM notify messages primarily used at shutdown.
* SYSTEM notify messages primarily used for signals.
* CLOCK notify messages used for system alarms.
* Debug messages. IS could still be in charge of fkey handling but would
forward the debug message to the target process (e.g. PM, if the user
requested debug information about PM). SEF would then catch the message and
do nothing unless the process has registered an appropriate callback to
deal with the event. This simplifies the programming model to print debug
information, avoids duplicating code, and reduces the effort to print
debug information.
SYSTEM PROCESSES CHANGES:
- Every system process registers SEF callbacks it needs to override the default
system behavior and calls sef_startup() right after being started.
- sef_startup() does almost nothing now, but will be extended in the future to
support callbacks of its own to let RS control and synchronize with every
system process at initialization time.
- Every system process calls sef_receive() now rather than receive() directly,
to let SEF handle predefined system events.
RS CHANGES:
- RS supports a basic single-component live update protocol now, as follows:
* When an update command is issued (via "service update *"), RS notifies the
target system process to prepare for a specific update state.
* If the process doesn't respond back in time, the update is aborted.
* When the process responds back, RS kills it and marks it for refreshing.
* The process is then automatically restarted as for a buggy process and can
start running again.
* Live update is currently prototyped as a controlled failure.
2009-12-21 15:12:21 +01:00
|
|
|
|