ahci/libdriver: multithreading support
This patch adds support for executing multiple concurrent requests on different devices on the same AHCI controller. The libdriver library has been extended to include a generic multithreading interface, and the AHCI driver has been extended to make use of this interface. The original version of this code has been written by Arne Welzel.
This commit is contained in:
@@ -7,12 +7,12 @@ INCS+= env.h fetch.h hgfs.h lib.h libutil.h timers.h
|
||||
INCS+= minix/acpi.h minix/ansi.h minix/audio_fw.h minix/bitmap.h \
|
||||
minix/callnr.h minix/com.h minix/compiler.h minix/config.h \
|
||||
minix/const.h minix/cpufeature.h minix/crtso.h minix/debug.h \
|
||||
minix/devio.h minix/devman.h minix/dmap.h \
|
||||
minix/driver.h minix/drivers.h minix/drvlib.h minix/ds.h \
|
||||
minix/devio.h minix/devman.h minix/dmap.h minix/driver.h \
|
||||
minix/driver_mt.h minix/drivers.h minix/drvlib.h minix/ds.h \
|
||||
minix/endpoint.h minix/fslib.h minix/gcov.h minix/hash.h \
|
||||
minix/ioctl.h minix/input.h minix/ipc.h minix/ipcconst.h \
|
||||
minix/keymap.h minix/limits.h minix/mthread.h minix/minlib.h \
|
||||
minix/mq.h minix/netdriver.h minix/partition.h minix/portio.h \
|
||||
minix/netdriver.h minix/partition.h minix/portio.h \
|
||||
minix/priv.h minix/procfs.h minix/profile.h minix/queryparam.h \
|
||||
minix/rs.h minix/safecopies.h minix/sched.h minix/sef.h \
|
||||
minix/sound.h minix/spin.h minix/sys_config.h minix/sysinfo.h \
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <minix/partition.h>
|
||||
#include <minix/u64.h>
|
||||
|
||||
typedef int thread_id_t;
|
||||
|
||||
/* Info about and entry points into the device dependent code. */
|
||||
struct driver {
|
||||
_PROTOTYPE( char *(*dr_name), (void) );
|
||||
@@ -46,7 +48,8 @@ struct driver {
|
||||
_PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int (*dr_other), (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int (*dr_hw_int), (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( void (*dr_hw_int), (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int (*dr_thread), (dev_t dev, thread_id_t *threadp) );
|
||||
};
|
||||
|
||||
/* Base and size of a partition in bytes. */
|
||||
@@ -55,7 +58,6 @@ struct device {
|
||||
u64_t dv_size;
|
||||
};
|
||||
|
||||
|
||||
#define DRIVER_STD 0 /* Use the standard reply protocol */
|
||||
#define DRIVER_ASYN 1 /* Use the new asynchronous protocol */
|
||||
|
||||
@@ -63,17 +65,10 @@ struct device {
|
||||
|
||||
#define IS_DEV_MINOR_RQ(type) (IS_DEV_RQ(type) && (type) != DEV_STATUS)
|
||||
|
||||
/* Functions defined by driver.c: */
|
||||
/* Functions defined by libdriver. These can be used for both singlethreaded
|
||||
* and multithreaded drivers.
|
||||
*/
|
||||
_PROTOTYPE( void driver_announce, (void) );
|
||||
_PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr,
|
||||
int *status_ptr) );
|
||||
_PROTOTYPE( int driver_receive_mq, (message *m_ptr, int *status_ptr) );
|
||||
_PROTOTYPE( int driver_handle_msg, (struct driver *dp, int type, message *m_ptr,
|
||||
int ipc_status));
|
||||
_PROTOTYPE( void driver_terminate, (void) );
|
||||
_PROTOTYPE( void driver_task, (struct driver *dr, int type) );
|
||||
_PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) );
|
||||
_PROTOTYPE( void driver_init_buffer, (void) );
|
||||
_PROTOTYPE( char *no_name, (void) );
|
||||
_PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( struct device *nop_prepare, (int device) );
|
||||
@@ -85,6 +80,22 @@ _PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr) );
|
||||
_PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) );
|
||||
|
||||
#ifndef _DRIVER_MT_API
|
||||
/* Additional functions for the singlethreaded version. These allow the driver
|
||||
* to either use the stock driver_task(), or implement its own message loop.
|
||||
* To avoid accidents, these functions are not exposed when minix/driver_mt.h
|
||||
* has been included previously.
|
||||
*/
|
||||
_PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr,
|
||||
int *status_ptr) );
|
||||
_PROTOTYPE( int driver_receive_mq, (message *m_ptr, int *status_ptr) );
|
||||
_PROTOTYPE( void driver_handle_msg, (struct driver *dp, int type,
|
||||
message *m_ptr, int ipc_status) );
|
||||
_PROTOTYPE( void driver_terminate, (void) );
|
||||
_PROTOTYPE( void driver_task, (struct driver *dr, int type) );
|
||||
_PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) );
|
||||
#endif /* !_DRIVER_MT_API */
|
||||
|
||||
/* Parameters for the disk drive. */
|
||||
#define SECTOR_SIZE 512 /* physical sector size in bytes */
|
||||
#define SECTOR_SHIFT 9 /* for division */
|
||||
@@ -93,14 +104,6 @@ _PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) );
|
||||
#define CD_SECTOR_SIZE 2048 /* sector size of a CD-ROM in bytes */
|
||||
|
||||
/* Size of the DMA buffer buffer in bytes. */
|
||||
#define USE_EXTRA_DMA_BUF 0 /* usually not needed */
|
||||
#define DMA_BUF_SIZE (DMA_SECTORS * SECTOR_SIZE)
|
||||
|
||||
#if (CHIP == INTEL)
|
||||
extern u8_t *tmp_buf; /* the DMA buffer */
|
||||
#else
|
||||
extern u8_t tmp_buf[]; /* the DMA buffer */
|
||||
#endif
|
||||
extern phys_bytes tmp_phys; /* phys address of DMA buffer */
|
||||
|
||||
#endif /* __MINIX_DRIVER_H__ */
|
||||
|
||||
16
common/include/minix/driver_mt.h
Normal file
16
common/include/minix/driver_mt.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _MINIX_DRIVER_MT_H
|
||||
#define _MINIX_DRIVER_MT_H
|
||||
|
||||
#define DRIVER_MT_API 1 /* do not expose the singlethreaded API */
|
||||
#include <minix/driver.h>
|
||||
|
||||
/* The maximum number of worker threads. */
|
||||
#define DRIVER_MT_MAX_WORKERS 32
|
||||
|
||||
_PROTOTYPE( void driver_mt_task, (struct driver *driver_p, int driver_type) );
|
||||
_PROTOTYPE( void driver_mt_sleep, (void) );
|
||||
_PROTOTYPE( void driver_mt_wakeup, (thread_id_t id) );
|
||||
_PROTOTYPE( void driver_mt_stop, (void) );
|
||||
_PROTOTYPE( void driver_mt_terminate, (void) );
|
||||
|
||||
#endif /* _MINIX_DRIVER_MT_H */
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
inet/mq.h
|
||||
|
||||
Created: Jan 3, 1992 by Philip Homburg
|
||||
|
||||
Copyright 1995 Philip Homburg
|
||||
*/
|
||||
|
||||
#ifndef INET__MQ_H
|
||||
#define INET__MQ_H
|
||||
|
||||
typedef struct mq
|
||||
{
|
||||
message mq_mess;
|
||||
int mq_mess_status;
|
||||
struct mq *mq_next;
|
||||
int mq_allocated;
|
||||
} mq_t;
|
||||
|
||||
_PROTOTYPE( mq_t *mq_get, (void) );
|
||||
_PROTOTYPE( void mq_free, (mq_t *mq) );
|
||||
_PROTOTYPE( void mq_init, (void) );
|
||||
|
||||
#endif /* INET__MQ_H */
|
||||
|
||||
/*
|
||||
* $PchId: mq.h,v 1.4 1995/11/21 06:40:30 philip Exp $
|
||||
*/
|
||||
@@ -36,11 +36,6 @@ int cmp64ul(u64_t i, unsigned long j);
|
||||
unsigned long ex64lo(u64_t i);
|
||||
unsigned long ex64hi(u64_t i);
|
||||
u64_t make64(unsigned long lo, unsigned long hi);
|
||||
u64_t rrotate64(u64_t x, unsigned short b);
|
||||
u64_t rshift64(u64_t x, unsigned short b);
|
||||
u64_t xor64(u64_t a, u64_t b);
|
||||
u64_t and64(u64_t a, u64_t b);
|
||||
u64_t not64(u64_t a);
|
||||
|
||||
#define is_zero64(i) ((i).lo == 0 && (i).hi == 0)
|
||||
#define make_zero64(i) do { (i).lo = (i).hi = 0; } while(0)
|
||||
@@ -216,4 +211,10 @@ static inline u64_t sub64ul(u64_t i, unsigned long j)
|
||||
|
||||
#endif
|
||||
|
||||
u64_t rrotate64(u64_t x, unsigned short b);
|
||||
u64_t rshift64(u64_t x, unsigned short b);
|
||||
u64_t xor64(u64_t a, u64_t b);
|
||||
u64_t and64(u64_t a, u64_t b);
|
||||
u64_t not64(u64_t a);
|
||||
|
||||
#endif /* _MINIX__U64_H */
|
||||
|
||||
Reference in New Issue
Block a user