From 68125bc44173893fb3af08085b0b6b823b60d030 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 31 May 2006 14:34:17 +0000 Subject: Added generic asynchronous operations code. Removed data_in_len and data_out_len from ata_command structure; the lengths are implied by the sector count and the presence of the data_in or data_out pointers. Changed AoE code to use subcommands by default, and made aoe_issue() nonblocking (with completion via async_wait()). --- src/include/gpxe/aoe.h | 20 +++++++++------- src/include/gpxe/async.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ src/include/gpxe/ata.h | 18 +++++++------- 3 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 src/include/gpxe/async.h (limited to 'src/include/gpxe') diff --git a/src/include/gpxe/aoe.h b/src/include/gpxe/aoe.h index 2e13d7a8d..fb692224b 100644 --- a/src/include/gpxe/aoe.h +++ b/src/include/gpxe/aoe.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include /** An AoE ATA command */ @@ -89,29 +91,31 @@ struct aoe_session { /** Target MAC address */ uint8_t target[ETH_ALEN]; - /** Tag for current command */ + /** Tag for current AoE command */ uint32_t tag; + /** Current ATA command */ struct ata_command *command; - /** Status of the command */ - int status; + /** Overall status of current ATA command */ + unsigned int status; /** Byte offset within command's data buffer */ unsigned int command_offset; + /** Asynchronous operation for this command */ + struct async_operation aop; + + /** Retransmission timer */ + struct retry_timer timer; }; #define AOE_STATUS_ERR_MASK 0x0f /**< Error portion of status code */ #define AOE_STATUS_PENDING 0x80 /**< Command pending */ -#define AOE_STATUS_UNDERRUN 0x40 /**< Buffer overrun */ -#define AOE_STATUS_OVERRUN 0x20 /**< Buffer underrun */ /** Maximum number of sectors per packet */ #define AOE_MAX_COUNT 2 extern void aoe_open ( struct aoe_session *aoe ); extern void aoe_close ( struct aoe_session *aoe ); -extern int aoe_issue ( struct aoe_session *aoe, struct ata_command *command ); -extern int aoe_issue_split ( struct aoe_session *aoe, - struct ata_command *command ); +extern void aoe_issue ( struct aoe_session *aoe, struct ata_command *command ); /** An AoE device */ struct aoe_device { diff --git a/src/include/gpxe/async.h b/src/include/gpxe/async.h new file mode 100644 index 000000000..8a6819786 --- /dev/null +++ b/src/include/gpxe/async.h @@ -0,0 +1,62 @@ +#ifndef _GPXE_ASYNC_H +#define _GPXE_ASYNC_H + +/** @file + * + * Asynchronous operations + * + */ + +#include +#include + +/** An asynchronous operation */ +struct async_operation { + /** Operation status + * + * This is an error code as defined in errno.h, plus an offset + * of EINPROGRESS. This means that a status value of 0 + * corresponds to a return status code of -EINPROGRESS, + * i.e. that the default state of an asynchronous operation is + * "not yet completed". + */ + int status; +}; + +/** + * Set asynchronous operation status + * + * @v aop Asynchronous operation + * @v rc Return status code + */ +static inline __attribute__ (( always_inline )) void +async_set_status ( struct async_operation *aop, int rc ) { + aop->status = ( rc + EINPROGRESS ); +} + +/** + * Get asynchronous operation status + * + * @v aop Asynchronous operation + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +async_status ( struct async_operation *aop ) { + return ( aop->status - EINPROGRESS ); +} + +/** + * Flag asynchronous operation as complete + * + * @v aop Asynchronous operation + * @v rc Return status code + */ +static inline __attribute__ (( always_inline )) void +async_done ( struct async_operation *aop, int rc ) { + assert ( rc != -EINPROGRESS ); + async_set_status ( aop, rc ); +} + +extern int async_wait ( struct async_operation *aop ); + +#endif /* _GPXE_ASYNC_H */ diff --git a/src/include/gpxe/ata.h b/src/include/gpxe/ata.h index 195e361cf..e0fca7afe 100644 --- a/src/include/gpxe/ata.h +++ b/src/include/gpxe/ata.h @@ -139,20 +139,18 @@ struct ata_cb { struct ata_command { /** ATA command block */ struct ata_cb cb; - /** Data-out buffer (may be NULL) */ - userptr_t data_out; - /** Data-out buffer length + /** Data-out buffer (may be NULL) * - * Must be zero if @c data_out is NULL + * If non-NULL, this buffer must be ata_command::cb::count + * sectors in size. */ - size_t data_out_len; - /** Data-in buffer (may be NULL) */ - userptr_t data_in; - /** Data-in buffer length + userptr_t data_out; + /** Data-in buffer (may be NULL) * - * Must be zero if @c data_in is NULL + * If non-NULL, this buffer must be ata_command::cb::count + * sectors in size. */ - size_t data_in_len; + userptr_t data_in; }; /** -- cgit v1.2.3-55-g7522