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()).
This commit is contained in:
Michael Brown
2006-05-31 14:34:17 +00:00
parent 73a449e96b
commit 68125bc441
6 changed files with 166 additions and 122 deletions

View File

@@ -10,6 +10,8 @@
#include <stdint.h>
#include <gpxe/list.h>
#include <gpxe/if_ether.h>
#include <gpxe/retry.h>
#include <gpxe/async.h>
#include <gpxe/ata.h>
/** 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 {

62
src/include/gpxe/async.h Normal file
View File

@@ -0,0 +1,62 @@
#ifndef _GPXE_ASYNC_H
#define _GPXE_ASYNC_H
/** @file
*
* Asynchronous operations
*
*/
#include <errno.h>
#include <assert.h>
/** 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 */

View File

@@ -139,20 +139,18 @@ struct ata_cb {
struct ata_command {
/** ATA command block */
struct ata_cb cb;
/** Data-out buffer (may be NULL) */
/** Data-out buffer (may be NULL)
*
* If non-NULL, this buffer must be ata_command::cb::count
* sectors in size.
*/
userptr_t data_out;
/** Data-out buffer length
/** Data-in 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
*
* Must be zero if @c data_in is NULL
*/
size_t data_in_len;
};
/**