Annotation of qemu/hw/ide/ahci.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * QEMU AHCI Emulation
                      3:  *
                      4:  * Copyright (c) 2010 [email protected]
                      5:  * Copyright (c) 2010 Roland Elek <[email protected]>
                      6:  * Copyright (c) 2010 Sebastian Herbszt <[email protected]>
                      7:  * Copyright (c) 2010 Alexander Graf <[email protected]>
                      8:  *
                      9:  * This library is free software; you can redistribute it and/or
                     10:  * modify it under the terms of the GNU Lesser General Public
                     11:  * License as published by the Free Software Foundation; either
                     12:  * version 2 of the License, or (at your option) any later version.
                     13:  *
                     14:  * This library is distributed in the hope that it will be useful,
                     15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     17:  * Lesser General Public License for more details.
                     18:  *
                     19:  * You should have received a copy of the GNU Lesser General Public
                     20:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
                     21:  *
                     22:  */
                     23: 
                     24: #include <hw/hw.h>
                     25: #include <hw/msi.h>
                     26: #include <hw/pc.h>
                     27: #include <hw/pci.h>
                     28: 
                     29: #include "monitor.h"
                     30: #include "dma.h"
                     31: #include "cpu-common.h"
                     32: #include "internal.h"
                     33: #include <hw/ide/pci.h>
                     34: #include <hw/ide/ahci.h>
                     35: 
                     36: /* #define DEBUG_AHCI */
                     37: 
                     38: #ifdef DEBUG_AHCI
                     39: #define DPRINTF(port, fmt, ...) \
                     40: do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \
                     41:      fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
                     42: #else
                     43: #define DPRINTF(port, fmt, ...) do {} while(0)
                     44: #endif
                     45: 
                     46: static void check_cmd(AHCIState *s, int port);
                     47: static int handle_cmd(AHCIState *s,int port,int slot);
                     48: static void ahci_reset_port(AHCIState *s, int port);
                     49: static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis);
                     50: static void ahci_init_d2h(AHCIDevice *ad);
                     51: 
                     52: static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
                     53: {
                     54:     uint32_t val;
                     55:     AHCIPortRegs *pr;
                     56:     pr = &s->dev[port].port_regs;
                     57: 
                     58:     switch (offset) {
                     59:     case PORT_LST_ADDR:
                     60:         val = pr->lst_addr;
                     61:         break;
                     62:     case PORT_LST_ADDR_HI:
                     63:         val = pr->lst_addr_hi;
                     64:         break;
                     65:     case PORT_FIS_ADDR:
                     66:         val = pr->fis_addr;
                     67:         break;
                     68:     case PORT_FIS_ADDR_HI:
                     69:         val = pr->fis_addr_hi;
                     70:         break;
                     71:     case PORT_IRQ_STAT:
                     72:         val = pr->irq_stat;
                     73:         break;
                     74:     case PORT_IRQ_MASK:
                     75:         val = pr->irq_mask;
                     76:         break;
                     77:     case PORT_CMD:
                     78:         val = pr->cmd;
                     79:         break;
                     80:     case PORT_TFDATA:
                     81:         val = ((uint16_t)s->dev[port].port.ifs[0].error << 8) |
                     82:               s->dev[port].port.ifs[0].status;
                     83:         break;
                     84:     case PORT_SIG:
                     85:         val = pr->sig;
                     86:         break;
                     87:     case PORT_SCR_STAT:
                     88:         if (s->dev[port].port.ifs[0].bs) {
                     89:             val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
                     90:                   SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
                     91:         } else {
                     92:             val = SATA_SCR_SSTATUS_DET_NODEV;
                     93:         }
                     94:         break;
                     95:     case PORT_SCR_CTL:
                     96:         val = pr->scr_ctl;
                     97:         break;
                     98:     case PORT_SCR_ERR:
                     99:         val = pr->scr_err;
                    100:         break;
                    101:     case PORT_SCR_ACT:
                    102:         pr->scr_act &= ~s->dev[port].finished;
                    103:         s->dev[port].finished = 0;
                    104:         val = pr->scr_act;
                    105:         break;
                    106:     case PORT_CMD_ISSUE:
                    107:         val = pr->cmd_issue;
                    108:         break;
                    109:     case PORT_RESERVED:
                    110:     default:
                    111:         val = 0;
                    112:     }
                    113:     DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
                    114:     return val;
                    115: 
                    116: }
                    117: 
                    118: static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
                    119: {
                    120:     struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
                    121: 
                    122:     DPRINTF(0, "raise irq\n");
                    123: 
                    124:     if (msi_enabled(&d->card)) {
                    125:         msi_notify(&d->card, 0);
                    126:     } else {
                    127:         qemu_irq_raise(s->irq);
                    128:     }
                    129: }
                    130: 
                    131: static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
                    132: {
                    133:     struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
                    134: 
                    135:     DPRINTF(0, "lower irq\n");
                    136: 
                    137:     if (!msi_enabled(&d->card)) {
                    138:         qemu_irq_lower(s->irq);
                    139:     }
                    140: }
                    141: 
                    142: static void ahci_check_irq(AHCIState *s)
                    143: {
                    144:     int i;
                    145: 
                    146:     DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);
                    147: 
                    148:     for (i = 0; i < s->ports; i++) {
                    149:         AHCIPortRegs *pr = &s->dev[i].port_regs;
                    150:         if (pr->irq_stat & pr->irq_mask) {
                    151:             s->control_regs.irqstatus |= (1 << i);
                    152:         }
                    153:     }
                    154: 
                    155:     if (s->control_regs.irqstatus &&
                    156:         (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
                    157:             ahci_irq_raise(s, NULL);
                    158:     } else {
                    159:         ahci_irq_lower(s, NULL);
                    160:     }
                    161: }
                    162: 
                    163: static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
                    164:                              int irq_type)
                    165: {
                    166:     DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
                    167:             irq_type, d->port_regs.irq_mask & irq_type);
                    168: 
                    169:     d->port_regs.irq_stat |= irq_type;
                    170:     ahci_check_irq(s);
                    171: }
                    172: 
                    173: static void map_page(uint8_t **ptr, uint64_t addr, uint32_t wanted)
                    174: {
                    175:     target_phys_addr_t len = wanted;
                    176: 
                    177:     if (*ptr) {
                    178:         cpu_physical_memory_unmap(*ptr, len, 1, len);
                    179:     }
                    180: 
                    181:     *ptr = cpu_physical_memory_map(addr, &len, 1);
                    182:     if (len < wanted) {
                    183:         cpu_physical_memory_unmap(*ptr, len, 1, len);
                    184:         *ptr = NULL;
                    185:     }
                    186: }
                    187: 
                    188: static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
                    189: {
                    190:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    191: 
                    192:     DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
                    193:     switch (offset) {
                    194:         case PORT_LST_ADDR:
                    195:             pr->lst_addr = val;
                    196:             map_page(&s->dev[port].lst,
                    197:                      ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
                    198:             s->dev[port].cur_cmd = NULL;
                    199:             break;
                    200:         case PORT_LST_ADDR_HI:
                    201:             pr->lst_addr_hi = val;
                    202:             map_page(&s->dev[port].lst,
                    203:                      ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
                    204:             s->dev[port].cur_cmd = NULL;
                    205:             break;
                    206:         case PORT_FIS_ADDR:
                    207:             pr->fis_addr = val;
                    208:             map_page(&s->dev[port].res_fis,
                    209:                      ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
                    210:             break;
                    211:         case PORT_FIS_ADDR_HI:
                    212:             pr->fis_addr_hi = val;
                    213:             map_page(&s->dev[port].res_fis,
                    214:                      ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
                    215:             break;
                    216:         case PORT_IRQ_STAT:
                    217:             pr->irq_stat &= ~val;
                    218:             break;
                    219:         case PORT_IRQ_MASK:
                    220:             pr->irq_mask = val & 0xfdc000ff;
                    221:             ahci_check_irq(s);
                    222:             break;
                    223:         case PORT_CMD:
                    224:             pr->cmd = val & ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON);
                    225: 
                    226:             if (pr->cmd & PORT_CMD_START) {
                    227:                 pr->cmd |= PORT_CMD_LIST_ON;
                    228:             }
                    229: 
                    230:             if (pr->cmd & PORT_CMD_FIS_RX) {
                    231:                 pr->cmd |= PORT_CMD_FIS_ON;
                    232:             }
                    233: 
                    234:             /* XXX usually the FIS would be pending on the bus here and
                    235:                    issuing deferred until the OS enables FIS receival.
                    236:                    Instead, we only submit it once - which works in most
                    237:                    cases, but is a hack. */
                    238:             if ((pr->cmd & PORT_CMD_FIS_ON) &&
                    239:                 !s->dev[port].init_d2h_sent) {
                    240:                 ahci_init_d2h(&s->dev[port]);
                    241:                 s->dev[port].init_d2h_sent = 1;
                    242:             }
                    243: 
                    244:             check_cmd(s, port);
                    245:             break;
                    246:         case PORT_TFDATA:
                    247:             s->dev[port].port.ifs[0].error = (val >> 8) & 0xff;
                    248:             s->dev[port].port.ifs[0].status = val & 0xff;
                    249:             break;
                    250:         case PORT_SIG:
                    251:             pr->sig = val;
                    252:             break;
                    253:         case PORT_SCR_STAT:
                    254:             pr->scr_stat = val;
                    255:             break;
                    256:         case PORT_SCR_CTL:
                    257:             if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) &&
                    258:                 ((val & AHCI_SCR_SCTL_DET) == 0)) {
                    259:                 ahci_reset_port(s, port);
                    260:             }
                    261:             pr->scr_ctl = val;
                    262:             break;
                    263:         case PORT_SCR_ERR:
                    264:             pr->scr_err &= ~val;
                    265:             break;
                    266:         case PORT_SCR_ACT:
                    267:             /* RW1 */
                    268:             pr->scr_act |= val;
                    269:             break;
                    270:         case PORT_CMD_ISSUE:
                    271:             pr->cmd_issue |= val;
                    272:             check_cmd(s, port);
                    273:             break;
                    274:         default:
                    275:             break;
                    276:     }
                    277: }
                    278: 
                    279: static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
                    280: {
                    281:     AHCIState *s = ptr;
                    282:     uint32_t val = 0;
                    283: 
                    284:     addr = addr & 0xfff;
                    285:     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
                    286:         switch (addr) {
                    287:         case HOST_CAP:
                    288:             val = s->control_regs.cap;
                    289:             break;
                    290:         case HOST_CTL:
                    291:             val = s->control_regs.ghc;
                    292:             break;
                    293:         case HOST_IRQ_STAT:
                    294:             val = s->control_regs.irqstatus;
                    295:             break;
                    296:         case HOST_PORTS_IMPL:
                    297:             val = s->control_regs.impl;
                    298:             break;
                    299:         case HOST_VERSION:
                    300:             val = s->control_regs.version;
                    301:             break;
                    302:         }
                    303: 
                    304:         DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
                    305:     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                    306:                (addr < (AHCI_PORT_REGS_START_ADDR +
                    307:                 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
                    308:         val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                    309:                              addr & AHCI_PORT_ADDR_OFFSET_MASK);
                    310:     }
                    311: 
                    312:     return val;
                    313: }
                    314: 
                    315: 
                    316: 
                    317: static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
                    318: {
                    319:     AHCIState *s = ptr;
                    320:     addr = addr & 0xfff;
                    321: 
                    322:     /* Only aligned reads are allowed on AHCI */
                    323:     if (addr & 3) {
                    324:         fprintf(stderr, "ahci: Mis-aligned write to addr 0x"
                    325:                 TARGET_FMT_plx "\n", addr);
                    326:         return;
                    327:     }
                    328: 
                    329:     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
                    330:         DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
                    331: 
                    332:         switch (addr) {
                    333:             case HOST_CAP: /* R/WO, RO */
                    334:                 /* FIXME handle R/WO */
                    335:                 break;
                    336:             case HOST_CTL: /* R/W */
                    337:                 if (val & HOST_CTL_RESET) {
                    338:                     DPRINTF(-1, "HBA Reset\n");
                    339:                     ahci_reset(container_of(s, AHCIPCIState, ahci));
                    340:                 } else {
                    341:                     s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                    342:                     ahci_check_irq(s);
                    343:                 }
                    344:                 break;
                    345:             case HOST_IRQ_STAT: /* R/WC, RO */
                    346:                 s->control_regs.irqstatus &= ~val;
                    347:                 ahci_check_irq(s);
                    348:                 break;
                    349:             case HOST_PORTS_IMPL: /* R/WO, RO */
                    350:                 /* FIXME handle R/WO */
                    351:                 break;
                    352:             case HOST_VERSION: /* RO */
                    353:                 /* FIXME report write? */
                    354:                 break;
                    355:             default:
                    356:                 DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
                    357:         }
                    358:     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                    359:                (addr < (AHCI_PORT_REGS_START_ADDR +
                    360:                 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
                    361:         ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                    362:                         addr & AHCI_PORT_ADDR_OFFSET_MASK, val);
                    363:     }
                    364: 
                    365: }
                    366: 
                    367: static CPUReadMemoryFunc * const ahci_readfn[3]={
                    368:     ahci_mem_readl,
                    369:     ahci_mem_readl,
                    370:     ahci_mem_readl
                    371: };
                    372: 
                    373: static CPUWriteMemoryFunc * const ahci_writefn[3]={
                    374:     ahci_mem_writel,
                    375:     ahci_mem_writel,
                    376:     ahci_mem_writel
                    377: };
                    378: 
                    379: static void ahci_reg_init(AHCIState *s)
                    380: {
                    381:     int i;
                    382: 
                    383:     s->control_regs.cap = (s->ports - 1) |
                    384:                           (AHCI_NUM_COMMAND_SLOTS << 8) |
                    385:                           (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |
                    386:                           HOST_CAP_NCQ | HOST_CAP_AHCI;
                    387: 
                    388:     s->control_regs.impl = (1 << s->ports) - 1;
                    389: 
                    390:     s->control_regs.version = AHCI_VERSION_1_0;
                    391: 
                    392:     for (i = 0; i < s->ports; i++) {
                    393:         s->dev[i].port_state = STATE_RUN;
                    394:     }
                    395: }
                    396: 
                    397: static uint32_t read_from_sglist(uint8_t *buffer, uint32_t len,
                    398:                                  QEMUSGList *sglist)
                    399: {
                    400:     uint32_t i = 0;
                    401:     uint32_t total = 0, once;
                    402:     ScatterGatherEntry *cur_prd;
                    403:     uint32_t sgcount;
                    404: 
                    405:     cur_prd = sglist->sg;
                    406:     sgcount = sglist->nsg;
                    407:     for (i = 0; len && sgcount; i++) {
                    408:         once = MIN(cur_prd->len, len);
                    409:         cpu_physical_memory_read(cur_prd->base, buffer, once);
                    410:         cur_prd++;
                    411:         sgcount--;
                    412:         len -= once;
                    413:         buffer += once;
                    414:         total += once;
                    415:     }
                    416: 
                    417:     return total;
                    418: }
                    419: 
                    420: static uint32_t write_to_sglist(uint8_t *buffer, uint32_t len,
                    421:                                 QEMUSGList *sglist)
                    422: {
                    423:     uint32_t i = 0;
                    424:     uint32_t total = 0, once;
                    425:     ScatterGatherEntry *cur_prd;
                    426:     uint32_t sgcount;
                    427: 
                    428:     DPRINTF(-1, "total: 0x%x bytes\n", len);
                    429: 
                    430:     cur_prd = sglist->sg;
                    431:     sgcount = sglist->nsg;
                    432:     for (i = 0; len && sgcount; i++) {
                    433:         once = MIN(cur_prd->len, len);
                    434:         DPRINTF(-1, "write 0x%x bytes to 0x%lx\n", once, (long)cur_prd->base);
                    435:         cpu_physical_memory_write(cur_prd->base, buffer, once);
                    436:         cur_prd++;
                    437:         sgcount--;
                    438:         len -= once;
                    439:         buffer += once;
                    440:         total += once;
                    441:     }
                    442: 
                    443:     return total;
                    444: }
                    445: 
                    446: static void check_cmd(AHCIState *s, int port)
                    447: {
                    448:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    449:     int slot;
                    450: 
                    451:     if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
                    452:         for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
                    453:             if ((pr->cmd_issue & (1 << slot)) &&
                    454:                 !handle_cmd(s, port, slot)) {
                    455:                 pr->cmd_issue &= ~(1 << slot);
                    456:             }
                    457:         }
                    458:     }
                    459: }
                    460: 
                    461: static void ahci_check_cmd_bh(void *opaque)
                    462: {
                    463:     AHCIDevice *ad = opaque;
                    464: 
                    465:     qemu_bh_delete(ad->check_bh);
                    466:     ad->check_bh = NULL;
                    467: 
                    468:     if ((ad->busy_slot != -1) &&
                    469:         !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
                    470:         /* no longer busy */
                    471:         ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
                    472:         ad->busy_slot = -1;
                    473:     }
                    474: 
                    475:     check_cmd(ad->hba, ad->port_no);
                    476: }
                    477: 
                    478: static void ahci_init_d2h(AHCIDevice *ad)
                    479: {
                    480:     uint8_t init_fis[0x20];
                    481:     IDEState *ide_state = &ad->port.ifs[0];
                    482: 
                    483:     memset(init_fis, 0, sizeof(init_fis));
                    484: 
                    485:     init_fis[4] = 1;
                    486:     init_fis[12] = 1;
                    487: 
                    488:     if (ide_state->drive_kind == IDE_CD) {
                    489:         init_fis[5] = ide_state->lcyl;
                    490:         init_fis[6] = ide_state->hcyl;
                    491:     }
                    492: 
                    493:     ahci_write_fis_d2h(ad, init_fis);
                    494: }
                    495: 
                    496: static void ahci_reset_port(AHCIState *s, int port)
                    497: {
                    498:     AHCIDevice *d = &s->dev[port];
                    499:     AHCIPortRegs *pr = &d->port_regs;
                    500:     IDEState *ide_state = &d->port.ifs[0];
                    501:     int i;
                    502: 
                    503:     DPRINTF(port, "reset port\n");
                    504: 
                    505:     ide_bus_reset(&d->port);
                    506:     ide_state->ncq_queues = AHCI_MAX_CMDS;
                    507: 
                    508:     pr->irq_stat = 0;
                    509:     pr->irq_mask = 0;
                    510:     pr->scr_stat = 0;
                    511:     pr->scr_ctl = 0;
                    512:     pr->scr_err = 0;
                    513:     pr->scr_act = 0;
                    514:     d->busy_slot = -1;
                    515:     d->init_d2h_sent = 0;
                    516: 
                    517:     ide_state = &s->dev[port].port.ifs[0];
                    518:     if (!ide_state->bs) {
                    519:         return;
                    520:     }
                    521: 
                    522:     /* reset ncq queue */
                    523:     for (i = 0; i < AHCI_MAX_CMDS; i++) {
                    524:         NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
                    525:         if (!ncq_tfs->used) {
                    526:             continue;
                    527:         }
                    528: 
                    529:         if (ncq_tfs->aiocb) {
                    530:             bdrv_aio_cancel(ncq_tfs->aiocb);
                    531:             ncq_tfs->aiocb = NULL;
                    532:         }
                    533: 
                    534:         qemu_sglist_destroy(&ncq_tfs->sglist);
                    535:         ncq_tfs->used = 0;
                    536:     }
                    537: 
                    538:     s->dev[port].port_state = STATE_RUN;
                    539:     if (!ide_state->bs) {
                    540:         s->dev[port].port_regs.sig = 0;
                    541:         ide_state->status = SEEK_STAT | WRERR_STAT;
                    542:     } else if (ide_state->drive_kind == IDE_CD) {
                    543:         s->dev[port].port_regs.sig = SATA_SIGNATURE_CDROM;
                    544:         ide_state->lcyl = 0x14;
                    545:         ide_state->hcyl = 0xeb;
                    546:         DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
                    547:         ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
                    548:     } else {
                    549:         s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK;
                    550:         ide_state->status = SEEK_STAT | WRERR_STAT;
                    551:     }
                    552: 
                    553:     ide_state->error = 1;
                    554:     ahci_init_d2h(d);
                    555: }
                    556: 
                    557: static void debug_print_fis(uint8_t *fis, int cmd_len)
                    558: {
                    559: #ifdef DEBUG_AHCI
                    560:     int i;
                    561: 
                    562:     fprintf(stderr, "fis:");
                    563:     for (i = 0; i < cmd_len; i++) {
                    564:         if ((i & 0xf) == 0) {
                    565:             fprintf(stderr, "\n%02x:",i);
                    566:         }
                    567:         fprintf(stderr, "%02x ",fis[i]);
                    568:     }
                    569:     fprintf(stderr, "\n");
                    570: #endif
                    571: }
                    572: 
                    573: static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
                    574: {
                    575:     AHCIPortRegs *pr = &s->dev[port].port_regs;
                    576:     IDEState *ide_state;
                    577:     uint8_t *sdb_fis;
                    578: 
                    579:     if (!s->dev[port].res_fis ||
                    580:         !(pr->cmd & PORT_CMD_FIS_RX)) {
                    581:         return;
                    582:     }
                    583: 
                    584:     sdb_fis = &s->dev[port].res_fis[RES_FIS_SDBFIS];
                    585:     ide_state = &s->dev[port].port.ifs[0];
                    586: 
                    587:     /* clear memory */
                    588:     *(uint32_t*)sdb_fis = 0;
                    589: 
                    590:     /* write values */
                    591:     sdb_fis[0] = ide_state->error;
                    592:     sdb_fis[2] = ide_state->status & 0x77;
                    593:     s->dev[port].finished |= finished;
                    594:     *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(s->dev[port].finished);
                    595: 
                    596:     ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_STAT_SDBS);
                    597: }
                    598: 
                    599: static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
                    600: {
                    601:     AHCIPortRegs *pr = &ad->port_regs;
                    602:     uint8_t *d2h_fis;
                    603:     int i;
                    604:     target_phys_addr_t cmd_len = 0x80;
                    605:     int cmd_mapped = 0;
                    606: 
                    607:     if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
                    608:         return;
                    609:     }
                    610: 
                    611:     if (!cmd_fis) {
                    612:         /* map cmd_fis */
                    613:         uint64_t tbl_addr = le64_to_cpu(ad->cur_cmd->tbl_addr);
                    614:         cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 0);
                    615:         cmd_mapped = 1;
                    616:     }
                    617: 
                    618:     d2h_fis = &ad->res_fis[RES_FIS_RFIS];
                    619: 
                    620:     d2h_fis[0] = 0x34;
                    621:     d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
                    622:     d2h_fis[2] = ad->port.ifs[0].status;
                    623:     d2h_fis[3] = ad->port.ifs[0].error;
                    624: 
                    625:     d2h_fis[4] = cmd_fis[4];
                    626:     d2h_fis[5] = cmd_fis[5];
                    627:     d2h_fis[6] = cmd_fis[6];
                    628:     d2h_fis[7] = cmd_fis[7];
                    629:     d2h_fis[8] = cmd_fis[8];
                    630:     d2h_fis[9] = cmd_fis[9];
                    631:     d2h_fis[10] = cmd_fis[10];
                    632:     d2h_fis[11] = cmd_fis[11];
                    633:     d2h_fis[12] = cmd_fis[12];
                    634:     d2h_fis[13] = cmd_fis[13];
                    635:     for (i = 14; i < 0x20; i++) {
                    636:         d2h_fis[i] = 0;
                    637:     }
                    638: 
                    639:     if (d2h_fis[2] & ERR_STAT) {
                    640:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_TFES);
                    641:     }
                    642: 
                    643:     ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
                    644: 
                    645:     if (cmd_mapped) {
                    646:         cpu_physical_memory_unmap(cmd_fis, cmd_len, 0, cmd_len);
                    647:     }
                    648: }
                    649: 
                    650: static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist)
                    651: {
                    652:     AHCICmdHdr *cmd = ad->cur_cmd;
                    653:     uint32_t opts = le32_to_cpu(cmd->opts);
                    654:     uint64_t prdt_addr = le64_to_cpu(cmd->tbl_addr) + 0x80;
                    655:     int sglist_alloc_hint = opts >> AHCI_CMD_HDR_PRDT_LEN;
                    656:     target_phys_addr_t prdt_len = (sglist_alloc_hint * sizeof(AHCI_SG));
                    657:     target_phys_addr_t real_prdt_len = prdt_len;
                    658:     uint8_t *prdt;
                    659:     int i;
                    660:     int r = 0;
                    661: 
                    662:     if (!sglist_alloc_hint) {
                    663:         DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
                    664:         return -1;
                    665:     }
                    666: 
                    667:     /* map PRDT */
                    668:     if (!(prdt = cpu_physical_memory_map(prdt_addr, &prdt_len, 0))){
                    669:         DPRINTF(ad->port_no, "map failed\n");
                    670:         return -1;
                    671:     }
                    672: 
                    673:     if (prdt_len < real_prdt_len) {
                    674:         DPRINTF(ad->port_no, "mapped less than expected\n");
                    675:         r = -1;
                    676:         goto out;
                    677:     }
                    678: 
                    679:     /* Get entries in the PRDT, init a qemu sglist accordingly */
                    680:     if (sglist_alloc_hint > 0) {
                    681:         AHCI_SG *tbl = (AHCI_SG *)prdt;
                    682: 
                    683:         qemu_sglist_init(sglist, sglist_alloc_hint);
                    684:         for (i = 0; i < sglist_alloc_hint; i++) {
                    685:             /* flags_size is zero-based */
                    686:             qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
                    687:                             le32_to_cpu(tbl[i].flags_size) + 1);
                    688:         }
                    689:     }
                    690: 
                    691: out:
                    692:     cpu_physical_memory_unmap(prdt, prdt_len, 0, prdt_len);
                    693:     return r;
                    694: }
                    695: 
                    696: static void ncq_cb(void *opaque, int ret)
                    697: {
                    698:     NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
                    699:     IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
                    700: 
                    701:     /* Clear bit for this tag in SActive */
                    702:     ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag);
                    703: 
                    704:     if (ret < 0) {
                    705:         /* error */
                    706:         ide_state->error = ABRT_ERR;
                    707:         ide_state->status = READY_STAT | ERR_STAT;
                    708:         ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
                    709:     } else {
                    710:         ide_state->status = READY_STAT | SEEK_STAT;
                    711:     }
                    712: 
                    713:     ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
                    714:                        (1 << ncq_tfs->tag));
                    715: 
                    716:     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
                    717:             ncq_tfs->tag);
                    718: 
                    719:     qemu_sglist_destroy(&ncq_tfs->sglist);
                    720:     ncq_tfs->used = 0;
                    721: }
                    722: 
                    723: static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
                    724:                                 int slot)
                    725: {
                    726:     NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
                    727:     uint8_t tag = ncq_fis->tag >> 3;
                    728:     NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[tag];
                    729: 
                    730:     if (ncq_tfs->used) {
                    731:         /* error - already in use */
                    732:         fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);
                    733:         return;
                    734:     }
                    735: 
                    736:     ncq_tfs->used = 1;
                    737:     ncq_tfs->drive = &s->dev[port];
                    738:     ncq_tfs->slot = slot;
                    739:     ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |
                    740:                    ((uint64_t)ncq_fis->lba4 << 32) |
                    741:                    ((uint64_t)ncq_fis->lba3 << 24) |
                    742:                    ((uint64_t)ncq_fis->lba2 << 16) |
                    743:                    ((uint64_t)ncq_fis->lba1 << 8) |
                    744:                    (uint64_t)ncq_fis->lba0;
                    745: 
                    746:     /* Note: We calculate the sector count, but don't currently rely on it.
                    747:      * The total size of the DMA buffer tells us the transfer size instead. */
                    748:     ncq_tfs->sector_count = ((uint16_t)ncq_fis->sector_count_high << 8) |
                    749:                                 ncq_fis->sector_count_low;
                    750: 
                    751:     DPRINTF(port, "NCQ transfer LBA from %ld to %ld, drive max %ld\n",
                    752:             ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2,
                    753:             s->dev[port].port.ifs[0].nb_sectors - 1);
                    754: 
                    755:     ahci_populate_sglist(&s->dev[port], &ncq_tfs->sglist);
                    756:     ncq_tfs->tag = tag;
                    757: 
                    758:     switch(ncq_fis->command) {
                    759:         case READ_FPDMA_QUEUED:
                    760:             DPRINTF(port, "NCQ reading %d sectors from LBA %ld, tag %d\n",
                    761:                     ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
                    762:             ncq_tfs->is_read = 1;
                    763: 
                    764:             DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);
                    765:             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
                    766:                                            &ncq_tfs->sglist, ncq_tfs->lba,
                    767:                                            ncq_cb, ncq_tfs);
                    768:             break;
                    769:         case WRITE_FPDMA_QUEUED:
                    770:             DPRINTF(port, "NCQ writing %d sectors to LBA %ld, tag %d\n",
                    771:                     ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
                    772:             ncq_tfs->is_read = 0;
                    773: 
                    774:             DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba);
                    775:             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
                    776:                                             &ncq_tfs->sglist, ncq_tfs->lba,
                    777:                                             ncq_cb, ncq_tfs);
                    778:             break;
                    779:         default:
                    780:             DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n");
                    781:             qemu_sglist_destroy(&ncq_tfs->sglist);
                    782:             break;
                    783:     }
                    784: }
                    785: 
                    786: static int handle_cmd(AHCIState *s, int port, int slot)
                    787: {
                    788:     IDEState *ide_state;
                    789:     uint32_t opts;
                    790:     uint64_t tbl_addr;
                    791:     AHCICmdHdr *cmd;
                    792:     uint8_t *cmd_fis;
                    793:     target_phys_addr_t cmd_len;
                    794: 
                    795:     if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
                    796:         /* Engine currently busy, try again later */
                    797:         DPRINTF(port, "engine busy\n");
                    798:         return -1;
                    799:     }
                    800: 
                    801:     cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
                    802: 
                    803:     if (!s->dev[port].lst) {
                    804:         DPRINTF(port, "error: lst not given but cmd handled");
                    805:         return -1;
                    806:     }
                    807: 
                    808:     /* remember current slot handle for later */
                    809:     s->dev[port].cur_cmd = cmd;
                    810: 
                    811:     opts = le32_to_cpu(cmd->opts);
                    812:     tbl_addr = le64_to_cpu(cmd->tbl_addr);
                    813: 
                    814:     cmd_len = 0x80;
                    815:     cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 1);
                    816: 
                    817:     if (!cmd_fis) {
                    818:         DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
                    819:         return -1;
                    820:     }
                    821: 
                    822:     /* The device we are working for */
                    823:     ide_state = &s->dev[port].port.ifs[0];
                    824: 
                    825:     if (!ide_state->bs) {
                    826:         DPRINTF(port, "error: guest accessed unused port");
                    827:         goto out;
                    828:     }
                    829: 
                    830:     debug_print_fis(cmd_fis, 0x90);
                    831:     //debug_print_fis(cmd_fis, (opts & AHCI_CMD_HDR_CMD_FIS_LEN) * 4);
                    832: 
                    833:     switch (cmd_fis[0]) {
                    834:         case SATA_FIS_TYPE_REGISTER_H2D:
                    835:             break;
                    836:         default:
                    837:             DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                    838:                           "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                    839:                           cmd_fis[2]);
                    840:             goto out;
                    841:             break;
                    842:     }
                    843: 
                    844:     switch (cmd_fis[1]) {
                    845:         case SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER:
                    846:             break;
                    847:         case 0:
                    848:             break;
                    849:         default:
                    850:             DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                    851:                           "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                    852:                           cmd_fis[2]);
                    853:             goto out;
                    854:             break;
                    855:     }
                    856: 
                    857:     switch (s->dev[port].port_state) {
                    858:         case STATE_RUN:
                    859:             if (cmd_fis[15] & ATA_SRST) {
                    860:                 s->dev[port].port_state = STATE_RESET;
                    861:             }
                    862:             break;
                    863:         case STATE_RESET:
                    864:             if (!(cmd_fis[15] & ATA_SRST)) {
                    865:                 ahci_reset_port(s, port);
                    866:             }
                    867:             break;
                    868:     }
                    869: 
                    870:     if (cmd_fis[1] == SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER) {
                    871: 
                    872:         /* Check for NCQ command */
                    873:         if ((cmd_fis[2] == READ_FPDMA_QUEUED) ||
                    874:             (cmd_fis[2] == WRITE_FPDMA_QUEUED)) {
                    875:             process_ncq_command(s, port, cmd_fis, slot);
                    876:             goto out;
                    877:         }
                    878: 
                    879:         /* Decompose the FIS  */
                    880:         ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
                    881:         ide_state->feature = cmd_fis[3];
                    882:         if (!ide_state->nsector) {
                    883:             ide_state->nsector = 256;
                    884:         }
                    885: 
                    886:         if (ide_state->drive_kind != IDE_CD) {
1.1.1.2 ! root      887:             /*
        !           888:              * We set the sector depending on the sector defined in the FIS.
        !           889:              * Unfortunately, the spec isn't exactly obvious on this one.
        !           890:              *
        !           891:              * Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the
        !           892:              * 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for
        !           893:              * such a command.
        !           894:              *
        !           895:              * Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a
        !           896:              * 28-bit sector number. ATA_CMD_READ_DMA is an example for such
        !           897:              * a command.
        !           898:              *
        !           899:              * Since the spec doesn't explicitly state what each field should
        !           900:              * do, I simply assume non-used fields as reserved and OR everything
        !           901:              * together, independent of the command.
        !           902:              */
        !           903:             ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40)
        !           904:                                     | ((uint64_t)cmd_fis[9] << 32)
        !           905:                                     /* This is used for LBA48 commands */
        !           906:                                     | ((uint64_t)cmd_fis[8] << 24)
        !           907:                                     /* This is used for non-LBA48 commands */
        !           908:                                     | ((uint64_t)(cmd_fis[7] & 0xf) << 24)
        !           909:                                     | ((uint64_t)cmd_fis[6] << 16)
        !           910:                                     | ((uint64_t)cmd_fis[5] << 8)
        !           911:                                     | cmd_fis[4]);
