From patchwork Thu May 13 15:34:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Herbszt X-Patchwork-Id: 52489 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 82F26B7E39 for ; Fri, 14 May 2010 01:36:54 +1000 (EST) Received: from localhost ([127.0.0.1]:51189 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OCaSx-0001xs-81 for incoming@patchwork.ozlabs.org; Thu, 13 May 2010 11:36:51 -0400 Received: from [140.186.70.92] (port=43068 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OCaRk-0001gn-B0 for qemu-devel@nongnu.org; Thu, 13 May 2010 11:35:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OCaRi-0001qp-2Q for qemu-devel@nongnu.org; Thu, 13 May 2010 11:35:36 -0400 Received: from mail.gmx.net ([213.165.64.20]:60311) by eggs.gnu.org with smtp (Exim 4.69) (envelope-from ) id 1OCaRh-0001qQ-MI for qemu-devel@nongnu.org; Thu, 13 May 2010 11:35:34 -0400 Received: (qmail invoked by alias); 13 May 2010 15:35:31 -0000 Received: from g226032134.adsl.alicedsl.de (HELO opensuse112) [92.226.32.134] by mail.gmx.net (mp031) with SMTP; 13 May 2010 17:35:31 +0200 X-Authenticated: #310364 X-Provags-ID: V01U2FsdGVkX19sZmQvPldsBsiViMo5/Wn0sfnm0YhoyFJOOaBZvp VEiBUFUwyEVb1t X-Mailer: gregkh_patchbomb modified Date: Thu, 13 May 2010 17:34:24 +0200 Message-Id: <1273764864$2723@local> Mime-Version: 1.0 To: qemu-devel@nongnu.org From: Sebastian Herbszt X-Y-GMX-Trusted: 0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Sebastian Herbszt Subject: [Qemu-devel] [PATCH] ahci: enhance usable port count to 4 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Make all 4 SATA ports usable. Signed-off-by: Sebastian Herbszt diff --git a/hw/ahci.c b/hw/ahci.c index 6f7b807..a343839 100644 --- a/hw/ahci.c +++ b/hw/ahci.c @@ -17,7 +17,6 @@ * * TODO: * o ahci cd support should use ide,but now ide 's bmdma prdt is different from ahci's prdt. - * make ahci use multi-devices at the same time * make code to reuse ide's code */ #include "hw.h" @@ -266,7 +265,7 @@ typedef struct AHCIState{ uint32_t port_state[SATA_PORTS]; int mem; QEMUTimer *timer; - IDEBus *ide; + IDEBus *ide[SATA_PORTS]; ahci_sg *prdt_buf; qemu_irq irq; } AHCIState; @@ -291,7 +290,7 @@ static uint32_t ahci_port_read(AHCIState *s,int port,int offset) switch(offset) { case PORT_SCR: - if(s->ide && port==0) + if(s->ide[port]) val= 3 /* DET */ | (1 << 4) /* SPD */ | (1 << 8) /* IPM */; else val=0; @@ -489,7 +488,7 @@ static void ahci_reg_init(AHCIState *s) int i; s->control_regs.cap = 3 | (0x1f << 8) | (1 << 20) ; /* 4 ports, 32 command slots, 1.5 Gb/s */ s->control_regs.ghc = 1 << 31; /* AHCI Enable */ - s->control_regs.impl = 1; /* Port 0 implemented */ + s->control_regs.impl = 15; /* Ports 0-3 implemented */ s->control_regs.version = 0x10000; for(i=0;iport_state[i]=STATE_RUN; @@ -736,13 +735,13 @@ static inline int media_is_cd(IDEState *s) { return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS); } -static void ide_atapi_cmd(AHCIState *s,int prdt_num) +static void ide_atapi_cmd(AHCIState *s,int prdt_num, int port) { const uint8_t *packet; uint8_t *buf; int max_len; IDEState *ide_state; - ide_state=&s->ide->ifs[0]; + ide_state=&s->ide[port]->ifs[0]; packet = ide_state->io_buffer; buf = ide_state->io_buffer; @@ -1055,8 +1054,8 @@ static void handle_cmd(AHCIState *s,int port,int slot) case STATE_RESET: if(!(fis[15]&ATA_SRST)) { - if(!s->ide)hw_error("no ahci sata disk now\n"); - ide_state=&s->ide->ifs[0]; + if(!s->ide[port])hw_error("no ahci sata disk now\n"); + ide_state=&s->ide[port]->ifs[0]; s->port_state[port]=STATE_RUN; if(bdrv_get_type_hint(ide_state->bs)==BDRV_TYPE_CDROM) s->port_regs[port].sig=0xeb14<<16; @@ -1067,8 +1066,8 @@ static void handle_cmd(AHCIState *s,int port,int slot) if(fis[1]==(1<<7)) { - if(!s->ide)hw_error("no ahci sata disk now\n"); - ide_state=&s->ide->ifs[0]; + if(!s->ide[port])hw_error("no ahci sata disk now\n"); + ide_state=&s->ide[port]->ifs[0]; switch(fis[2]) { case WIN_PIDENTIFY: @@ -1094,7 +1093,7 @@ static void handle_cmd(AHCIState *s,int port,int slot) ide_state->atapi_dma = 1; ide_state->nsector = 1; memcpy(ide_state->io_buffer,acmd,32); - ide_atapi_cmd(s,prdt_num); + ide_atapi_cmd(s,prdt_num,port); pr->irq_stat |= (1<<2); break; case WIN_STANDBYNOW1: @@ -1151,20 +1150,26 @@ static void ahci_timer_function(void *opaque) static AHCIState *ahci_new(void) { + int i; DriveInfo *dinfo; - IDEBus *bus = qemu_mallocz(sizeof(IDEBus)); - BMDMAState *bmdma=qemu_mallocz(sizeof(BMDMAState)); + IDEBus *bus[SATA_PORTS]; + BMDMAState *bmdma[SATA_PORTS]; + for (i = 0; i < SATA_PORTS; i++) { + bus[i] = qemu_mallocz(sizeof(IDEBus)); + bmdma[i] = qemu_mallocz(sizeof(BMDMAState)); + } AHCIState *s = qemu_mallocz(sizeof(AHCIState)); ahci_reg_init(s); s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s); s->timer = qemu_new_timer(vm_clock, ahci_timer_function, s); s->prdt_buf = qemu_malloc(65535*32); - if ((dinfo = drive_get(IF_SATA, 0, 0)) != NULL) - { - ide_init2(bus, dinfo, NULL,0); - s->ide=bus; - s->ide->bmdma=bmdma; + for (i = 0; i < SATA_PORTS; i++) { + if ((dinfo = drive_get(IF_SATA, 0, i)) != NULL) { + ide_init2(bus[i], dinfo, NULL,0); + s->ide[i]=bus[i]; + s->ide[i]->bmdma=bmdma[i]; + } } return s; }