qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] ahci: enhance usable port count to 4


From: Sebastian Herbszt
Subject: [Qemu-devel] [PATCH] ahci: enhance usable port count to 4
Date: Thu, 13 May 2010 17:34:24 +0200

Make all 4 SATA ports usable.

Signed-off-by: Sebastian Herbszt <address@hidden>

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;i<SATA_PORTS;i++)
     s->port_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;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]