From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=36758 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OENrj-0000L2-0C for qemu-devel@nongnu.org; Tue, 18 May 2010 10:33:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OEIao-0004yl-4w for qemu-devel@nongnu.org; Tue, 18 May 2010 04:58:35 -0400 Received: from smtp125.sbc.mail.sp1.yahoo.com ([69.147.65.184]:36439) by eggs.gnu.org with smtp (Exim 4.69) (envelope-from ) id 1OEIam-0004xQ-AM for qemu-devel@nongnu.org; Tue, 18 May 2010 04:56:01 -0400 From: "Nicholas A. Bellinger" In-Reply-To: <20100518065713.352E22A371@ochil.suse.de> References: <20100518065713.352E22A371@ochil.suse.de> Content-Type: text/plain Date: Tue, 18 May 2010 01:49:14 -0700 Message-Id: <1274172554.7348.161.camel@haakon2.linux-iscsi.org> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH 4/4] megasas: Implement ABORT_CMD List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Hannes Reinecke Cc: qemu-devel@nongnu.org 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 > --- > 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