Changeset 7deca26 in mainline
- Timestamp:
- 2012-07-22T14:16:22Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7df0c2ff
- Parents:
- 0b293a6 (diff), 76c07e4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/ddi/irq.h
r0b293a6 r7deca26 42 42 43 43 typedef enum { 44 /** Read 1 byte from the I/O space. */ 44 /** Read 1 byte from the I/O space. 45 * 46 * *addr(8) -> scratch[dstarg] 47 */ 45 48 CMD_PIO_READ_8 = 1, 46 /** Read 2 bytes from the I/O space. */ 49 50 /** Read 2 bytes from the I/O space. 51 * 52 * *addr(16) -> scratch[dstarg] 53 */ 47 54 CMD_PIO_READ_16, 48 /** Read 4 bytes from the I/O space. */ 55 56 /** Read 4 bytes from the I/O space. 57 * 58 * *addr(32) -> scratch[dstarg] 59 */ 49 60 CMD_PIO_READ_32, 50 61 51 /** Write 1 byte to the I/O space. */ 62 /** Write 1 byte to the I/O space. 63 * 64 * value(8) -> *addr 65 */ 52 66 CMD_PIO_WRITE_8, 53 /** Write 2 bytes to the I/O space. */ 67 68 /** Write 2 bytes to the I/O space. 69 * 70 * value(16) -> *addr 71 */ 54 72 CMD_PIO_WRITE_16, 55 /** Write 4 bytes to the I/O space. */ 73 74 /** Write 4 bytes to the I/O space. 75 * 76 * value(32) -> *addr 77 */ 56 78 CMD_PIO_WRITE_32, 57 79 58 /** 59 * Write 1 byte from the source argument60 * to the I/O space.80 /** Write 1 byte to the I/O space. 81 * 82 * scratch[srcarg](8) -> *addr 61 83 */ 62 84 CMD_PIO_WRITE_A_8, 63 /** 64 * Write 2 bytes from the source argument 65 * to the I/O space. 85 86 /** Write 2 bytes to the I/O space. 87 * 88 * scratch[srcarg](16) -> *addr 66 89 */ 67 90 CMD_PIO_WRITE_A_16, 68 /** 69 * Write 4 bytes from the source argument 70 * to the I/O space. 91 92 /** Write 4 bytes to the I/O space. 93 * 94 * scratch[srcarg](32) -> *addr 71 95 */ 72 96 CMD_PIO_WRITE_A_32, 73 97 74 /** 75 * Perform a bit masking on the source argument76 * and store the result into the destination argument.98 /** Load value. 99 * 100 * value -> scratch[dstarg] 77 101 */ 78 CMD_ BTEST,102 CMD_LOAD, 79 103 80 /** 81 * Predicate the execution of the following 82 * N commands by the boolean value of the source 83 * argument. 104 /** Perform bitwise conjunction. 105 * 106 * scratch[srcarg] & value -> scratch[dstarg] 107 */ 108 CMD_AND, 109 110 /** Predicate the execution of the following commands. 111 * 112 * if (scratch[srcarg] == 0) 113 * (skip the following 'value' commands) 84 114 */ 85 115 CMD_PREDICATE, -
kernel/generic/include/ipc/irq.h
r0b293a6 r7deca26 37 37 38 38 /** Maximum number of IPC IRQ programmed I/O ranges. */ 39 #define IRQ_MAX_RANGE_COUNT 39 #define IRQ_MAX_RANGE_COUNT 8 40 40 41 41 /** Maximum length of IPC IRQ program. */ 42 #define IRQ_MAX_PROG_SIZE 2 042 #define IRQ_MAX_PROG_SIZE 256 43 43 44 44 #include <ipc/ipc.h> -
kernel/generic/src/ipc/irq.c
r0b293a6 r7deca26 39 39 * when interrupt is detected. The application may provide a simple 'top-half' 40 40 * handler as part of its registration, which can perform simple operations 41 * (read/write port/memory, add information to notification ipcmessage).41 * (read/write port/memory, add information to notification IPC message). 42 42 * 43 43 * The structure of a notification message is as follows: 44 44 * - IMETHOD: interface and method as registered by 45 45 * the SYS_IRQ_REGISTER syscall 46 * - ARG1: payload modified by a 'top-half' handler 47 * - ARG2: payload modified by a 'top-half' handler 48 * - ARG3: payload modified by a 'top-half' handler 49 * - ARG4: payload modified by a 'top-half' handler 50 * - ARG5: payload modified by a 'top-half' handler 46 * - ARG1: payload modified by a 'top-half' handler (scratch[1]) 47 * - ARG2: payload modified by a 'top-half' handler (scratch[2]) 48 * - ARG3: payload modified by a 'top-half' handler (scratch[3]) 49 * - ARG4: payload modified by a 'top-half' handler (scratch[4]) 50 * - ARG5: payload modified by a 'top-half' handler (scratch[5]) 51 51 * - in_phone_hash: interrupt counter (may be needed to assure correct order 52 52 * in multithreaded drivers) … … 87 87 static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount) 88 88 { 89 size_t i; 90 91 for (i = 0; i < rangecount; i++) { 89 for (size_t i = 0; i < rangecount; i++) { 92 90 #ifdef IO_SPACE_BOUNDARY 93 91 if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY) … … 100 98 irq_cmd_t *cmds, size_t cmdcount) 101 99 { 102 uintptr_t *pbase;103 size_t i, j;104 105 100 /* Copy the physical base addresses aside. */ 106 pbase = malloc(rangecount * sizeof(uintptr_t), 0);107 for ( i = 0; i < rangecount; i++)101 uintptr_t *pbase = malloc(rangecount * sizeof(uintptr_t), 0); 102 for (size_t i = 0; i < rangecount; i++) 108 103 pbase[i] = ranges[i].base; 109 104 110 105 /* Map the PIO ranges into the kernel virtual address space. */ 111 for ( i = 0; i < rangecount; i++) {106 for (size_t i = 0; i < rangecount; i++) { 112 107 #ifdef IO_SPACE_BOUNDARY 113 108 if ((void *) ranges[i].base < IO_SPACE_BOUNDARY) … … 122 117 } 123 118 } 124 119 125 120 /* Rewrite the pseudocode addresses from physical to kernel virtual. */ 126 for ( i = 0; i < cmdcount; i++) {121 for (size_t i = 0; i < cmdcount; i++) { 127 122 uintptr_t addr; 128 123 size_t size; 129 124 130 125 /* Process only commands that use an address. */ 131 126 switch (cmds[i].cmd) { 132 127 case CMD_PIO_READ_8: 133 134 128 case CMD_PIO_WRITE_8: 129 case CMD_PIO_WRITE_A_8: 135 130 size = 1; 136 131 break; 137 138 139 132 case CMD_PIO_READ_16: 133 case CMD_PIO_WRITE_16: 134 case CMD_PIO_WRITE_A_16: 140 135 size = 2; 141 136 break; 142 143 144 137 case CMD_PIO_READ_32: 138 case CMD_PIO_WRITE_32: 139 case CMD_PIO_WRITE_A_32: 145 140 size = 4; 146 141 break; … … 149 144 continue; 150 145 } 151 146 152 147 addr = (uintptr_t) cmds[i].addr; 153 148 149 size_t j; 154 150 for (j = 0; j < rangecount; j++) { 155 156 151 /* Find the matching range. */ 157 152 if (!iswithin(pbase[j], ranges[j].size, addr, size)) 158 153 continue; 159 154 160 155 /* Switch the command to a kernel virtual address. */ 161 156 addr -= pbase[j]; 162 157 addr += ranges[j].base; 163 158 164 159 cmds[i].addr = (void *) addr; 165 160 break; 166 161 } 167 162 168 163 if (j == rangecount) { 169 164 /* … … 176 171 } 177 172 } 178 173 179 174 free(pbase); 175 return EOK; 176 } 177 178 /** Statically check the top-half pseudocode 179 * 180 * Check the top-half pseudocode for invalid or unsafe 181 * constructs. 182 * 183 */ 184 static int code_check(irq_cmd_t *cmds, size_t cmdcount) 185 { 186 for (size_t i = 0; i < cmdcount; i++) { 187 /* 188 * Check for accepted ranges. 189 */ 190 if (cmds[i].cmd >= CMD_LAST) 191 return EINVAL; 192 193 if (cmds[i].srcarg >= IPC_CALL_LEN) 194 return EINVAL; 195 196 if (cmds[i].dstarg >= IPC_CALL_LEN) 197 return EINVAL; 198 199 switch (cmds[i].cmd) { 200 case CMD_PREDICATE: 201 /* 202 * Check for control flow overflow. 203 * Note that jumping just beyond the last 204 * command is a correct behaviour. 205 */ 206 if (i + cmds[i].value > cmdcount) 207 return EINVAL; 208 209 break; 210 default: 211 break; 212 } 213 } 214 180 215 return EOK; 181 216 } … … 207 242 irq_pio_range_t *ranges = NULL; 208 243 irq_cmd_t *cmds = NULL; 209 244 210 245 irq_code_t *code = malloc(sizeof(*code), 0); 211 246 int rc = copy_from_uspace(code, ucode, sizeof(*code)); … … 222 257 if (rc != EOK) 223 258 goto error; 224 259 225 260 cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0); 226 261 rc = copy_from_uspace(cmds, code->cmds, … … 228 263 if (rc != EOK) 229 264 goto error; 230 265 266 rc = code_check(cmds, code->cmdcount); 267 if (rc != EOK) 268 goto error; 269 231 270 rc = ranges_map_and_apply(ranges, code->rangecount, cmds, 232 271 code->cmdcount); 233 272 if (rc != EOK) 234 273 goto error; 235 274 236 275 code->ranges = ranges; 237 276 code->cmds = cmds; 238 277 239 278 return code; 240 279 241 280 error: 242 281 if (cmds) 243 282 free(cmds); 283 244 284 if (ranges) 245 285 free(ranges); 286 246 287 free(code); 247 288 return NULL; … … 250 291 /** Register an answerbox as a receiving end for IRQ notifications. 251 292 * 252 * @param box Receiving answerbox. 253 * @param inr IRQ number. 254 * @param devno Device number. 255 * @param imethod Interface and method to be associated with the 256 * notification. 257 * @param ucode Uspace pointer to top-half pseudocode. 258 * @return EOK on success or a negative error code. 293 * @param box Receiving answerbox. 294 * @param inr IRQ number. 295 * @param devno Device number. 296 * @param imethod Interface and method to be associated with the 297 * notification. 298 * @param ucode Uspace pointer to top-half pseudocode. 299 * 300 * @return EOK on success or a negative error code. 259 301 * 260 302 */ … … 266 308 (sysarg_t) devno 267 309 }; 268 310 269 311 if ((inr < 0) || (inr > last_inr)) 270 312 return ELIMIT; … … 329 371 /** Unregister task from IRQ notification. 330 372 * 331 * @param box Answerbox associated with the notification. 332 * @param inr IRQ number. 333 * @param devno Device number. 334 * @return EOK on success or a negative error code. 373 * @param box Answerbox associated with the notification. 374 * @param inr IRQ number. 375 * @param devno Device number. 376 * 377 * @return EOK on success or a negative error code. 378 * 335 379 */ 336 380 int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno) … … 340 384 (sysarg_t) devno 341 385 }; 342 386 343 387 if ((inr < 0) || (inr > last_inr)) 344 388 return ELIMIT; … … 436 480 /* Remove from the hash table. */ 437 481 hash_table_remove(&irq_uspace_hash_table, key, 2); 438 482 439 483 /* 440 484 * Release both locks so that we can free the pseudo code. … … 442 486 irq_spinlock_unlock(&box->irq_lock, false); 443 487 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 444 488 445 489 code_free(irq->notif_cfg.code); 446 490 free(irq); … … 492 536 493 537 for (size_t i = 0; i < code->cmdcount; i++) { 494 uint32_t dstval;495 496 538 uintptr_t srcarg = code->cmds[i].srcarg; 497 539 uintptr_t dstarg = code->cmds[i].dstarg; 498 540 499 if (srcarg >= IPC_CALL_LEN)500 break;501 502 if (dstarg >= IPC_CALL_LEN)503 break;504 505 541 switch (code->cmds[i].cmd) { 506 542 case CMD_PIO_READ_8: 507 dstval = pio_read_8((ioport8_t *) code->cmds[i].addr); 508 if (dstarg) 509 scratch[dstarg] = dstval; 543 scratch[dstarg] = 544 pio_read_8((ioport8_t *) code->cmds[i].addr); 510 545 break; 511 546 case CMD_PIO_READ_16: 512 dstval = pio_read_16((ioport16_t *) code->cmds[i].addr); 513 if (dstarg) 514 scratch[dstarg] = dstval; 547 scratch[dstarg] = 548 pio_read_16((ioport16_t *) code->cmds[i].addr); 515 549 break; 516 550 case CMD_PIO_READ_32: 517 dstval = pio_read_32((ioport32_t *) code->cmds[i].addr); 518 if (dstarg) 519 scratch[dstarg] = dstval; 551 scratch[dstarg] = 552 pio_read_32((ioport32_t *) code->cmds[i].addr); 520 553 break; 521 554 case CMD_PIO_WRITE_8: … … 532 565 break; 533 566 case CMD_PIO_WRITE_A_8: 534 if (srcarg) { 535 pio_write_8((ioport8_t *) code->cmds[i].addr, 536 (uint8_t) scratch[srcarg]); 537 } 567 pio_write_8((ioport8_t *) code->cmds[i].addr, 568 (uint8_t) scratch[srcarg]); 538 569 break; 539 570 case CMD_PIO_WRITE_A_16: 540 if (srcarg) { 541 pio_write_16((ioport16_t *) code->cmds[i].addr, 542 (uint16_t) scratch[srcarg]); 543 } 571 pio_write_16((ioport16_t *) code->cmds[i].addr, 572 (uint16_t) scratch[srcarg]); 544 573 break; 545 574 case CMD_PIO_WRITE_A_32: 546 if (srcarg) { 547 pio_write_32((ioport32_t *) code->cmds[i].addr, 548 (uint32_t) scratch[srcarg]); 549 } 550 break; 551 case CMD_BTEST: 552 if ((srcarg) && (dstarg)) { 553 dstval = scratch[srcarg] & code->cmds[i].value; 554 scratch[dstarg] = dstval; 555 } 575 pio_write_32((ioport32_t *) code->cmds[i].addr, 576 (uint32_t) scratch[srcarg]); 577 break; 578 case CMD_LOAD: 579 scratch[dstarg] = code->cmds[i].value; 580 break; 581 case CMD_AND: 582 scratch[dstarg] = scratch[srcarg] & 583 code->cmds[i].value; 556 584 break; 557 585 case CMD_PREDICATE: 558 if ( (srcarg) && (!scratch[srcarg])) {586 if (scratch[srcarg] == 0) 559 587 i += code->cmds[i].value; 560 continue; 561 } 588 562 589 break; 563 590 case CMD_ACCEPT: … … 582 609 { 583 610 ASSERT(irq); 584 611 585 612 ASSERT(interrupts_disabled()); 586 613 ASSERT(irq_spinlock_locked(&irq->lock)); -
uspace/drv/block/ahci/ahci.c
r0b293a6 r7deca26 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 sata->event_pxis = 0; 308 while (sata->event_pxis == 0) 309 fibril_condvar_wait(&sata->event_condvar, &sata->event_lock); 310 311 ahci_port_is_t pxis = sata->event_pxis; 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
r0b293a6 r7deca26 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
r0b293a6 r7deca26 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 -
uspace/drv/bus/usb/ohci/hc.c
r0b293a6 r7deca26 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 /** @addtogroup drvusbohcihc 29 30 * @{ … … 32 33 * @brief OHCI Host controller driver routines 33 34 */ 35 34 36 #include <errno.h> 35 37 #include <str_error.h> … … 49 51 static const irq_pio_range_t ohci_pio_ranges[] = { 50 52 { 51 .base = 0, /* filled later */53 .base = 0, 52 54 .size = sizeof(ohci_regs_t) 53 55 } … … 55 57 56 58 static const irq_cmd_t ohci_irq_commands[] = { 57 { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ }, 58 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = 0 /* filled later */ }, 59 { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 }, 60 { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ }, 61 { .cmd = CMD_ACCEPT }, 59 { 60 .cmd = CMD_PIO_READ_32, 61 .dstarg = 1, 62 .addr = NULL 63 }, 64 { 65 .cmd = CMD_AND, 66 .srcarg = 1, 67 .dstarg = 2, 68 .value = OHCI_USED_INTERRUPTS 69 }, 70 { 71 .cmd = CMD_PREDICATE, 72 .srcarg = 2, 73 .value = 2 74 }, 75 { 76 .cmd = CMD_PIO_WRITE_A_32, 77 .srcarg = 1, 78 .addr = NULL 79 }, 80 { 81 .cmd = CMD_ACCEPT 82 } 62 83 }; 63 84 … … 76 97 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t); 77 98 } 78 79 99 80 100 /** Get number of commands used in IRQ code. … … 111 131 ohci_regs_t *registers = (ohci_regs_t *) regs; 112 132 cmds[0].addr = (void *) ®isters->interrupt_status; 113 cmds[1].value = OHCI_USED_INTERRUPTS;114 133 cmds[3].addr = (void *) ®isters->interrupt_status; 115 134 … … 445 464 return; 446 465 } 466 447 467 const unsigned hc_status = C_HCFS_GET(instance->registers->control); 448 468 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ -
uspace/drv/bus/usb/uhci/hc.c
r0b293a6 r7deca26 50 50 static const irq_pio_range_t uhci_irq_pio_ranges[] = { 51 51 { 52 .base = 0, /* filled later */52 .base = 0, 53 53 .size = sizeof(uhci_regs_t) 54 54 } … … 56 56 57 57 static const irq_cmd_t uhci_irq_commands[] = { 58 { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/}, 59 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, 60 .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS }, 61 { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 }, 62 { .cmd = CMD_PIO_WRITE_A_16, .srcarg = 1, .addr = NULL/*filled later*/}, 63 { .cmd = CMD_ACCEPT }, 58 { 59 .cmd = CMD_PIO_READ_16, 60 .dstarg = 1, 61 .addr = NULL 62 }, 63 { 64 .cmd = CMD_AND, 65 .srcarg = 1, 66 .dstarg = 2, 67 .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS 68 }, 69 { 70 .cmd = CMD_PREDICATE, 71 .srcarg = 2, 72 .value = 2 73 }, 74 { 75 .cmd = CMD_PIO_WRITE_A_16, 76 .srcarg = 1, 77 .addr = NULL 78 }, 79 { 80 .cmd = CMD_ACCEPT 81 } 64 82 }; 65 83 -
uspace/drv/char/i8042/i8042.c
r0b293a6 r7deca26 120 120 }, 121 121 { 122 .cmd = CMD_ BTEST,122 .cmd = CMD_AND, 123 123 .value = i8042_OUTPUT_FULL, 124 124 .srcarg = 1, -
uspace/drv/nic/ne2k/ne2k.c
r0b293a6 r7deca26 83 83 { 84 84 /* Mask supported interrupt causes */ 85 .cmd = CMD_ BTEST,85 .cmd = CMD_AND, 86 86 .value = (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | 87 87 ISR_CNT | ISR_RDC), -
uspace/srv/hid/input/port/ns16550.c
r0b293a6 r7deca26 84 84 }, 85 85 { 86 .cmd = CMD_ BTEST,86 .cmd = CMD_AND, 87 87 .value = LSR_DATA_READY, 88 88 .srcarg = 1, -
uspace/srv/hid/input/port/pl050.c
r0b293a6 r7deca26 80 80 }, 81 81 { 82 .cmd = CMD_ BTEST,82 .cmd = CMD_AND, 83 83 .value = PL050_STAT_RXFULL, 84 84 .srcarg = 1, -
uspace/srv/hw/bus/cuda_adb/cuda_adb.c
r0b293a6 r7deca26 116 116 { 117 117 .cmd = CMD_PIO_READ_8, 118 .addr = NULL, /* will be patched in run-time */118 .addr = NULL, 119 119 .dstarg = 1 120 120 }, 121 121 { 122 .cmd = CMD_ BTEST,122 .cmd = CMD_AND, 123 123 .value = SR_INT, 124 124 .srcarg = 1,
Note:
See TracChangeset
for help on using the changeset viewer.