Lines Matching refs:cmd

37     uint8_t  cmd;        /* Command Code */  member
52 { .cmd = CMD_READ_PIO, .data = true, .pio = true,
54 { .cmd = CMD_WRITE_PIO, .data = true, .pio = true,
56 { .cmd = CMD_READ_PIO_EXT, .data = true, .pio = true,
58 { .cmd = CMD_WRITE_PIO_EXT, .data = true, .pio = true,
60 { .cmd = CMD_READ_DMA, .data = true, .dma = true,
62 { .cmd = CMD_WRITE_DMA, .data = true, .dma = true,
64 { .cmd = CMD_READ_DMA_EXT, .data = true, .dma = true,
66 { .cmd = CMD_WRITE_DMA_EXT, .data = true, .dma = true,
68 { .cmd = CMD_IDENTIFY, .data = true, .pio = true,
70 { .cmd = READ_FPDMA_QUEUED, .data = true, .dma = true,
72 { .cmd = WRITE_FPDMA_QUEUED, .data = true, .dma = true,
74 { .cmd = CMD_READ_MAX, .lba28 = true },
75 { .cmd = CMD_READ_MAX_EXT, .lba48 = true },
76 { .cmd = CMD_FLUSH_CACHE, .data = false },
77 { .cmd = CMD_PACKET, .data = true, .size = 16,
79 { .cmd = CMD_PACKET_ID, .data = true, .pio = true,
407 void ahci_port_check_error(AHCIQState *ahci, AHCICommand *cmd) in ahci_port_check_error() argument
409 uint8_t port = cmd->port; in ahci_port_check_error()
413 if (cmd->errors) { in ahci_port_check_error()
419 reg &= ~cmd->interrupts; in ahci_port_check_error()
430 if (cmd->errors) { in ahci_port_check_error()
455 if (!cmd->errors) { in ahci_port_check_error()
460 ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR & (~cmd->errors << 8)); in ahci_port_check_error()
461 ASSERT_BIT_SET(reg, AHCI_PX_TFD_ERR & (cmd->errors << 8)); in ahci_port_check_error()
464 void ahci_port_check_interrupts(AHCIQState *ahci, AHCICommand *cmd) in ahci_port_check_interrupts() argument
466 uint8_t port = cmd->port; in ahci_port_check_interrupts()
472 if (cmd->errors) { in ahci_port_check_interrupts()
478 ASSERT_BIT_SET(reg, cmd->interrupts); in ahci_port_check_interrupts()
481 ahci_px_wreg(ahci, port, AHCI_PX_IS, cmd->interrupts); in ahci_port_check_interrupts()
485 void ahci_port_check_nonbusy(AHCIQState *ahci, AHCICommand *cmd) in ahci_port_check_nonbusy() argument
487 uint8_t slot = cmd->slot; in ahci_port_check_nonbusy()
488 uint8_t port = cmd->port; in ahci_port_check_nonbusy()
495 if (cmd->props->ncq && cmd->errors) { in ahci_port_check_nonbusy()
506 if (!cmd->props->ncq && cmd->errors) { in ahci_port_check_nonbusy()
508 } else if (!cmd->errors) { in ahci_port_check_nonbusy()
533 void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd) in ahci_port_check_pio_sanity() argument
536 uint8_t port = cmd->port; in ahci_port_check_pio_sanity()
549 if (cmd->props->atapi && (cmd->xbytes == 0 || cmd->props->dma)) { in ahci_port_check_pio_sanity()
556 size_t pio_len = ((cmd->xbytes % cmd->sector_size) ? in ahci_port_check_pio_sanity()
557 (cmd->xbytes % cmd->sector_size) : cmd->sector_size); in ahci_port_check_pio_sanity()
563 void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd) in ahci_port_check_cmd_sanity() argument
567 ahci_get_command_header(ahci, cmd->port, cmd->slot, &cmdh); in ahci_port_check_cmd_sanity()
569 if (!cmd->props->ncq) { in ahci_port_check_cmd_sanity()
570 g_assert_cmphex(cmd->xbytes, ==, cmdh.prdbc); in ahci_port_check_cmd_sanity()
576 uint8_t slot, AHCICommandHeader *cmd) in ahci_get_command_header() argument
580 qtest_memread(ahci->parent->qts, ba, cmd, sizeof(AHCICommandHeader)); in ahci_get_command_header()
582 cmd->flags = le16_to_cpu(cmd->flags); in ahci_get_command_header()
583 cmd->prdtl = le16_to_cpu(cmd->prdtl); in ahci_get_command_header()
584 cmd->prdbc = le32_to_cpu(cmd->prdbc); in ahci_get_command_header()
585 cmd->ctba = le64_to_cpu(cmd->ctba); in ahci_get_command_header()
590 uint8_t slot, AHCICommandHeader *cmd) in ahci_set_command_header() argument
596 tmp.flags = cpu_to_le16(cmd->flags); in ahci_set_command_header()
597 tmp.prdtl = cpu_to_le16(cmd->prdtl); in ahci_set_command_header()
598 tmp.prdbc = cpu_to_le32(cmd->prdbc); in ahci_set_command_header()
599 tmp.ctba = cpu_to_le64(cmd->ctba); in ahci_set_command_header()
606 AHCICommandHeader cmd; in ahci_destroy_command() local
609 ahci_get_command_header(ahci, port, slot, &cmd); in ahci_destroy_command()
610 if (cmd.ctba == 0) { in ahci_destroy_command()
616 ahci_free(ahci, cmd.ctba); in ahci_destroy_command()
620 memset(&cmd, 0x00, sizeof(cmd)); in ahci_destroy_command()
621 ahci_set_command_header(ahci, port, slot, &cmd); in ahci_destroy_command()
626 void ahci_write_fis(AHCIQState *ahci, AHCICommand *cmd) in ahci_write_fis() argument
628 RegH2DFIS tmp = cmd->fis; in ahci_write_fis()
629 uint64_t addr = cmd->header.ctba; in ahci_write_fis()
635 if (!cmd->props->ncq) { in ahci_write_fis()
689 AHCICommand *cmd; in ahci_exec() local
709 cmd = ahci_atapi_command_create(op, bcl, opts->atapi_dma); in ahci_exec()
711 cmd = ahci_command_create(op); in ahci_exec()
713 ahci_command_adjust(cmd, opts->lba, opts->buffer, in ahci_exec()
717 rc = opts->pre_cb(ahci, cmd, opts); in ahci_exec()
722 ahci_command_commit(ahci, cmd, port); in ahci_exec()
723 ahci_command_issue_async(ahci, cmd); in ahci_exec()
728 rc = opts->mid_cb(ahci, cmd, opts); in ahci_exec()
737 ahci_command_wait(ahci, cmd); in ahci_exec()
738 ahci_command_verify(ahci, cmd); in ahci_exec()
740 rc = opts->post_cb(ahci, cmd, opts); in ahci_exec()
743 ahci_command_free(cmd); in ahci_exec()
755 AHCICommand *cmd; in ahci_guest_io_halt() local
757 cmd = ahci_command_create(ide_cmd); in ahci_guest_io_halt()
758 ahci_command_adjust(cmd, sector, buffer, bufsize, 0); in ahci_guest_io_halt()
759 ahci_command_commit(ahci, cmd, port); in ahci_guest_io_halt()
760 ahci_command_issue_async(ahci, cmd); in ahci_guest_io_halt()
763 return cmd; in ahci_guest_io_halt()
767 void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd) in ahci_guest_io_resume() argument
772 ahci_command_wait(ahci, cmd); in ahci_guest_io_resume()
773 ahci_command_verify(ahci, cmd); in ahci_guest_io_resume()
774 ahci_command_free(cmd); in ahci_guest_io_resume()
781 AHCICommand *cmd; in ahci_guest_io() local
782 cmd = ahci_command_create(ide_cmd); in ahci_guest_io()
783 ahci_command_set_buffer(cmd, buffer); in ahci_guest_io()
784 ahci_command_set_size(cmd, bufsize); in ahci_guest_io()
786 ahci_command_set_offset(cmd, sector); in ahci_guest_io()
788 ahci_command_commit(ahci, cmd, port); in ahci_guest_io()
789 ahci_command_issue(ahci, cmd); in ahci_guest_io()
790 ahci_command_verify(ahci, cmd); in ahci_guest_io()
791 ahci_command_free(cmd); in ahci_guest_io()
799 if (ahci_command_properties[i].cmd == command_name) { in ahci_command_find()
837 static void command_header_init(AHCICommand *cmd) in command_header_init() argument
839 AHCICommandHeader *hdr = &cmd->header; in command_header_init()
840 AHCICommandProp *props = cmd->props; in command_header_init()
851 hdr->prdtl = size_to_prdtl(cmd->xbytes, cmd->prd_size); in command_header_init()
856 static void command_table_init(AHCICommand *cmd) in command_table_init() argument
858 RegH2DFIS *fis = &(cmd->fis); in command_table_init()
859 uint16_t sect_count = (cmd->xbytes / cmd->sector_size); in command_table_init()
863 fis->command = cmd->name; in command_table_init()
865 if (cmd->props->ncq) { in command_table_init()
879 if (cmd->props->lba28 || cmd->props->lba48) { in command_table_init()
882 fis->count = (cmd->xbytes / cmd->sector_size); in command_table_init()
889 void ahci_command_enable_atapi_dma(AHCICommand *cmd) in ahci_command_enable_atapi_dma() argument
891 RegH2DFIS *fis = &(cmd->fis); in ahci_command_enable_atapi_dma()
892 g_assert(cmd->props->atapi); in ahci_command_enable_atapi_dma()
895 g_assert(cmd->props->pio); in ahci_command_enable_atapi_dma()
896 cmd->props->dma = true; in ahci_command_enable_atapi_dma()
904 AHCICommand *cmd; in ahci_command_create() local
907 cmd = g_new0(AHCICommand, 1); in ahci_command_create()
915 cmd->props = g_memdup2(props, sizeof(AHCICommandProp)); in ahci_command_create()
916 cmd->name = command_name; in ahci_command_create()
917 cmd->xbytes = props->size; in ahci_command_create()
918 cmd->prd_size = 4096; in ahci_command_create()
919 cmd->buffer = 0xabad1dea; in ahci_command_create()
920 cmd->sector_size = props->atapi ? ATAPI_SECTOR_SIZE : AHCI_SECTOR_SIZE; in ahci_command_create()
922 if (!cmd->props->ncq) { in ahci_command_create()
923 cmd->interrupts = AHCI_PX_IS_DHRS; in ahci_command_create()
929 cmd->interrupts |= props->ncq ? AHCI_PX_IS_SDBS : 0; in ahci_command_create()
931 command_header_init(cmd); in ahci_command_create()
932 command_table_init(cmd); in ahci_command_create()
934 return cmd; in ahci_command_create()
939 AHCICommand *cmd = ahci_command_create(CMD_PACKET); in ahci_atapi_command_create() local
940 cmd->atapi_cmd = g_malloc0(16); in ahci_atapi_command_create()
941 cmd->atapi_cmd[0] = scsi_cmd; in ahci_atapi_command_create()
942 stw_le_p(&cmd->fis.lba_lo[1], bcl); in ahci_atapi_command_create()
944 ahci_command_enable_atapi_dma(cmd); in ahci_atapi_command_create()
946 cmd->interrupts |= bcl ? AHCI_PX_IS_PSS : 0; in ahci_atapi_command_create()
948 return cmd; in ahci_atapi_command_create()
954 AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_TEST_UNIT_READY, 0, false); in ahci_atapi_test_ready() local
955 ahci_command_set_size(cmd, 0); in ahci_atapi_test_ready()
957 cmd->interrupts |= AHCI_PX_IS_TFES; in ahci_atapi_test_ready()
958 cmd->errors |= expected_sense << 4; in ahci_atapi_test_ready()
960 ahci_command_commit(ahci, cmd, port); in ahci_atapi_test_ready()
961 ahci_command_issue(ahci, cmd); in ahci_atapi_test_ready()
962 ahci_command_verify(ahci, cmd); in ahci_atapi_test_ready()
963 ahci_command_free(cmd); in ahci_atapi_test_ready()
966 static int copy_buffer(AHCIQState *ahci, AHCICommand *cmd, in copy_buffer() argument
996 AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_START_STOP_UNIT, 0, false); in ahci_atapi_eject() local
997 ahci_command_set_size(cmd, 0); in ahci_atapi_eject()
999 cmd->atapi_cmd[4] = 0x02; /* loej = true */ in ahci_atapi_eject()
1000 ahci_command_commit(ahci, cmd, port); in ahci_atapi_eject()
1001 ahci_command_issue(ahci, cmd); in ahci_atapi_eject()
1002 ahci_command_verify(ahci, cmd); in ahci_atapi_eject()
1003 ahci_command_free(cmd); in ahci_atapi_eject()
1008 AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_START_STOP_UNIT, 0, false); in ahci_atapi_load() local
1009 ahci_command_set_size(cmd, 0); in ahci_atapi_load()
1011 cmd->atapi_cmd[4] = 0x03; /* loej,start = true */ in ahci_atapi_load()
1012 ahci_command_commit(ahci, cmd, port); in ahci_atapi_load()
1013 ahci_command_issue(ahci, cmd); in ahci_atapi_load()
1014 ahci_command_verify(ahci, cmd); in ahci_atapi_load()
1015 ahci_command_free(cmd); in ahci_atapi_load()
1018 void ahci_command_free(AHCICommand *cmd) in ahci_command_free() argument
1020 g_free(cmd->atapi_cmd); in ahci_command_free()
1021 g_free(cmd->props); in ahci_command_free()
1022 g_free(cmd); in ahci_command_free()
1025 void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags) in ahci_command_set_flags() argument
1027 cmd->header.flags |= cmdh_flags; in ahci_command_set_flags()
1030 void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags) in ahci_command_clr_flags() argument
1032 cmd->header.flags &= ~cmdh_flags; in ahci_command_clr_flags()
1035 static void ahci_atapi_command_set_offset(AHCICommand *cmd, uint64_t lba) in ahci_atapi_command_set_offset() argument
1037 unsigned char *cbd = cmd->atapi_cmd; in ahci_atapi_command_set_offset()
1062 void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect) in ahci_command_set_offset() argument
1064 RegH2DFIS *fis = &(cmd->fis); in ahci_command_set_offset()
1066 if (cmd->props->atapi) { in ahci_command_set_offset()
1067 ahci_atapi_command_set_offset(cmd, lba_sect); in ahci_command_set_offset()
1069 } else if (!cmd->props->data && !lba_sect) { in ahci_command_set_offset()
1072 } else if (cmd->props->lba28) { in ahci_command_set_offset()
1074 } else if (cmd->props->lba48 || cmd->props->ncq) { in ahci_command_set_offset()
1085 if (cmd->props->lba28) { in ahci_command_set_offset()
1093 void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer) in ahci_command_set_buffer() argument
1095 cmd->buffer = buffer; in ahci_command_set_buffer()
1098 static void ahci_atapi_set_size(AHCICommand *cmd, uint64_t xbytes) in ahci_atapi_set_size() argument
1100 unsigned char *cbd = cmd->atapi_cmd; in ahci_atapi_set_size()
1136 void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes, in ahci_command_set_sizes() argument
1145 cmd->prd_size = prd_size; in ahci_command_set_sizes()
1147 cmd->xbytes = xbytes; in ahci_command_set_sizes()
1148 sect_count = (cmd->xbytes / cmd->sector_size); in ahci_command_set_sizes()
1150 if (cmd->props->ncq) { in ahci_command_set_sizes()
1151 NCQFIS *nfis = (NCQFIS *)&(cmd->fis); in ahci_command_set_sizes()
1154 } else if (cmd->props->atapi) { in ahci_command_set_sizes()
1155 ahci_atapi_set_size(cmd, xbytes); in ahci_command_set_sizes()
1160 if (cmd->props->pio && sect_count > (cmd->props->read ? 0 : 1)) { in ahci_command_set_sizes()
1161 cmd->interrupts |= AHCI_PX_IS_PSS; in ahci_command_set_sizes()
1163 cmd->fis.count = sect_count; in ahci_command_set_sizes()
1165 cmd->header.prdtl = size_to_prdtl(cmd->xbytes, cmd->prd_size); in ahci_command_set_sizes()
1168 void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes) in ahci_command_set_size() argument
1170 ahci_command_set_sizes(cmd, xbytes, cmd->prd_size); in ahci_command_set_size()
1173 void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size) in ahci_command_set_prd_size() argument
1175 ahci_command_set_sizes(cmd, cmd->xbytes, prd_size); in ahci_command_set_prd_size()
1178 void ahci_command_adjust(AHCICommand *cmd, uint64_t offset, uint64_t buffer, in ahci_command_adjust() argument
1181 ahci_command_set_sizes(cmd, xbytes, prd_size); in ahci_command_adjust()
1182 ahci_command_set_buffer(cmd, buffer); in ahci_command_adjust()
1183 ahci_command_set_offset(cmd, offset); in ahci_command_adjust()
1186 void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port) in ahci_command_commit() argument
1193 cmd->port = port; in ahci_command_commit()
1194 cmd->slot = ahci_pick_cmd(ahci, port); in ahci_command_commit()
1196 if (cmd->props->ncq) { in ahci_command_commit()
1197 NCQFIS *nfis = (NCQFIS *)&cmd->fis; in ahci_command_commit()
1198 nfis->tag = (cmd->slot << 3) & 0xFC; in ahci_command_commit()
1202 prdtl = size_to_prdtl(cmd->xbytes, cmd->prd_size); in ahci_command_commit()
1208 cmd->header.ctba = table_ptr; in ahci_command_commit()
1211 ahci_set_command_header(ahci, port, cmd->slot, &(cmd->header)); in ahci_command_commit()
1213 ahci_write_fis(ahci, cmd); in ahci_command_commit()
1215 if (cmd->props->atapi) { in ahci_command_commit()
1216 qtest_memwrite(ahci->parent->qts, table_ptr + 0x40, cmd->atapi_cmd, 16); in ahci_command_commit()
1220 g_assert_cmphex(prdtl, ==, cmd->header.prdtl); in ahci_command_commit()
1221 remaining = cmd->xbytes; in ahci_command_commit()
1223 prd.dba = cpu_to_le64(cmd->buffer + (cmd->prd_size * i)); in ahci_command_commit()
1225 if (remaining > cmd->prd_size) { in ahci_command_commit()
1227 prd.dbc = cpu_to_le32(cmd->prd_size - 1); in ahci_command_commit()
1228 remaining -= cmd->prd_size; in ahci_command_commit()
1242 ahci->port[port].ctba[cmd->slot] = table_ptr; in ahci_command_commit()
1243 ahci->port[port].prdtl[cmd->slot] = prdtl; in ahci_command_commit()
1246 void ahci_command_issue_async(AHCIQState *ahci, AHCICommand *cmd) in ahci_command_issue_async() argument
1248 if (cmd->props->ncq) { in ahci_command_issue_async()
1249 ahci_px_wreg(ahci, cmd->port, AHCI_PX_SACT, (1 << cmd->slot)); in ahci_command_issue_async()
1252 ahci_px_wreg(ahci, cmd->port, AHCI_PX_CI, (1 << cmd->slot)); in ahci_command_issue_async()
1255 void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd) in ahci_command_wait() argument
1261 #define RSET(REG, MASK) (BITSET(ahci_px_rreg(ahci, cmd->port, (REG)), (MASK))) in ahci_command_wait()
1265 RSET(AHCI_PX_CI, 1 << cmd->slot) || in ahci_command_wait()
1266 (cmd->props->ncq && RSET(AHCI_PX_SACT, 1 << cmd->slot)))) { in ahci_command_wait()
1272 void ahci_command_issue(AHCIQState *ahci, AHCICommand *cmd) in ahci_command_issue() argument
1274 ahci_command_issue_async(ahci, cmd); in ahci_command_issue()
1275 ahci_command_wait(ahci, cmd); in ahci_command_issue()
1278 void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd) in ahci_command_verify() argument
1280 uint8_t slot = cmd->slot; in ahci_command_verify()
1281 uint8_t port = cmd->port; in ahci_command_verify()
1283 ahci_port_check_nonbusy(ahci, cmd); in ahci_command_verify()
1284 ahci_port_check_error(ahci, cmd); in ahci_command_verify()
1285 ahci_port_check_interrupts(ahci, cmd); in ahci_command_verify()
1286 ahci_port_check_cmd_sanity(ahci, cmd); in ahci_command_verify()
1287 if (cmd->interrupts & AHCI_PX_IS_DHRS) { in ahci_command_verify()
1290 if (cmd->props->pio) { in ahci_command_verify()
1291 ahci_port_check_pio_sanity(ahci, cmd); in ahci_command_verify()
1295 uint8_t ahci_command_slot(AHCICommand *cmd) in ahci_command_slot() argument
1297 return cmd->slot; in ahci_command_slot()