Changeset eb3683a in mainline
- Timestamp:
- 2012-07-21T14:11:55Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 76c07e4
- Parents:
- 8486c07
- Location:
- uspace/drv/block/ahci
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/ahci/ahci.c
r8486c07 reb3683a 49 49 #define NAME "ahci" 50 50 51 /** Number of ticks for watchdog timer. */52 #define AHCI_TIMER_TICKS 80000053 54 /** Number of ticks for timer based interrupt. */55 #define AHCI_TIMER_NO_INTR_TICKS 800056 57 51 #define LO(ptr) \ 58 52 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff)) … … 60 54 #define HI(ptr) \ 61 55 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32)) 56 57 /** Interrupt pseudocode for a single port 58 * 59 * The interrupt handling works as follows: 60 * 61 * 1. Port interrupt status register is read 62 * (stored as arg2). 63 * 2. If port interrupt is indicated, then: 64 * 3. Port interrupt status register is cleared. 65 * 4. Global interrupt status register is read 66 * and cleared (any potential interrupts from 67 * other ports are reasserted automatically). 68 * 5. Port number is stored as arg1. 69 * 6. The interrupt is accepted. 70 * 71 */ 72 #define AHCI_PORT_CMDS(port) \ 73 { \ 74 /* Read port interrupt status register */ \ 75 .cmd = CMD_PIO_READ_32, \ 76 .addr = NULL, \ 77 .dstarg = 2 \ 78 }, \ 79 { \ 80 /* Check if port asserted interrupt */ \ 81 .cmd = CMD_PREDICATE, \ 82 .value = 5, \ 83 .srcarg = 2, \ 84 }, \ 85 { \ 86 /* Clear port interrupt status register */ \ 87 .cmd = CMD_PIO_WRITE_A_32, \ 88 .addr = NULL, \ 89 .srcarg = 2 \ 90 }, \ 91 { \ 92 /* Read global interrupt status register */ \ 93 .cmd = CMD_PIO_READ_32, \ 94 .addr = NULL, \ 95 .dstarg = 0 \ 96 }, \ 97 { \ 98 /* Clear global interrupt status register */ \ 99 .cmd = CMD_PIO_WRITE_A_32, \ 100 .addr = NULL, \ 101 .srcarg = 0 \ 102 }, \ 103 { \ 104 /* Indicate port interrupt assertion */ \ 105 .cmd = CMD_LOAD, \ 106 .value = (port), \ 107 .dstarg = 1 \ 108 }, \ 109 { \ 110 /* Accept the interrupt */ \ 111 .cmd = CMD_ACCEPT \ 112 } 62 113 63 114 static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *); … … 243 294 /*----------------------------------------------------------------------------*/ 244 295 245 /** Get and clear AHCI port interrupt state register.296 /** Wait for interrupt event. 246 297 * 247 298 * @param sata SATA device structure. … … 250 301 * 251 302 */ 252 static ahci_port_is_t ahci_get_and_clear_pxis(sata_dev_t *sata) 253 { 254 ahci_port_is_t pxis; 255 256 fibril_mutex_lock(&sata->pxis_lock); 257 258 pxis.u32 = sata->ahci->memregs->ports[sata->port_num].pxis; 259 sata->ahci->memregs->ports[sata->port_num].pxis = pxis.u32; 303 static ahci_port_is_t ahci_wait_event(sata_dev_t *sata) 304 { 305 fibril_mutex_lock(&sata->event_lock); 306 307 while (sata->event_pxis == 0) 308 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 309 310 ahci_port_is_t pxis = sata->event_pxis; 311 sata->event_pxis = 0; 260 312 261 313 if (ahci_port_is_permanent_error(pxis)) 262 314 sata->is_invalid_device = true; 263 315 264 fibril_mutex_unlock(&sata-> pxis_lock);316 fibril_mutex_unlock(&sata->event_lock); 265 317 266 318 return pxis; … … 275 327 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys) 276 328 { 277 /* Clear interrupt state registers */278 ahci_get_and_clear_pxis(sata);279 sata->shadow_pxis.u32 = 0;280 281 329 volatile sata_std_command_frame_t *cmd = 282 330 (sata_std_command_frame_t *) sata->cmd_table; … … 308 356 sata->cmd_header->flags = 309 357 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 310 AHCI_CMDHDR_FLAGS_2DWCMD; 358 AHCI_CMDHDR_FLAGS_2DWCMD; 311 359 sata->cmd_header->bytesprocessed = 0; 312 360 … … 324 372 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys) 325 373 { 326 /* Clear interrupt state registers */ 327 ahci_get_and_clear_pxis(sata); 328 sata->shadow_pxis.u32 = 0; 329 330 volatile sata_std_command_frame_t * cmd = 374 volatile sata_std_command_frame_t *cmd = 331 375 (sata_std_command_frame_t *) sata->cmd_table; 332 376 … … 355 399 356 400 sata->cmd_header->prdtl = 1; 357 sata->cmd_header->flags = 401 sata->cmd_header->flags = 358 402 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 359 403 AHCI_CMDHDR_FLAGS_2DWCMD; … … 382 426 void *phys; 383 427 sata_identify_data_t *idata; 384 dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys, 385 (void **) &idata); 386 bzero(idata, 512); 428 int rc = dmamem_map_anonymous(SATA_IDENTIFY_DEVICE_BUFFER_LENGTH, 429 AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata); 430 if (rc != EOK) { 431 ddf_msg(LVL_ERROR, "Cannot allocate buffer to identify device."); 432 return rc; 433 } 434 435 bzero(idata, SATA_IDENTIFY_DEVICE_BUFFER_LENGTH); 387 436 388 437 fibril_mutex_lock(&sata->lock); 389 438 390 439 ahci_identify_device_cmd(sata, phys); 391 392 fibril_mutex_lock(&sata->event_lock); 393 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 394 fibril_mutex_unlock(&sata->event_lock); 395 396 ahci_port_is_t pxis = sata->shadow_pxis; 397 sata->shadow_pxis.u32 &= ~pxis.u32; 440 ahci_port_is_t pxis = ahci_wait_event(sata); 398 441 399 442 if (sata->is_invalid_device) { … … 405 448 if (ahci_port_is_tfes(pxis)) { 406 449 ahci_identify_packet_device_cmd(sata, phys); 407 408 fibril_mutex_lock(&sata->event_lock); 409 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 410 fibril_mutex_unlock(&sata->event_lock); 411 412 pxis = sata->shadow_pxis; 413 sata->shadow_pxis.u32 &= ~pxis.u32; 450 pxis = ahci_wait_event(sata); 414 451 415 452 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 441 478 "%s: Sector length other than 512 B not supported", 442 479 sata->model); 443 goto error; 480 goto error; 444 481 } 445 482 … … 449 486 "%s: Sector length other than 512 B not supported", 450 487 sata->model); 451 goto error; 488 goto error; 452 489 } 453 490 } … … 488 525 goto error; 489 526 } else { 490 for (u nsigned int i = 0; i < 7; i++) {527 for (uint8_t i = 0; i < 7; i++) { 491 528 if (udma_mask & (1 << i)) 492 529 sata->highest_udma_mode = i; … … 515 552 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode) 516 553 { 517 /* Clear interrupt state registers */518 ahci_get_and_clear_pxis(sata);519 sata->shadow_pxis.u32 = 0;520 521 554 volatile sata_std_command_frame_t *cmd = 522 555 (sata_std_command_frame_t *) sata->cmd_table; … … 599 632 uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07); 600 633 ahci_set_mode_cmd(sata, phys, mode); 601 602 fibril_mutex_lock(&sata->event_lock); 603 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 604 fibril_mutex_unlock(&sata->event_lock); 605 606 ahci_port_is_t pxis = sata->shadow_pxis; 607 sata->shadow_pxis.u32 &= ~pxis.u32; 634 ahci_port_is_t pxis = ahci_wait_event(sata); 608 635 609 636 if (sata->is_invalid_device) { … … 641 668 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 642 669 { 643 /* Clear interrupt state registers */644 ahci_get_and_clear_pxis(sata);645 sata->shadow_pxis.u32 = 0;646 647 670 volatile sata_ncq_command_frame_t *cmd = 648 671 (sata_ncq_command_frame_t *) sata->cmd_table; … … 709 732 710 733 ahci_rb_fpdma_cmd(sata, phys, blocknum); 711 712 fibril_mutex_lock(&sata->event_lock); 713 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 714 fibril_mutex_unlock(&sata->event_lock); 715 716 ahci_port_is_t pxis = sata->shadow_pxis; 717 sata->shadow_pxis.u32 &= ~pxis.u32; 734 ahci_port_is_t pxis = ahci_wait_event(sata); 718 735 719 736 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 737 754 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 738 755 { 739 /* Clear interrupt state registers */ 740 ahci_get_and_clear_pxis(sata); 741 sata->shadow_pxis.u32 = 0; 742 743 volatile sata_ncq_command_frame_t * cmd = 756 volatile sata_ncq_command_frame_t *cmd = 744 757 (sata_ncq_command_frame_t *) sata->cmd_table; 745 758 … … 767 780 cmd->lba5 = (blocknum >> 40) & 0xff; 768 781 769 volatile ahci_cmd_prdt_t * 782 volatile ahci_cmd_prdt_t *prdt = 770 783 (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]); 771 784 … … 806 819 807 820 ahci_wb_fpdma_cmd(sata, phys, blocknum); 808 809 fibril_mutex_lock(&sata->event_lock); 810 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 811 fibril_mutex_unlock(&sata->event_lock); 812 813 ahci_port_is_t pxis = sata->shadow_pxis; 814 sata->shadow_pxis.u32 &= ~pxis.u32; 821 ahci_port_is_t pxis = ahci_wait_event(sata); 815 822 816 823 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 824 831 825 832 /*----------------------------------------------------------------------------*/ 826 /*-- Interrupts and timer unified handling-----------------------------------*/833 /*-- Interrupts handling -----------------------------------------------------*/ 827 834 /*----------------------------------------------------------------------------*/ 828 835 … … 830 837 { 831 838 .base = 0, 832 .size = 32,839 .size = 0, 833 840 } 834 841 }; 835 842 836 843 static irq_cmd_t ahci_cmds[] = { 837 { 838 /* Disable interrupt - interrupt is deasserted in qemu 1.0.1 */ 839 .cmd = CMD_PIO_WRITE_32, 840 .addr = NULL, 841 .value = AHCI_GHC_GHC_AE 842 }, 843 { 844 .cmd = CMD_PIO_READ_32, 845 .addr = NULL, 846 .dstarg = 1 847 }, 848 { 849 /* Clear interrupt status register - for vbox and real hw */ 850 .cmd = CMD_PIO_WRITE_A_32, 851 .addr = NULL, 852 .srcarg = 1 853 }, 854 { 855 .cmd = CMD_ACCEPT 856 } 844 AHCI_PORT_CMDS(0), 845 AHCI_PORT_CMDS(1), 846 AHCI_PORT_CMDS(2), 847 AHCI_PORT_CMDS(3), 848 AHCI_PORT_CMDS(4), 849 AHCI_PORT_CMDS(5), 850 AHCI_PORT_CMDS(6), 851 AHCI_PORT_CMDS(7), 852 AHCI_PORT_CMDS(8), 853 AHCI_PORT_CMDS(9), 854 AHCI_PORT_CMDS(10), 855 AHCI_PORT_CMDS(11), 856 AHCI_PORT_CMDS(12), 857 AHCI_PORT_CMDS(13), 858 AHCI_PORT_CMDS(14), 859 AHCI_PORT_CMDS(15), 860 AHCI_PORT_CMDS(16), 861 AHCI_PORT_CMDS(17), 862 AHCI_PORT_CMDS(18), 863 AHCI_PORT_CMDS(19), 864 AHCI_PORT_CMDS(20), 865 AHCI_PORT_CMDS(21), 866 AHCI_PORT_CMDS(22), 867 AHCI_PORT_CMDS(23), 868 AHCI_PORT_CMDS(24), 869 AHCI_PORT_CMDS(25), 870 AHCI_PORT_CMDS(26), 871 AHCI_PORT_CMDS(27), 872 AHCI_PORT_CMDS(28), 873 AHCI_PORT_CMDS(29), 874 AHCI_PORT_CMDS(30), 875 AHCI_PORT_CMDS(31) 857 876 }; 858 859 /** Unified AHCI interrupt and timer interrupt handler.860 *861 * @param ahci AHCI device.862 * @param is_timer Indicate timer interrupt.863 *864 */865 static void ahci_interrupt_or_timer(ahci_dev_t *ahci, bool is_timer)866 {867 /*868 * Get current value of hardware interrupt state register,869 * clear hardware register (write to clear behavior).870 */871 ahci_ghc_is_t is;872 873 is.u32 = ahci->memregs->ghc.is;874 ahci->memregs->ghc.is = is.u32;875 876 if (!is_timer)877 ahci->is_hw_interrupt = true;878 else if (is.u32)879 ahci->is_hw_interrupt = false;880 881 uint32_t port_event_flags = 0;882 uint32_t port_mask = 1;883 for (unsigned int i = 0; i < 32; i++) {884 sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];885 if (sata != NULL) {886 ahci_port_is_t pxis = ahci_get_and_clear_pxis(sata);887 888 /* Add value to shadow copy of port interrupt state register. */889 sata->shadow_pxis.u32 |= pxis.u32;890 891 /* Evaluate port event. */892 if ((ahci_port_is_end_of_operation(pxis)) ||893 (ahci_port_is_error(pxis)))894 port_event_flags |= port_mask;895 }896 897 port_mask <<= 1;898 }899 900 port_mask = 1;901 for (unsigned int i = 0; i < 32; i++) {902 sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];903 if ((port_event_flags & port_mask) && (sata != NULL)) {904 fibril_mutex_lock(&sata->event_lock);905 fibril_condvar_signal(&sata->event_condvar);906 fibril_mutex_unlock(&sata->event_lock);907 }908 909 port_mask <<= 1;910 }911 }912 913 /** AHCI timer interrupt handler.914 *915 * @param arg AHCI device.916 *917 */918 static void ahci_timer(void *arg)919 {920 ahci_dev_t *ahci = (ahci_dev_t *) arg;921 922 ahci_interrupt_or_timer(ahci, 1);923 924 if (ahci->is_hw_interrupt)925 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);926 else927 fibril_timer_set(ahci->timer, AHCI_TIMER_NO_INTR_TICKS,928 ahci_timer, ahci);929 }930 877 931 878 /** AHCI interrupt handler. … … 939 886 { 940 887 ahci_dev_t *ahci = (ahci_dev_t *) dev->driver_data; 941 942 ahci_interrupt_or_timer(ahci, 0); 943 944 /* Enable interrupt. */ 945 ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE; 888 unsigned int port = IPC_GET_ARG1(*icall); 889 ahci_port_is_t pxis = IPC_GET_ARG2(*icall); 890 891 if (port >= AHCI_MAX_PORTS) 892 return; 893 894 sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[port]; 895 if (sata == NULL) 896 return; 897 898 /* Evaluate port event */ 899 if ((ahci_port_is_end_of_operation(pxis)) || 900 (ahci_port_is_error(pxis))) { 901 fibril_mutex_lock(&sata->event_lock); 902 903 sata->event_pxis = pxis; 904 fibril_condvar_signal(&sata->event_condvar); 905 906 fibril_mutex_unlock(&sata->event_lock); 907 } 946 908 } 947 909 … … 951 913 952 914 /** Allocate SATA device structure with buffers for hardware. 953 * 915 * 954 916 * @param port AHCI port structure 955 917 * … … 960 922 { 961 923 size_t size = 4096; 962 void *phys = NULL;963 void *virt_fb = NULL;964 void *virt_cmd = NULL;965 void *virt_table = NULL;924 void *phys = NULL; 925 void *virt_fb = NULL; 926 void *virt_cmd = NULL; 927 void *virt_table = NULL; 966 928 967 929 sata_dev_t *sata = malloc(sizeof(sata_dev_t)); … … 1054 1016 1055 1017 /** Create and initialize connected SATA structure device 1056 * 1018 * 1057 1019 * @param ahci AHCI device structure. 1058 1020 * @param dev DDF device structure. … … 1078 1040 /* Initialize synchronization structures */ 1079 1041 fibril_mutex_initialize(&sata->lock); 1080 fibril_mutex_initialize(&sata->pxis_lock);1081 1042 fibril_mutex_initialize(&sata->event_lock); 1082 1043 fibril_condvar_initialize(&sata->event_condvar); 1083 1044 1084 1045 ahci_sata_hw_start(sata); 1085 1046 1086 1047 /* Identify device. */ 1087 1048 if (ahci_identify_device(sata) != EOK) … … 1150 1111 1151 1112 /** Create AHCI device structure, intialize it and register interrupt routine. 1152 * 1113 * 1153 1114 * @param dev DDF device structure. 1154 1115 * … … 1165 1126 1166 1127 ahci->dev = dev; 1167 1168 /* Create timer for AHCI. */1169 ahci->timer = fibril_timer_create();1170 if (ahci->timer == NULL)1171 goto error_create_timer;1172 1128 1173 1129 hw_res_list_parsed_t hw_res_parsed; … … 1187 1143 /* Register interrupt handler */ 1188 1144 ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address; 1189 ahci_ranges[0].size = sizeof(ahci_dev_t); 1190 1191 ahci_cmds[0].addr = 1192 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1193 AHCI_GHC_GHC_REGISTER_OFFSET; 1194 ahci_cmds[1].addr = 1195 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1196 AHCI_GHC_IS_REGISTER_OFFSET; 1197 ahci_cmds[2].addr = ahci_cmds[1].addr; 1145 ahci_ranges[0].size = sizeof(ahci_memregs_t); 1146 1147 for (unsigned int port = 0; port < AHCI_MAX_PORTS; port++) { 1148 size_t base = port * 7; 1149 1150 ahci_cmds[base].addr = 1151 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1152 AHCI_PORTS_REGISTERS_OFFSET + port * AHCI_PORT_REGISTERS_SIZE + 1153 AHCI_PORT_IS_REGISTER_OFFSET; 1154 ahci_cmds[base + 2].addr = ahci_cmds[base].addr; 1155 1156 ahci_cmds[base + 3].addr = 1157 ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1158 AHCI_GHC_IS_REGISTER_OFFSET; 1159 ahci_cmds[base + 4].addr = ahci_cmds[base + 3].addr; 1160 } 1198 1161 1199 1162 irq_code_t ct; … … 1205 1168 int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0], 1206 1169 ahci_interrupt, &ct); 1207 1208 1170 if (rc != EOK) { 1209 ddf_msg(LVL_ERROR, "Failed register _interrupt_handler function.");1171 ddf_msg(LVL_ERROR, "Failed registering interrupt handler."); 1210 1172 goto error_register_interrupt_handler; 1211 1173 } … … 1230 1192 1231 1193 error_get_res_parsed: 1232 fibril_timer_destroy(ahci->timer);1233 1234 error_create_timer:1235 1194 free(ahci); 1236 1195 return NULL; … … 1249 1208 ccc.u32 = ahci->memregs->ghc.ccc_ctl; 1250 1209 ccc.en = 0; 1251 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1210 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1252 1211 1253 1212 /* Set master latency timer. */ … … 1263 1222 1264 1223 /* Enable AHCI and interrupt. */ 1265 ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 1224 ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 1266 1225 } 1267 1226 … … 1290 1249 dev->driver_data = ahci; 1291 1250 1292 /* Set timer and AHCI hardware start. */ 1293 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 1251 /* Start AHCI hardware. */ 1294 1252 ahci_ahci_hw_start(ahci); 1295 1253 -
uspace/drv/block/ahci/ahci.h
r8486c07 reb3683a 48 48 volatile ahci_memregs_t *memregs; 49 49 50 /** AHCI device global timer. */51 fibril_timer_t *timer;52 53 50 /** Pointers to sata devices. */ 54 void *sata_devs[32]; 55 56 /** Device has harware interrupt. */ 57 bool is_hw_interrupt; 51 void *sata_devs[AHCI_MAX_PORTS]; 58 52 } ahci_dev_t; 59 53 … … 63 57 ahci_dev_t *ahci; 64 58 65 /** SATA port number (0-31). */59 /** SATA port number (0-31). */ 66 60 uint8_t port_num; 67 68 /** Port interrupt states shadow registers. */69 ahci_port_is_t shadow_pxis;70 61 71 62 /** Device in invalid state (disconnected and so on). */ … … 84 75 fibril_mutex_t lock; 85 76 86 /** Mutex for port interrupt state register manipulation. */87 fibril_mutex_t pxis_lock;88 89 77 /** Mutex for event signaling condition variable. */ 90 78 fibril_mutex_t event_lock; 79 91 80 /** Event signaling condition variable. */ 92 81 fibril_condvar_t event_condvar; 93 82 83 /** Event interrupt state. */ 84 ahci_port_is_t event_pxis; 85 94 86 /** Block device service id. */ 95 service_id_t service_id; 87 service_id_t service_id; 96 88 97 89 /** Number of device data blocks. */ 98 90 uint64_t blocks; 91 99 92 /** Size of device data blocks. */ 100 93 size_t block_size; -
uspace/drv/block/ahci/ahci_hw.h
r8486c07 reb3683a 374 374 } ahci_ghc_ghc_t; 375 375 376 /** AHCI GHC register offset. */377 #define AHCI_GHC_GHC_REGISTER_OFFSET 1378 379 376 /** AHCI Enable mask bit. */ 380 377 #define AHCI_GHC_GHC_AE 0x80000000 … … 384 381 385 382 /** AHCI Memory register Interrupt pending register. */ 386 typedef struct { 387 /** Interrupt pending status, if set, indicates that 388 * the corresponding port has an interrupt pending. 389 */ 390 uint32_t u32; 391 } ahci_ghc_is_t; 383 typedef uint32_t ahci_ghc_is_t; 392 384 393 385 /** AHCI GHC register offset. */ 394 #define AHCI_GHC_IS_REGISTER_OFFSET 2 386 #define AHCI_GHC_IS_REGISTER_OFFSET 2 387 388 /** AHCI ports registers offset. */ 389 #define AHCI_PORTS_REGISTERS_OFFSET 64 390 391 /** AHCI port registers size. */ 392 #define AHCI_PORT_REGISTERS_SIZE 32 393 394 /** AHCI port IS register offset. */ 395 #define AHCI_PORT_IS_REGISTER_OFFSET 4 395 396 396 397 /** AHCI Memory register Ports implemented. */ … … 531 532 uint32_t ghc; 532 533 /** Interrupt Status */ 533 uint32_t is;534 ahci_ghc_is_t is; 534 535 /** Ports Implemented */ 535 536 uint32_t pi; … … 603 604 604 605 /** AHCI Memory register Port x Interrupt Status. */ 605 typedef union { 606 struct { 607 /** Device to Host Register FIS Interrupt. */ 608 unsigned int dhrs : 1; 609 /** PIO Setup FIS Interrupt. */ 610 unsigned int pss : 1; 611 /** DMA Setup FIS Interrupt. */ 612 unsigned int dss : 1; 613 /** Set Device Bits Interrupt. */ 614 unsigned int sdbs : 1; 615 /** Unknown FIS Interrupt. */ 616 unsigned int ufs : 1; 617 /** Descriptor Processed. */ 618 unsigned int dps : 1; 619 /** Port Connect Change Status. */ 620 unsigned int pcs : 1; 621 /** Device Mechanical Presence Status. */ 622 unsigned int dmps : 1; 623 /** Reserved. */ 624 unsigned int reserved1 : 14; 625 /** PhyRdy Change Status. */ 626 unsigned int prcs : 1; 627 /** Incorrect Port Multiplier Status. */ 628 unsigned int ipms : 1; 629 /** Overflow Status. */ 630 unsigned int ofs : 1; 631 /** Reserved. */ 632 unsigned int reserved2 : 1; 633 /** Interface Non-fatal Error Status. */ 634 unsigned int infs : 1; 635 /** Interface Fatal Error Status. */ 636 unsigned int ifs : 1; 637 /** Host Bus Data Error Status. */ 638 unsigned int hbds : 1; 639 /** Host Bus Fatal Error Status. */ 640 unsigned int hbfs : 1; 641 /** Task File Error Status. */ 642 unsigned int tfes : 1; 643 /** Cold Port Detect Status. */ 644 unsigned int cpds : 1; 645 }; 646 uint32_t u32; 647 } ahci_port_is_t; 606 typedef uint32_t ahci_port_is_t; 648 607 649 608 #define AHCI_PORT_IS_DHRS (1 << 0) … … 700 659 static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is) 701 660 { 702 return port_is .u32& AHCI_PORT_END_OF_OPERATION;661 return port_is & AHCI_PORT_END_OF_OPERATION; 703 662 } 704 663 … … 712 671 static inline int ahci_port_is_error(ahci_port_is_t port_is) 713 672 { 714 return port_is .u32& AHCI_PORT_IS_ERROR;673 return port_is & AHCI_PORT_IS_ERROR; 715 674 } 716 675 … … 724 683 static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is) 725 684 { 726 return port_is .u32& AHCI_PORT_IS_PERMANENT_ERROR;685 return port_is & AHCI_PORT_IS_PERMANENT_ERROR; 727 686 } 728 687 … … 736 695 static inline int ahci_port_is_tfes(ahci_port_is_t port_is) 737 696 { 738 return port_is .u32& AHCI_PORT_IS_TFES;697 return port_is & AHCI_PORT_IS_TFES; 739 698 } 740 699 … … 994 953 uint32_t pxfbu; 995 954 /** Port x Interrupt Status. */ 996 uint32_t pxis;955 ahci_port_is_t pxis; 997 956 /** Port x Interrupt Enable. */ 998 957 uint32_t pxie; … … 1030 989 ahci_ghc_t ghc; 1031 990 /** Reserved. */ 1032 uint32_t reserved[13]; 991 uint32_t reserved[13]; 1033 992 /** Reserved for NVMHCI. */ 1034 993 uint32_t reservedfornvmhci[16]; … … 1036 995 uint32_t vendorspecificsregs[24]; 1037 996 /** Ports. */ 1038 ahci_port_t ports[ 32];997 ahci_port_t ports[AHCI_MAX_PORTS]; 1039 998 } ahci_memregs_t; 1040 999
Note:
See TracChangeset
for help on using the changeset viewer.