[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [PATCH 4/4] megasas: Implement ABORT_CMD
From: |
Nicholas A. Bellinger |
Subject: |
[Qemu-devel] Re: [PATCH 4/4] megasas: Implement ABORT_CMD |
Date: |
Tue, 18 May 2010 01:49:14 -0700 |
On Tue, 2010-05-18 at 08:57 +0200, Hannes Reinecke wrote:
> Win7 is impatient during shutdown and is sending 'ABORT_CMD' frames.
> Haven't tried to figure out _why_, but we should be handling them
> nevertheless.
>
> Signed-off-by: Hannes Reinecke <address@hidden>
> ---
> hw/megasas.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
> hw/mfi.h | 2 +-
> 2 files changed, 45 insertions(+), 6 deletions(-)
>
> diff --git a/hw/megasas.c b/hw/megasas.c
> index e91c96b..c249914 100644
> --- a/hw/megasas.c
> +++ b/hw/megasas.c
> @@ -241,13 +241,13 @@ static inline int megasas_next_index(MPTState *s, int
> index)
> return index;
> }
>
> -static inline struct megasas_cmd_t *megasas_next_frame(MPTState *s,
> +static inline struct megasas_cmd_t *megasas_lookup_frame(MPTState *s,
> target_phys_addr_t frame)
> {
> struct megasas_cmd_t *cmd = NULL;
> - int num = 0, tail, index;
> + int num = 0, index;
>
> - tail = index = s->reply_queue_index;
> + index = s->reply_queue_index;
>
> while (num < MEGASAS_MAX_FRAMES) {
> if (s->frames[index].pa && s->frames[index].pa == frame) {
> @@ -257,14 +257,25 @@ static inline struct megasas_cmd_t
> *megasas_next_frame(MPTState *s,
> index = megasas_next_index(s, index);
> num++;
> }
> +
> + return cmd;
> +}
> +
> +static inline struct megasas_cmd_t *megasas_next_frame(MPTState *s,
> + target_phys_addr_t frame)
> +{
> + struct megasas_cmd_t *cmd = NULL;
> + int num = 0, index;
> +
> + cmd = megasas_lookup_frame(s, frame);
> if (cmd) {
> #ifdef DEBUG_MEGASAS_QUEUE
> - DPRINTF("Found mapped frame %x context %x pa %lx\n", index,
> + DPRINTF("Found mapped frame %x context %x pa %lx\n", cmd->index,
> cmd->frame->header.context, cmd->pa);
> #endif
> return cmd;
> }
> - index = tail;
> + index = s->reply_queue_index;
> num = 0;
> while (num < MEGASAS_MAX_FRAMES) {
> if (!s->frames[index].pa) {
> @@ -1067,6 +1078,31 @@ static void megasas_command_complete(SCSIRequest *req)
> megasas_dequeue_frame(cmd->state, context);
> }
>
> +static int megasas_handle_abort(MPTState *s, struct megasas_cmd_t *cmd)
> +{
> + uint32_t abort_ctx = le32_to_cpu(cmd->frame->abort.abort_context);
> + target_phys_addr_t abort_addr, addr_hi, addr_lo;
> + struct megasas_cmd_t *abort_cmd;
> +
> + addr_hi = le32_to_cpu(cmd->frame->abort.abort_mfi_addr_hi);
> + addr_lo = le32_to_cpu(cmd->frame->abort.abort_mfi_addr_lo);
> + abort_addr = (addr_hi << 32) | addr_lo;
> +
> + abort_cmd = megasas_lookup_frame(s, abort_addr);
> + if (!abort_cmd) {
> + DPRINTF("No active command for frame context %x\n", abort_ctx);
> + return MFI_STAT_OK;
> + }
> + if (abort_cmd->frame->header.context != abort_ctx) {
> + DPRINTF("abort frame %x: invalid context %x\n", abort_cmd->index,
> + abort_cmd->frame->header.context);
> + return MFI_STAT_ABORT_NOT_POSSIBLE;
> + }
> + DPRINTF("aborting frame context %x\n", abort_ctx);
> + megasas_abort_command(abort_cmd);
> + return MFI_STAT_OK;
> +}
> +
> static void megasas_handle_frame(MPTState *s, target_phys_addr_t frame_addr,
> uint32_t frame_count)
> {
> @@ -1098,6 +1134,9 @@ static void megasas_handle_frame(MPTState *s,
> target_phys_addr_t frame_addr,
> case MFI_CMD_DCMD:
> frame_status = megasas_handle_dcmd(s, cmd);
> break;
> + case MFI_CMD_ABORT:
> + frame_status = megasas_handle_abort(s, cmd);
> + break;
> case MFI_CMD_PD_SCSI_IO:
> case MFI_CMD_LD_SCSI_IO:
> frame_status = megasas_handle_scsi(s, cmd);
> diff --git a/hw/mfi.h b/hw/mfi.h
> index 0beb1b6..f73cda7 100644
> --- a/hw/mfi.h
> +++ b/hw/mfi.h
> @@ -125,7 +125,7 @@
> #define MFI_FWSTATE_MAXSGL_MASK 0x00ff0000
> #define MFI_FWSTATE_MAXCMD_MASK 0x0000ffff
> #define MFI_FWSTATE_HOSTMEMREQD_MASK 0x08000000
> -#define MFI_FWSTATE_BOOT_MESSAGE_PENDING 0x90000000
> +
> /*
> * Control bits to drive the card to ready state. These go into the IDB
> * register.
Thanks, commited as 07d41aed0de
Best,
--nab