Lines Matching +full:- +full:chs

28 #include "qemu/error-report.h"
30 #include "qemu/main-loop.h"
31 #include "system/block-backend.h"
33 #include "ahci-internal.h"
34 #include "ide-internal.h"
113 AHCIPortRegs *pr = &s->dev[port].port_regs; in ahci_port_read()
119 val = pr->lst_addr; in ahci_port_read()
122 val = pr->lst_addr_hi; in ahci_port_read()
125 val = pr->fis_addr; in ahci_port_read()
128 val = pr->fis_addr_hi; in ahci_port_read()
131 val = pr->irq_stat; in ahci_port_read()
134 val = pr->irq_mask; in ahci_port_read()
137 val = pr->cmd; in ahci_port_read()
140 val = pr->tfdata; in ahci_port_read()
143 val = pr->sig; in ahci_port_read()
146 if (s->dev[port].port.ifs[0].blk) { in ahci_port_read()
154 val = pr->scr_ctl; in ahci_port_read()
157 val = pr->scr_err; in ahci_port_read()
160 val = pr->scr_act; in ahci_port_read()
163 val = pr->cmd_issue; in ahci_port_read()
178 uint32_t old_irq = s->control_regs.irqstatus; in ahci_check_irq()
180 s->control_regs.irqstatus = 0; in ahci_check_irq()
181 for (i = 0; i < s->ports; i++) { in ahci_check_irq()
182 AHCIPortRegs *pr = &s->dev[i].port_regs; in ahci_check_irq()
183 if (pr->irq_stat & pr->irq_mask) { in ahci_check_irq()
184 s->control_regs.irqstatus |= (1 << i); in ahci_check_irq()
187 trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus); in ahci_check_irq()
188 if (s->control_regs.irqstatus && in ahci_check_irq()
189 (s->control_regs.ghc & HOST_CTL_IRQ_EN)) { in ahci_check_irq()
191 qemu_irq_raise(s->irq); in ahci_check_irq()
194 qemu_irq_lower(s->irq); in ahci_check_irq()
203 uint32_t irqstat = d->port_regs.irq_stat | irq; in ahci_trigger_irq()
205 trace_ahci_trigger_irq(s, d->port_no, in ahci_trigger_irq()
207 d->port_regs.irq_stat, irqstat, in ahci_trigger_irq()
208 irqstat & d->port_regs.irq_mask); in ahci_trigger_irq()
210 d->port_regs.irq_stat = irqstat; in ahci_trigger_irq()
237 * @return 0 on success, -1 on error.
241 AHCIPortRegs *pr = &ad->port_regs; in ahci_cond_start_engines()
242 bool cmd_start = pr->cmd & PORT_CMD_START; in ahci_cond_start_engines()
243 bool cmd_on = pr->cmd & PORT_CMD_LIST_ON; in ahci_cond_start_engines()
244 bool fis_start = pr->cmd & PORT_CMD_FIS_RX; in ahci_cond_start_engines()
245 bool fis_on = pr->cmd & PORT_CMD_FIS_ON; in ahci_cond_start_engines()
249 pr->cmd &= ~PORT_CMD_START; in ahci_cond_start_engines()
252 return -1; in ahci_cond_start_engines()
260 pr->cmd &= ~PORT_CMD_FIS_RX; in ahci_cond_start_engines()
263 return -1; in ahci_cond_start_engines()
274 AHCIPortRegs *pr = &s->dev[port].port_regs; in ahci_port_write()
281 pr->lst_addr = val; in ahci_port_write()
284 pr->lst_addr_hi = val; in ahci_port_write()
287 pr->fis_addr = val; in ahci_port_write()
290 pr->fis_addr_hi = val; in ahci_port_write()
293 pr->irq_stat &= ~val; in ahci_port_write()
297 pr->irq_mask = val & 0xfdc000ff; in ahci_port_write()
301 if ((pr->cmd & PORT_CMD_START) && !(val & PORT_CMD_START)) { in ahci_port_write()
302 pr->scr_act = 0; in ahci_port_write()
303 pr->cmd_issue = 0; in ahci_port_write()
306 /* Block any Read-only fields from being set; in ahci_port_write()
312 pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) | in ahci_port_write()
316 ahci_cond_start_engines(&s->dev[port]); in ahci_port_write()
320 Instead, we only submit it once - which works in most in ahci_port_write()
322 if ((pr->cmd & PORT_CMD_FIS_ON) && in ahci_port_write()
323 !s->dev[port].init_d2h_sent) { in ahci_port_write()
324 ahci_init_d2h(&s->dev[port]); in ahci_port_write()
335 if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) && in ahci_port_write()
339 pr->scr_ctl = val; in ahci_port_write()
342 pr->scr_err &= ~val; in ahci_port_write()
346 pr->scr_act |= val; in ahci_port_write()
349 pr->cmd_issue |= val; in ahci_port_write()
373 val = s->control_regs.cap; in ahci_mem_read_32()
376 val = s->control_regs.ghc; in ahci_mem_read_32()
379 val = s->control_regs.irqstatus; in ahci_mem_read_32()
382 val = s->control_regs.impl; in ahci_mem_read_32()
385 val = s->control_regs.version; in ahci_mem_read_32()
394 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) { in ahci_mem_read_32()
395 val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7, in ahci_mem_read_32()
414 int ofst = addr - aligned; in ahci_mem_read()
446 "ahci: Mis-aligned write to addr 0x%03" HWADDR_PRIX "\n", in ahci_mem_write()
463 s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN; in ahci_mem_write()
468 s->control_regs.irqstatus &= ~val; in ahci_mem_write()
490 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) { in ahci_mem_write()
491 ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7, in ahci_mem_write()
512 if (addr == s->idp_offset) { in ahci_idp_read()
514 return s->idp_index; in ahci_idp_read()
515 } else if (addr == s->idp_offset + 4) { in ahci_idp_read()
516 /* data register - do memory read at location selected by index */ in ahci_idp_read()
517 return ahci_mem_read(opaque, s->idp_index, size); in ahci_idp_read()
528 if (addr == s->idp_offset) { in ahci_idp_write()
529 /* index register - mask off reserved bits */ in ahci_idp_write()
530 s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3); in ahci_idp_write()
531 } else if (addr == s->idp_offset + 4) { in ahci_idp_write()
532 /* data register - do memory write at location selected by index */ in ahci_idp_write()
533 ahci_mem_write(opaque, s->idp_index, val, size); in ahci_idp_write()
548 s->control_regs.cap = (s->ports - 1) | in ahci_reg_init()
553 s->control_regs.impl = (1 << s->ports) - 1; in ahci_reg_init()
555 s->control_regs.version = AHCI_VERSION_1_0; in ahci_reg_init()
557 for (i = 0; i < s->ports; i++) { in ahci_reg_init()
558 s->dev[i].port_state = STATE_RUN; in ahci_reg_init()
564 AHCIPortRegs *pr = &s->dev[port].port_regs; in check_cmd()
567 if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) { in check_cmd()
568 for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) { in check_cmd()
569 if (pr->cmd_issue & (1U << slot)) { in check_cmd()
580 qemu_bh_delete(ad->check_bh); in ahci_check_cmd_bh()
581 ad->check_bh = NULL; in ahci_check_cmd_bh()
583 check_cmd(ad->hba, ad->port_no); in ahci_check_cmd_bh()
588 IDEState *ide_state = &ad->port.ifs[0]; in ahci_init_d2h()
589 AHCIPortRegs *pr = &ad->port_regs; in ahci_init_d2h()
591 if (ad->init_d2h_sent) { in ahci_init_d2h()
600 ad->init_d2h_sent = true; in ahci_init_d2h()
603 pr->sig = ((uint32_t)ide_state->hcyl << 24) | in ahci_init_d2h()
604 (ide_state->lcyl << 16) | in ahci_init_d2h()
605 (ide_state->sector << 8) | in ahci_init_d2h()
606 (ide_state->nsector & 0xFF); in ahci_init_d2h()
612 IDEState *s = &ad->port.ifs[0]; in ahci_set_signature()
613 s->hcyl = sig >> 24 & 0xFF; in ahci_set_signature()
614 s->lcyl = sig >> 16 & 0xFF; in ahci_set_signature()
615 s->sector = sig >> 8 & 0xFF; in ahci_set_signature()
616 s->nsector = sig & 0xFF; in ahci_set_signature()
618 trace_ahci_set_signature(ad->hba, ad->port_no, s->nsector, s->sector, in ahci_set_signature()
619 s->lcyl, s->hcyl, sig); in ahci_set_signature()
624 AHCIDevice *d = &s->dev[port]; in ahci_reset_port()
625 AHCIPortRegs *pr = &d->port_regs; in ahci_reset_port()
626 IDEState *ide_state = &d->port.ifs[0]; in ahci_reset_port()
631 ide_bus_reset(&d->port); in ahci_reset_port()
632 ide_state->ncq_queues = AHCI_MAX_CMDS; in ahci_reset_port()
634 pr->scr_stat = 0; in ahci_reset_port()
635 pr->scr_err = 0; in ahci_reset_port()
636 pr->scr_act = 0; in ahci_reset_port()
637 pr->tfdata = 0x7F; in ahci_reset_port()
638 pr->sig = 0xFFFFFFFF; in ahci_reset_port()
639 pr->cmd_issue = 0; in ahci_reset_port()
640 d->busy_slot = -1; in ahci_reset_port()
641 d->init_d2h_sent = false; in ahci_reset_port()
643 ide_state = &s->dev[port].port.ifs[0]; in ahci_reset_port()
644 if (!ide_state->blk) { in ahci_reset_port()
650 NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i]; in ahci_reset_port()
651 ncq_tfs->halt = false; in ahci_reset_port()
652 if (!ncq_tfs->used) { in ahci_reset_port()
656 if (ncq_tfs->aiocb) { in ahci_reset_port()
657 blk_aio_cancel(ncq_tfs->aiocb); in ahci_reset_port()
658 ncq_tfs->aiocb = NULL; in ahci_reset_port()
662 if (!ncq_tfs->used) { in ahci_reset_port()
666 qemu_sglist_destroy(&ncq_tfs->sglist); in ahci_reset_port()
667 ncq_tfs->used = 0; in ahci_reset_port()
670 s->dev[port].port_state = STATE_RUN; in ahci_reset_port()
671 if (ide_state->drive_kind == IDE_CD) { in ahci_reset_port()
673 ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT; in ahci_reset_port()
676 ide_state->status = SEEK_STAT | WRERR_STAT; in ahci_reset_port()
679 ide_state->error = 1; in ahci_reset_port()
702 AHCIPortRegs *pr = &ad->port_regs; in ahci_map_fis_address()
703 map_page(ad->hba->as, &ad->res_fis, in ahci_map_fis_address()
704 ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); in ahci_map_fis_address()
705 if (ad->res_fis != NULL) { in ahci_map_fis_address()
706 pr->cmd |= PORT_CMD_FIS_ON; in ahci_map_fis_address()
710 pr->cmd &= ~PORT_CMD_FIS_ON; in ahci_map_fis_address()
716 if (ad->res_fis == NULL) { in ahci_unmap_fis_address()
717 trace_ahci_unmap_fis_address_null(ad->hba, ad->port_no); in ahci_unmap_fis_address()
720 ad->port_regs.cmd &= ~PORT_CMD_FIS_ON; in ahci_unmap_fis_address()
721 dma_memory_unmap(ad->hba->as, ad->res_fis, 256, in ahci_unmap_fis_address()
723 ad->res_fis = NULL; in ahci_unmap_fis_address()
728 AHCIPortRegs *pr = &ad->port_regs; in ahci_map_clb_address()
729 ad->cur_cmd = NULL; in ahci_map_clb_address()
730 map_page(ad->hba->as, &ad->lst, in ahci_map_clb_address()
731 ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024); in ahci_map_clb_address()
732 if (ad->lst != NULL) { in ahci_map_clb_address()
733 pr->cmd |= PORT_CMD_LIST_ON; in ahci_map_clb_address()
737 pr->cmd &= ~PORT_CMD_LIST_ON; in ahci_map_clb_address()
743 if (ad->lst == NULL) { in ahci_unmap_clb_address()
744 trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no); in ahci_unmap_clb_address()
747 ad->port_regs.cmd &= ~PORT_CMD_LIST_ON; in ahci_unmap_clb_address()
748 dma_memory_unmap(ad->hba->as, ad->lst, 1024, in ahci_unmap_clb_address()
750 ad->lst = NULL; in ahci_unmap_clb_address()
755 AHCIDevice *ad = ncq_tfs->drive; in ahci_write_fis_sdb()
756 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_sdb()
760 if (!ad->res_fis || in ahci_write_fis_sdb()
761 !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_sdb()
765 sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS]; in ahci_write_fis_sdb()
766 ide_state = &ad->port.ifs[0]; in ahci_write_fis_sdb()
768 sdb_fis->type = SATA_FIS_TYPE_SDB; in ahci_write_fis_sdb()
770 sdb_fis->flags = 0x40; /* Interrupt bit, always 1 for NCQ */ in ahci_write_fis_sdb()
771 sdb_fis->status = ide_state->status & 0x77; in ahci_write_fis_sdb()
772 sdb_fis->error = ide_state->error; in ahci_write_fis_sdb()
774 sdb_fis->payload = cpu_to_le32(ad->finished); in ahci_write_fis_sdb()
777 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_sdb()
778 (ad->port.ifs[0].status & 0x77) | in ahci_write_fis_sdb()
779 (pr->tfdata & 0x88); in ahci_write_fis_sdb()
780 pr->scr_act &= ~ad->finished; in ahci_write_fis_sdb()
781 ad->finished = 0; in ahci_write_fis_sdb()
788 if (sdb_fis->status & ERR_STAT) { in ahci_write_fis_sdb()
790 } else if (sdb_fis->flags & 0x40) { in ahci_write_fis_sdb()
797 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_pio()
799 IDEState *s = &ad->port.ifs[0]; in ahci_write_fis_pio()
801 if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_pio()
805 pio_fis = &ad->res_fis[RES_FIS_PSFIS]; in ahci_write_fis_pio()
809 pio_fis[2] = s->status; in ahci_write_fis_pio()
810 pio_fis[3] = s->error; in ahci_write_fis_pio()
812 pio_fis[4] = s->sector; in ahci_write_fis_pio()
813 pio_fis[5] = s->lcyl; in ahci_write_fis_pio()
814 pio_fis[6] = s->hcyl; in ahci_write_fis_pio()
815 pio_fis[7] = s->select; in ahci_write_fis_pio()
816 pio_fis[8] = s->hob_sector; in ahci_write_fis_pio()
817 pio_fis[9] = s->hob_lcyl; in ahci_write_fis_pio()
818 pio_fis[10] = s->hob_hcyl; in ahci_write_fis_pio()
820 pio_fis[12] = s->nsector & 0xFF; in ahci_write_fis_pio()
821 pio_fis[13] = (s->nsector >> 8) & 0xFF; in ahci_write_fis_pio()
823 pio_fis[15] = s->status; in ahci_write_fis_pio()
830 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_pio()
831 ad->port.ifs[0].status; in ahci_write_fis_pio()
834 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES); in ahci_write_fis_pio()
840 AHCIPortRegs *pr = &ad->port_regs; in ahci_write_fis_d2h()
843 IDEState *s = &ad->port.ifs[0]; in ahci_write_fis_d2h()
845 if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { in ahci_write_fis_d2h()
849 d2h_fis = &ad->res_fis[RES_FIS_RFIS]; in ahci_write_fis_d2h()
853 d2h_fis[2] = s->status; in ahci_write_fis_d2h()
854 d2h_fis[3] = s->error; in ahci_write_fis_d2h()
856 d2h_fis[4] = s->sector; in ahci_write_fis_d2h()
857 d2h_fis[5] = s->lcyl; in ahci_write_fis_d2h()
858 d2h_fis[6] = s->hcyl; in ahci_write_fis_d2h()
859 d2h_fis[7] = s->select; in ahci_write_fis_d2h()
860 d2h_fis[8] = s->hob_sector; in ahci_write_fis_d2h()
861 d2h_fis[9] = s->hob_lcyl; in ahci_write_fis_d2h()
862 d2h_fis[10] = s->hob_hcyl; in ahci_write_fis_d2h()
864 d2h_fis[12] = s->nsector & 0xFF; in ahci_write_fis_d2h()
865 d2h_fis[13] = (s->nsector >> 8) & 0xFF; in ahci_write_fis_d2h()
871 pr->tfdata = (ad->port.ifs[0].error << 8) | in ahci_write_fis_d2h()
872 ad->port.ifs[0].status; in ahci_write_fis_d2h()
876 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES); in ahci_write_fis_d2h()
878 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS); in ahci_write_fis_d2h()
886 /* flags_size is zero-based */ in prdt_tbl_entry_size()
887 return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1; in prdt_tbl_entry_size()
891 * Fetch entries in a guest-provided PRDT and convert it into a QEMU SGlist.
899 * up to 32MiB as of ATA8-ACS3 rev 1b, assuming a 512 byte sector size. We stop
906 uint16_t opts = le16_to_cpu(cmd->opts); in ahci_populate_sglist()
907 uint16_t prdtl = le16_to_cpu(cmd->prdtl); in ahci_populate_sglist()
908 uint64_t cfis_addr = le64_to_cpu(cmd->tbl_addr); in ahci_populate_sglist()
916 int off_idx = -1; in ahci_populate_sglist()
917 int64_t off_pos = -1; in ahci_populate_sglist()
918 IDEBus *bus = &ad->port; in ahci_populate_sglist()
921 trace_ahci_populate_sglist(ad->hba, ad->port_no); in ahci_populate_sglist()
924 trace_ahci_populate_sglist_no_prdtl(ad->hba, ad->port_no, opts); in ahci_populate_sglist()
925 return -1; in ahci_populate_sglist()
929 if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len, in ahci_populate_sglist()
932 trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no); in ahci_populate_sglist()
933 return -1; in ahci_populate_sglist()
937 trace_ahci_populate_sglist_short_map(ad->hba, ad->port_no); in ahci_populate_sglist()
938 r = -1; in ahci_populate_sglist()
952 off_pos = offset - sum; in ahci_populate_sglist()
957 if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) { in ahci_populate_sglist()
958 trace_ahci_populate_sglist_bad_offset(ad->hba, ad->port_no, in ahci_populate_sglist()
960 r = -1; in ahci_populate_sglist()
964 qemu_sglist_init(sglist, qbus->parent, (prdtl - off_idx), in ahci_populate_sglist()
965 ad->hba->as); in ahci_populate_sglist()
967 MIN(prdt_tbl_entry_size(&tbl[off_idx]) - off_pos, in ahci_populate_sglist()
970 for (i = off_idx + 1; i < prdtl && sglist->size < limit; i++) { in ahci_populate_sglist()
973 limit - sglist->size)); in ahci_populate_sglist()
978 dma_memory_unmap(ad->hba->as, prdt, prdt_len, in ahci_populate_sglist()
985 IDEState *ide_state = &ncq_tfs->drive->port.ifs[0]; in ncq_err()
987 ide_state->error = ABRT_ERR; in ncq_err()
988 ide_state->status = READY_STAT | ERR_STAT; in ncq_err()
989 qemu_sglist_destroy(&ncq_tfs->sglist); in ncq_err()
990 ncq_tfs->used = 0; in ncq_err()
998 if (ncq_tfs->used) { in ncq_finish()
999 ncq_tfs->drive->finished |= (1 << ncq_tfs->tag); in ncq_finish()
1002 ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs); in ncq_finish()
1004 trace_ncq_finish(ncq_tfs->drive->hba, ncq_tfs->drive->port_no, in ncq_finish()
1005 ncq_tfs->tag); in ncq_finish()
1007 block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk), in ncq_finish()
1008 &ncq_tfs->acct); in ncq_finish()
1009 qemu_sglist_destroy(&ncq_tfs->sglist); in ncq_finish()
1010 ncq_tfs->used = 0; in ncq_finish()
1016 IDEState *ide_state = &ncq_tfs->drive->port.ifs[0]; in ncq_cb()
1018 ncq_tfs->aiocb = NULL; in ncq_cb()
1021 bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED; in ncq_cb()
1022 BlockErrorAction action = blk_get_error_action(ide_state->blk, in ncq_cb()
1023 is_read, -ret); in ncq_cb()
1025 ncq_tfs->halt = true; in ncq_cb()
1026 ide_state->bus->error_status = IDE_RETRY_HBA; in ncq_cb()
1030 blk_error_action(ide_state->blk, action, is_read, -ret); in ncq_cb()
1032 ide_state->status = READY_STAT | SEEK_STAT; in ncq_cb()
1035 if (!ncq_tfs->halt) { in ncq_cb()
1057 AHCIDevice *ad = ncq_tfs->drive; in execute_ncq_command()
1058 IDEState *ide_state = &ad->port.ifs[0]; in execute_ncq_command()
1059 int port = ad->port_no; in execute_ncq_command()
1061 g_assert(is_ncq(ncq_tfs->cmd)); in execute_ncq_command()
1062 ncq_tfs->halt = false; in execute_ncq_command()
1064 switch (ncq_tfs->cmd) { in execute_ncq_command()
1066 trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag, in execute_ncq_command()
1067 ncq_tfs->sector_count, ncq_tfs->lba); in execute_ncq_command()
1068 dma_acct_start(ide_state->blk, &ncq_tfs->acct, in execute_ncq_command()
1069 &ncq_tfs->sglist, BLOCK_ACCT_READ); in execute_ncq_command()
1070 ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist, in execute_ncq_command()
1071 ncq_tfs->lba << BDRV_SECTOR_BITS, in execute_ncq_command()
1076 trace_execute_ncq_command_write(ad->hba, port, ncq_tfs->tag, in execute_ncq_command()
1077 ncq_tfs->sector_count, ncq_tfs->lba); in execute_ncq_command()
1078 dma_acct_start(ide_state->blk, &ncq_tfs->acct, in execute_ncq_command()
1079 &ncq_tfs->sglist, BLOCK_ACCT_WRITE); in execute_ncq_command()
1080 ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist, in execute_ncq_command()
1081 ncq_tfs->lba << BDRV_SECTOR_BITS, in execute_ncq_command()
1086 trace_execute_ncq_command_unsup(ad->hba, port, in execute_ncq_command()
1087 ncq_tfs->tag, ncq_tfs->cmd); in execute_ncq_command()
1096 AHCIDevice *ad = &s->dev[port]; in process_ncq_command()
1098 uint8_t tag = ncq_fis->tag >> 3; in process_ncq_command()
1099 NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag]; in process_ncq_command()
1102 g_assert(is_ncq(ncq_fis->command)); in process_ncq_command()
1103 if (ncq_tfs->used) { in process_ncq_command()
1104 /* error - already in use */ in process_ncq_command()
1128 ncq_tfs->used = 1; in process_ncq_command()
1129 ncq_tfs->drive = ad; in process_ncq_command()
1130 ncq_tfs->slot = slot; in process_ncq_command()
1131 ncq_tfs->cmdh = &((AHCICmdHdr *)ad->lst)[slot]; in process_ncq_command()
1132 ncq_tfs->cmd = ncq_fis->command; in process_ncq_command()
1133 ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) | in process_ncq_command()
1134 ((uint64_t)ncq_fis->lba4 << 32) | in process_ncq_command()
1135 ((uint64_t)ncq_fis->lba3 << 24) | in process_ncq_command()
1136 ((uint64_t)ncq_fis->lba2 << 16) | in process_ncq_command()
1137 ((uint64_t)ncq_fis->lba1 << 8) | in process_ncq_command()
1138 (uint64_t)ncq_fis->lba0; in process_ncq_command()
1139 ncq_tfs->tag = tag; in process_ncq_command()
1141 /* Sanity-check the NCQ packet */ in process_ncq_command()
1146 if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) { in process_ncq_command()
1149 if (ncq_fis->prio || ncq_fis->icc) { in process_ncq_command()
1152 if (ncq_fis->fua & NCQ_FIS_FUA_MASK) { in process_ncq_command()
1155 if (ncq_fis->tag & NCQ_FIS_RARC_MASK) { in process_ncq_command()
1159 ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) | in process_ncq_command()
1160 ncq_fis->sector_count_low); in process_ncq_command()
1161 if (!ncq_tfs->sector_count) { in process_ncq_command()
1162 ncq_tfs->sector_count = 0x10000; in process_ncq_command()
1164 size = ncq_tfs->sector_count * BDRV_SECTOR_SIZE; in process_ncq_command()
1165 ahci_populate_sglist(ad, &ncq_tfs->sglist, ncq_tfs->cmdh, size, 0); in process_ncq_command()
1167 if (ncq_tfs->sglist.size < size) { in process_ncq_command()
1170 ncq_tfs->sglist.size, size); in process_ncq_command()
1172 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS); in process_ncq_command()
1174 } else if (ncq_tfs->sglist.size != size) { in process_ncq_command()
1176 ncq_tfs->sglist.size, size); in process_ncq_command()
1180 ncq_fis->command, in process_ncq_command()
1181 ncq_tfs->lba, in process_ncq_command()
1182 ncq_tfs->lba + ncq_tfs->sector_count - 1); in process_ncq_command()
1188 if (port >= s->ports || slot >= AHCI_MAX_CMDS) { in get_cmd_header()
1192 return s->dev[port].lst ? &((AHCICmdHdr *)s->dev[port].lst)[slot] : NULL; in get_cmd_header()
1198 IDEState *ide_state = &s->dev[port].port.ifs[0]; in handle_reg_h2d_fis()
1200 AHCIDevice *ad = &s->dev[port]; in handle_reg_h2d_fis()
1201 uint16_t opts = le16_to_cpu(cmd->opts); in handle_reg_h2d_fis()
1216 switch (s->dev[port].port_state) { in handle_reg_h2d_fis()
1219 s->dev[port].port_state = STATE_RESET; in handle_reg_h2d_fis()
1259 * SATA 1.0 describes how to decode LBA28 and CHS FIS packets. in handle_reg_h2d_fis()
1262 * ATA4 describes sector number for LBA28/CHS commands. in handle_reg_h2d_fis()
1264 * ATA8 deprecates CHS fully, describing only LBA28/48. in handle_reg_h2d_fis()
1268 ide_state->feature = cmd_fis[3]; in handle_reg_h2d_fis()
1269 ide_state->sector = cmd_fis[4]; /* LBA 7:0 */ in handle_reg_h2d_fis()
1270 ide_state->lcyl = cmd_fis[5]; /* LBA 15:8 */ in handle_reg_h2d_fis()
1271 ide_state->hcyl = cmd_fis[6]; /* LBA 23:16 */ in handle_reg_h2d_fis()
1272 ide_state->select = cmd_fis[7]; /* LBA 27:24 (LBA28) */ in handle_reg_h2d_fis()
1273 ide_state->hob_sector = cmd_fis[8]; /* LBA 31:24 */ in handle_reg_h2d_fis()
1274 ide_state->hob_lcyl = cmd_fis[9]; /* LBA 39:32 */ in handle_reg_h2d_fis()
1275 ide_state->hob_hcyl = cmd_fis[10]; /* LBA 47:40 */ in handle_reg_h2d_fis()
1276 ide_state->hob_feature = cmd_fis[11]; in handle_reg_h2d_fis()
1277 ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]); in handle_reg_h2d_fis()
1282 * table to ide_state->io_buffer */ in handle_reg_h2d_fis()
1284 memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10); in handle_reg_h2d_fis()
1286 char *pretty_fis = ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10); in handle_reg_h2d_fis()
1292 ide_state->error = 0; in handle_reg_h2d_fis()
1293 s->dev[port].done_first_drq = false; in handle_reg_h2d_fis()
1295 cmd->status = 0; in handle_reg_h2d_fis()
1298 * A non-NCQ command clears the bit in PxCI after the command has COMPLETED in handle_reg_h2d_fis()
1301 * For non-NCQ commands, PxCI will always be cleared by ahci_cmd_done(). in handle_reg_h2d_fis()
1303 ad->busy_slot = slot; in handle_reg_h2d_fis()
1306 ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]); in handle_reg_h2d_fis()
1317 if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) { in handle_cmd()
1323 if (!s->dev[port].lst) { in handle_cmd()
1329 s->dev[port].cur_cmd = cmd; in handle_cmd()
1332 ide_state = &s->dev[port].port.ifs[0]; in handle_cmd()
1333 if (!ide_state->blk) { in handle_cmd()
1338 tbl_addr = le64_to_cpu(cmd->tbl_addr); in handle_cmd()
1340 cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len, in handle_cmd()
1346 ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS); in handle_cmd()
1366 dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE, in handle_cmd()
1374 IDEState *s = &ad->port.ifs[0]; in ahci_pio_transfer()
1375 uint32_t size = (uint32_t)(s->data_end - s->data_ptr); in ahci_pio_transfer()
1376 /* write == ram -> device */ in ahci_pio_transfer()
1377 uint16_t opts = le16_to_cpu(ad->cur_cmd->opts); in ahci_pio_transfer()
1386 * The device only sets the 'I' bit in the PIO Setup FIS for device->host in ahci_pio_transfer()
1387 * requests (see "DPIOI1" in the SATA spec), or for host->device DRQs after in ahci_pio_transfer()
1393 pio_fis_i = ad->done_first_drq || (!is_atapi && !is_write); in ahci_pio_transfer()
1396 if (is_atapi && !ad->done_first_drq) { in ahci_pio_transfer()
1405 trace_ahci_pio_transfer(ad->hba, ad->port_no, is_write ? "writ" : "read", in ahci_pio_transfer()
1413 dma_buf_write(s->data_ptr, size, NULL, &s->sg, attrs); in ahci_pio_transfer()
1415 dma_buf_read(s->data_ptr, size, NULL, &s->sg, attrs); in ahci_pio_transfer()
1424 s->data_ptr = s->data_end; in ahci_pio_transfer()
1426 ad->done_first_drq = true; in ahci_pio_transfer()
1428 ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS); in ahci_pio_transfer()
1436 trace_ahci_start_dma(ad->hba, ad->port_no); in ahci_start_dma()
1437 s->io_buffer_offset = 0; in ahci_start_dma()
1443 /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset. */ in ahci_restart_dma()
1456 NCQTransferState *ncq_tfs = &ad->ncq_tfs[i]; in ahci_restart()
1457 if (ncq_tfs->halt) { in ahci_restart()
1470 IDEState *s = &ad->port.ifs[0]; in ahci_dma_prepare_buf()
1472 if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, in ahci_dma_prepare_buf()
1473 limit, s->io_buffer_offset) == -1) { in ahci_dma_prepare_buf()
1474 trace_ahci_dma_prepare_buf_fail(ad->hba, ad->port_no); in ahci_dma_prepare_buf()
1475 return -1; in ahci_dma_prepare_buf()
1477 s->io_buffer_size = s->sg.size; in ahci_dma_prepare_buf()
1479 trace_ahci_dma_prepare_buf(ad->hba, ad->port_no, limit, s->io_buffer_size); in ahci_dma_prepare_buf()
1480 return s->io_buffer_size; in ahci_dma_prepare_buf()
1484 * Updates the command header with a bytes-read value.
1492 tx_bytes += le32_to_cpu(ad->cur_cmd->status); in ahci_commit_buf()
1493 ad->cur_cmd->status = cpu_to_le32(tx_bytes); in ahci_commit_buf()
1499 IDEState *s = &ad->port.ifs[0]; in ahci_dma_rw_buf()
1500 uint8_t *p = s->io_buffer + s->io_buffer_index; in ahci_dma_rw_buf()
1501 int l = s->io_buffer_size - s->io_buffer_index; in ahci_dma_rw_buf()
1503 if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, l, s->io_buffer_offset)) { in ahci_dma_rw_buf()
1508 dma_buf_read(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED); in ahci_dma_rw_buf()
1510 dma_buf_write(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED); in ahci_dma_rw_buf()
1515 s->io_buffer_index += l; in ahci_dma_rw_buf()
1517 trace_ahci_dma_rw_buf(ad->hba, ad->port_no, l); in ahci_dma_rw_buf()
1523 IDEState *ide_state = &ad->port.ifs[0]; in ahci_clear_cmd_issue()
1525 if (!(ide_state->status & ERR_STAT) && in ahci_clear_cmd_issue()
1526 !(ide_state->status & (BUSY_STAT | DRQ_STAT))) { in ahci_clear_cmd_issue()
1527 ad->port_regs.cmd_issue &= ~(1 << slot); in ahci_clear_cmd_issue()
1531 /* Non-NCQ command is done - This function is never called for NCQ commands. */
1535 IDEState *ide_state = &ad->port.ifs[0]; in ahci_cmd_done()
1537 trace_ahci_cmd_done(ad->hba, ad->port_no); in ahci_cmd_done()
1540 if (ad->busy_slot != -1) { in ahci_cmd_done()
1541 ahci_clear_cmd_issue(ad, ad->busy_slot); in ahci_cmd_done()
1542 ad->busy_slot = -1; in ahci_cmd_done()
1546 * In reality, for non-NCQ commands, PxCI is cleared after receiving a D2H in ahci_cmd_done()
1552 if (!(ide_state->status & ERR_STAT) && in ahci_cmd_done()
1553 ad->port_regs.cmd_issue && !ad->check_bh) { in ahci_cmd_done()
1554 ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad, in ahci_cmd_done()
1555 &ad->mem_reentrancy_guard); in ahci_cmd_done()
1556 qemu_bh_schedule(ad->check_bh); in ahci_cmd_done()
1579 memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s, in ahci_init()
1581 memory_region_init_io(&s->idp, OBJECT(qdev), &ahci_idp_ops, s, in ahci_init()
1582 "ahci-idp", 32); in ahci_init()
1590 s->as = as; in ahci_realize()
1591 assert(s->ports > 0); in ahci_realize()
1592 s->dev = g_new0(AHCIDevice, s->ports); in ahci_realize()
1594 irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports); in ahci_realize()
1595 for (i = 0; i < s->ports; i++) { in ahci_realize()
1596 AHCIDevice *ad = &s->dev[i]; in ahci_realize()
1598 ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1); in ahci_realize()
1599 ide_bus_init_output_irq(&ad->port, irqs[i]); in ahci_realize()
1601 ad->hba = s; in ahci_realize()
1602 ad->port_no = i; in ahci_realize()
1603 ad->port.dma = &ad->dma; in ahci_realize()
1604 ad->port.dma->ops = &ahci_dma_ops; in ahci_realize()
1605 ide_bus_register_restart_cb(&ad->port); in ahci_realize()
1614 for (i = 0; i < s->ports; i++) { in ahci_uninit()
1615 AHCIDevice *ad = &s->dev[i]; in ahci_uninit()
1618 ide_exit(&ad->port.ifs[j]); in ahci_uninit()
1620 object_unparent(OBJECT(&ad->port)); in ahci_uninit()
1623 g_free(s->dev); in ahci_uninit()
1633 s->control_regs.irqstatus = 0; in ahci_reset()
1636 * CAP.SAM bit. If CAP.SAM is '0', then GHC.AE shall be read-write and in ahci_reset()
1638 * read-only and shall have a reset value of '1'. in ahci_reset()
1642 s->control_regs.ghc = HOST_CTL_AHCI_EN; in ahci_reset()
1644 for (i = 0; i < s->ports; i++) { in ahci_reset()
1645 pr = &s->dev[i].port_regs; in ahci_reset()
1646 pr->irq_stat = 0; in ahci_reset()
1647 pr->irq_mask = 0; in ahci_reset()
1648 pr->scr_ctl = 0; in ahci_reset()
1649 pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON; in ahci_reset()
1708 for (i = 0; i < s->ports; i++) { in ahci_state_post_load()
1709 ad = &s->dev[i]; in ahci_state_post_load()
1710 pr = &ad->port_regs; in ahci_state_post_load()
1712 if (!(pr->cmd & PORT_CMD_START) && (pr->cmd & PORT_CMD_LIST_ON)) { in ahci_state_post_load()
1715 return -1; in ahci_state_post_load()
1717 if (!(pr->cmd & PORT_CMD_FIS_RX) && (pr->cmd & PORT_CMD_FIS_ON)) { in ahci_state_post_load()
1720 return -1; in ahci_state_post_load()
1725 pr->cmd &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON); in ahci_state_post_load()
1727 return -1; in ahci_state_post_load()
1731 ncq_tfs = &ad->ncq_tfs[j]; in ahci_state_post_load()
1732 ncq_tfs->drive = ad; in ahci_state_post_load()
1734 if (ncq_tfs->used != ncq_tfs->halt) { in ahci_state_post_load()
1735 return -1; in ahci_state_post_load()
1737 if (!ncq_tfs->halt) { in ahci_state_post_load()
1740 if (!is_ncq(ncq_tfs->cmd)) { in ahci_state_post_load()
1741 return -1; in ahci_state_post_load()
1743 if (ncq_tfs->slot != ncq_tfs->tag) { in ahci_state_post_load()
1744 return -1; in ahci_state_post_load()
1746 /* If ncq_tfs->halt is justly set, the engine should be engaged, in ahci_state_post_load()
1748 ncq_tfs->cmdh = get_cmd_header(s, i, ncq_tfs->slot); in ahci_state_post_load()
1749 if (!ncq_tfs->cmdh) { in ahci_state_post_load()
1750 return -1; in ahci_state_post_load()
1752 ahci_populate_sglist(ncq_tfs->drive, &ncq_tfs->sglist, in ahci_state_post_load()
1753 ncq_tfs->cmdh, in ahci_state_post_load()
1754 ncq_tfs->sector_count * BDRV_SECTOR_SIZE, in ahci_state_post_load()
1756 if (ncq_tfs->sector_count != ncq_tfs->sglist.size >> 9) { in ahci_state_post_load()
1757 return -1; in ahci_state_post_load()
1763 * If an error is present, ad->busy_slot will be valid and not -1. in ahci_state_post_load()
1764 * In this case, an operation is waiting to resume and will re-check in ahci_state_post_load()
1767 * In the case where no error was present, busy_slot will be -1, in ahci_state_post_load()
1770 if (ad->busy_slot == -1) { in ahci_state_post_load()
1775 if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) { in ahci_state_post_load()
1776 return -1; in ahci_state_post_load()
1778 ad->cur_cmd = get_cmd_header(s, i, ad->busy_slot); in ahci_state_post_load()
1807 for (i = 0; i < ahci->ports; i++) { in ahci_ide_create_devs()
1811 ide_bus_create_drive(&ahci->dev[i].port, 0, hd[i]); in ahci_ide_create_devs()