1.1       root      912:         }
                    913: 
                    914:         /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
                    915:          * table to ide_state->io_buffer
                    916:          */
                    917:         if (opts & AHCI_CMD_ATAPI) {
                    918:             memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
                    919:             ide_state->lcyl = 0x14;
                    920:             ide_state->hcyl = 0xeb;
                    921:             debug_print_fis(ide_state->io_buffer, 0x10);
                    922:             ide_state->feature = IDE_FEATURE_DMA;
                    923:             s->dev[port].done_atapi_packet = 0;
                    924:             /* XXX send PIO setup FIS */
                    925:         }
                    926: 
                    927:         ide_state->error = 0;
                    928: 
                    929:         /* Reset transferred byte counter */
                    930:         cmd->status = 0;
                    931: 
                    932:         /* We're ready to process the command in FIS byte 2. */
                    933:         ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
                    934: 
                    935:         if (s->dev[port].port.ifs[0].status & READY_STAT) {
                    936:             ahci_write_fis_d2h(&s->dev[port], cmd_fis);
                    937:         }
                    938:     }
                    939: 
                    940: out:
                    941:     cpu_physical_memory_unmap(cmd_fis, cmd_len, 1, cmd_len);
                    942: 
                    943:     if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
                    944:         /* async command, complete later */
                    945:         s->dev[port].busy_slot = slot;
                    946:         return -1;
                    947:     }
                    948: 
                    949:     /* done handling the command */
                    950:     return 0;
                    951: }
                    952: 
                    953: /* DMA dev <-> ram */
                    954: static int ahci_start_transfer(IDEDMA *dma)
                    955: {
                    956:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                    957:     IDEState *s = &ad->port.ifs[0];
                    958:     uint32_t size = (uint32_t)(s->data_end - s->data_ptr);
                    959:     /* write == ram -> device */
                    960:     uint32_t opts = le32_to_cpu(ad->cur_cmd->opts);
                    961:     int is_write = opts & AHCI_CMD_WRITE;
                    962:     int is_atapi = opts & AHCI_CMD_ATAPI;
                    963:     int has_sglist = 0;
                    964: 
                    965:     if (is_atapi && !ad->done_atapi_packet) {
                    966:         /* already prepopulated iobuffer */
                    967:         ad->done_atapi_packet = 1;
                    968:         goto out;
                    969:     }
                    970: 
                    971:     if (!ahci_populate_sglist(ad, &s->sg)) {
                    972:         has_sglist = 1;
                    973:     }
                    974: 
                    975:     DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
                    976:             is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
                    977:             has_sglist ? "" : "o");
                    978: 
                    979:     if (is_write && has_sglist && (s->data_ptr < s->data_end)) {
                    980:         read_from_sglist(s->data_ptr, size, &s->sg);
                    981:     }
                    982: 
                    983:     if (!is_write && has_sglist && (s->data_ptr < s->data_end)) {
                    984:         write_to_sglist(s->data_ptr, size, &s->sg);
                    985:     }
                    986: 
                    987:     /* update number of transferred bytes */
                    988:     ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + size);
                    989: 
                    990: out:
                    991:     /* declare that we processed everything */
                    992:     s->data_ptr = s->data_end;
                    993: 
                    994:     if (has_sglist) {
                    995:         qemu_sglist_destroy(&s->sg);
                    996:     }
                    997: 
                    998:     s->end_transfer_func(s);
                    999: 
                   1000:     if (!(s->status & DRQ_STAT)) {
                   1001:         /* done with DMA */
                   1002:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
                   1003:     }
                   1004: 
                   1005:     return 0;
                   1006: }
                   1007: 
                   1008: static void ahci_start_dma(IDEDMA *dma, IDEState *s,
                   1009:                            BlockDriverCompletionFunc *dma_cb)
                   1010: {
                   1011:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1012: 
                   1013:     DPRINTF(ad->port_no, "\n");
                   1014:     ad->dma_cb = dma_cb;
                   1015:     ad->dma_status |= BM_STATUS_DMAING;
                   1016:     dma_cb(s, 0);
                   1017: }
                   1018: 
                   1019: static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
                   1020: {
                   1021:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1022:     IDEState *s = &ad->port.ifs[0];
                   1023:     int i;
                   1024: 
                   1025:     ahci_populate_sglist(ad, &s->sg);
                   1026: 
                   1027:     s->io_buffer_size = 0;
                   1028:     for (i = 0; i < s->sg.nsg; i++) {
                   1029:         s->io_buffer_size += s->sg.sg[i].len;
                   1030:     }
                   1031: 
                   1032:     DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
                   1033:     return s->io_buffer_size != 0;
                   1034: }
                   1035: 
                   1036: static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
                   1037: {
                   1038:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1039:     IDEState *s = &ad->port.ifs[0];
                   1040:     uint8_t *p = s->io_buffer + s->io_buffer_index;
                   1041:     int l = s->io_buffer_size - s->io_buffer_index;
                   1042: 
                   1043:     if (ahci_populate_sglist(ad, &s->sg)) {
                   1044:         return 0;
                   1045:     }
                   1046: 
                   1047:     if (is_write) {
                   1048:         write_to_sglist(p, l, &s->sg);
                   1049:     } else {
                   1050:         read_from_sglist(p, l, &s->sg);
                   1051:     }
                   1052: 
                   1053:     /* update number of transferred bytes */
                   1054:     ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + l);
                   1055:     s->io_buffer_index += l;
                   1056: 
                   1057:     DPRINTF(ad->port_no, "len=%#x\n", l);
                   1058: 
                   1059:     return 1;
                   1060: }
                   1061: 
                   1062: static int ahci_dma_set_unit(IDEDMA *dma, int unit)
                   1063: {
                   1064:     /* only a single unit per link */
                   1065:     return 0;
                   1066: }
                   1067: 
                   1068: static int ahci_dma_add_status(IDEDMA *dma, int status)
                   1069: {
                   1070:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1071:     ad->dma_status |= status;
                   1072:     DPRINTF(ad->port_no, "set status: %x\n", status);
                   1073: 
                   1074:     if (status & BM_STATUS_INT) {
                   1075:         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
                   1076:     }
                   1077: 
                   1078:     return 0;
                   1079: }
                   1080: 
                   1081: static int ahci_dma_set_inactive(IDEDMA *dma)
                   1082: {
                   1083:     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
                   1084: 
                   1085:     DPRINTF(ad->port_no, "dma done\n");
                   1086: 
                   1087:     /* update d2h status */
                   1088:     ahci_write_fis_d2h(ad, NULL);
                   1089: 
                   1090:     ad->dma_cb = NULL;
                   1091: 
1.1.1.2 ! root     1092:     if (!ad->check_bh) {
        !          1093:         /* maybe we still have something to process, check later */
        !          1094:         ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
        !          1095:         qemu_bh_schedule(ad->check_bh);
        !          1096:     }
1.1       root     1097: 
                   1098:     return 0;
                   1099: }
                   1100: 
                   1101: static void ahci_irq_set(void *opaque, int n, int level)
                   1102: {
                   1103: }
                   1104: 
                   1105: static void ahci_dma_restart_cb(void *opaque, int running, int reason)
                   1106: {
                   1107: }
                   1108: 
                   1109: static int ahci_dma_reset(IDEDMA *dma)
                   1110: {
                   1111:     return 0;
                   1112: }
                   1113: 
                   1114: static const IDEDMAOps ahci_dma_ops = {
                   1115:     .start_dma = ahci_start_dma,
                   1116:     .start_transfer = ahci_start_transfer,
                   1117:     .prepare_buf = ahci_dma_prepare_buf,
                   1118:     .rw_buf = ahci_dma_rw_buf,
                   1119:     .set_unit = ahci_dma_set_unit,
                   1120:     .add_status = ahci_dma_add_status,
                   1121:     .set_inactive = ahci_dma_set_inactive,
                   1122:     .restart_cb = ahci_dma_restart_cb,
                   1123:     .reset = ahci_dma_reset,
                   1124: };
                   1125: 
                   1126: void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
                   1127: {
                   1128:     qemu_irq *irqs;
                   1129:     int i;
                   1130: 
                   1131:     s->ports = ports;
                   1132:     s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports);
                   1133:     ahci_reg_init(s);
                   1134:     s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s,
                   1135:                                     DEVICE_LITTLE_ENDIAN);
                   1136:     irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
                   1137: 
                   1138:     for (i = 0; i < s->ports; i++) {
                   1139:         AHCIDevice *ad = &s->dev[i];
                   1140: 
                   1141:         ide_bus_new(&ad->port, qdev, i);
                   1142:         ide_init2(&ad->port, irqs[i]);
                   1143: 
                   1144:         ad->hba = s;
                   1145:         ad->port_no = i;
                   1146:         ad->port.dma = &ad->dma;
                   1147:         ad->port.dma->ops = &ahci_dma_ops;
                   1148:         ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
                   1149:     }
                   1150: }
                   1151: 
                   1152: void ahci_uninit(AHCIState *s)
                   1153: {
                   1154:     qemu_free(s->dev);
                   1155: }
                   1156: 
                   1157: void ahci_reset(void *opaque)
                   1158: {
                   1159:     struct AHCIPCIState *d = opaque;
                   1160:     int i;
                   1161: 
                   1162:     d->ahci.control_regs.irqstatus = 0;
                   1163:     d->ahci.control_regs.ghc = 0;
                   1164: 
                   1165:     for (i = 0; i < d->ahci.ports; i++) {
                   1166:         ahci_reset_port(&d->ahci, i);
                   1167:     }
                   1168: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.