Changes in / [7deca26:0b293a6] in mainline
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/ddi/irq.h
r7deca26 r0b293a6 42 42 43 43 typedef enum { 44 /** Read 1 byte from the I/O space. 45 * 46 * *addr(8) -> scratch[dstarg] 47 */ 44 /** Read 1 byte from the I/O space. */ 48 45 CMD_PIO_READ_8 = 1, 49 50 /** Read 2 bytes from the I/O space. 51 * 52 * *addr(16) -> scratch[dstarg] 53 */ 46 /** Read 2 bytes from the I/O space. */ 54 47 CMD_PIO_READ_16, 55 56 /** Read 4 bytes from the I/O space. 57 * 58 * *addr(32) -> scratch[dstarg] 59 */ 48 /** Read 4 bytes from the I/O space. */ 60 49 CMD_PIO_READ_32, 61 50 62 /** Write 1 byte to the I/O space. 63 * 64 * value(8) -> *addr 65 */ 51 /** Write 1 byte to the I/O space. */ 66 52 CMD_PIO_WRITE_8, 67 68 /** Write 2 bytes to the I/O space. 69 * 70 * value(16) -> *addr 71 */ 53 /** Write 2 bytes to the I/O space. */ 72 54 CMD_PIO_WRITE_16, 73 74 /** Write 4 bytes to the I/O space. 75 * 76 * value(32) -> *addr 77 */ 55 /** Write 4 bytes to the I/O space. */ 78 56 CMD_PIO_WRITE_32, 79 57 80 /** Write 1 byte to the I/O space.81 * 82 * scratch[srcarg](8) -> *addr58 /** 59 * Write 1 byte from the source argument 60 * to the I/O space. 83 61 */ 84 62 CMD_PIO_WRITE_A_8, 85 86 /** Write 2 bytes to the I/O space. 87 * 88 * scratch[srcarg](16) -> *addr 63 /** 64 * Write 2 bytes from the source argument 65 * to the I/O space. 89 66 */ 90 67 CMD_PIO_WRITE_A_16, 91 92 /** Write 4 bytes to the I/O space. 93 * 94 * scratch[srcarg](32) -> *addr 68 /** 69 * Write 4 bytes from the source argument 70 * to the I/O space. 95 71 */ 96 72 CMD_PIO_WRITE_A_32, 97 73 98 /** Load value.99 * 100 * value -> scratch[dstarg]74 /** 75 * Perform a bit masking on the source argument 76 * and store the result into the destination argument. 101 77 */ 102 CMD_ LOAD,78 CMD_BTEST, 103 79 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) 80 /** 81 * Predicate the execution of the following 82 * N commands by the boolean value of the source 83 * argument. 114 84 */ 115 85 CMD_PREDICATE, -
kernel/generic/include/ipc/irq.h
r7deca26 r0b293a6 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 5642 #define IRQ_MAX_PROG_SIZE 20 43 43 44 44 #include <ipc/ipc.h> -
kernel/generic/src/ipc/irq.c
r7deca26 r0b293a6 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 (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])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 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 for (size_t i = 0; i < rangecount; i++) { 89 size_t i; 90 91 for (i = 0; i < rangecount; i++) { 90 92 #ifdef IO_SPACE_BOUNDARY 91 93 if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY) … … 98 100 irq_cmd_t *cmds, size_t cmdcount) 99 101 { 102 uintptr_t *pbase; 103 size_t i, j; 104 100 105 /* Copy the physical base addresses aside. */ 101 uintptr_t *pbase = malloc(rangecount * sizeof(uintptr_t), 0);102 for ( size_ti = 0; i < rangecount; i++)106 pbase = malloc(rangecount * sizeof(uintptr_t), 0); 107 for (i = 0; i < rangecount; i++) 103 108 pbase[i] = ranges[i].base; 104 109 105 110 /* Map the PIO ranges into the kernel virtual address space. */ 106 for ( size_ti = 0; i < rangecount; i++) {111 for (i = 0; i < rangecount; i++) { 107 112 #ifdef IO_SPACE_BOUNDARY 108 113 if ((void *) ranges[i].base < IO_SPACE_BOUNDARY) … … 117 122 } 118 123 } 119 124 120 125 /* Rewrite the pseudocode addresses from physical to kernel virtual. */ 121 for ( size_ti = 0; i < cmdcount; i++) {126 for (i = 0; i < cmdcount; i++) { 122 127 uintptr_t addr; 123 128 size_t size; 124 129 125 130 /* Process only commands that use an address. */ 126 131 switch (cmds[i].cmd) { 127 132 case CMD_PIO_READ_8: 128 129 133 case CMD_PIO_WRITE_8: 134 case CMD_PIO_WRITE_A_8: 130 135 size = 1; 131 136 break; 132 133 134 137 case CMD_PIO_READ_16: 138 case CMD_PIO_WRITE_16: 139 case CMD_PIO_WRITE_A_16: 135 140 size = 2; 136 141 break; 137 138 139 142 case CMD_PIO_READ_32: 143 case CMD_PIO_WRITE_32: 144 case CMD_PIO_WRITE_A_32: 140 145 size = 4; 141 146 break; … … 144 149 continue; 145 150 } 146 151 147 152 addr = (uintptr_t) cmds[i].addr; 148 153 149 size_t j;150 154 for (j = 0; j < rangecount; j++) { 155 151 156 /* Find the matching range. */ 152 157 if (!iswithin(pbase[j], ranges[j].size, addr, size)) 153 158 continue; 154 159 155 160 /* Switch the command to a kernel virtual address. */ 156 161 addr -= pbase[j]; 157 162 addr += ranges[j].base; 158 163 159 164 cmds[i].addr = (void *) addr; 160 165 break; 161 166 } 162 167 163 168 if (j == rangecount) { 164 169 /* … … 171 176 } 172 177 } 173 178 174 179 free(pbase); 175 return EOK;176 }177 178 /** Statically check the top-half pseudocode179 *180 * Check the top-half pseudocode for invalid or unsafe181 * 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 last204 * 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 215 180 return EOK; 216 181 } … … 242 207 irq_pio_range_t *ranges = NULL; 243 208 irq_cmd_t *cmds = NULL; 244 209 245 210 irq_code_t *code = malloc(sizeof(*code), 0); 246 211 int rc = copy_from_uspace(code, ucode, sizeof(*code)); … … 257 222 if (rc != EOK) 258 223 goto error; 259 224 260 225 cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0); 261 226 rc = copy_from_uspace(cmds, code->cmds, … … 263 228 if (rc != EOK) 264 229 goto error; 265 266 rc = code_check(cmds, code->cmdcount); 267 if (rc != EOK) 268 goto error; 269 230 270 231 rc = ranges_map_and_apply(ranges, code->rangecount, cmds, 271 232 code->cmdcount); 272 233 if (rc != EOK) 273 234 goto error; 274 235 275 236 code->ranges = ranges; 276 237 code->cmds = cmds; 277 238 278 239 return code; 279 240 280 241 error: 281 242 if (cmds) 282 243 free(cmds); 283 284 244 if (ranges) 285 245 free(ranges); 286 287 246 free(code); 288 247 return NULL; … … 291 250 /** Register an answerbox as a receiving end for IRQ notifications. 292 251 * 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. 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. 301 259 * 302 260 */ … … 308 266 (sysarg_t) devno 309 267 }; 310 268 311 269 if ((inr < 0) || (inr > last_inr)) 312 270 return ELIMIT; … … 371 329 /** Unregister task from IRQ notification. 372 330 * 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 * 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. 379 335 */ 380 336 int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno) … … 384 340 (sysarg_t) devno 385 341 }; 386 342 387 343 if ((inr < 0) || (inr > last_inr)) 388 344 return ELIMIT; … … 480 436 /* Remove from the hash table. */ 481 437 hash_table_remove(&irq_uspace_hash_table, key, 2); 482 438 483 439 /* 484 440 * Release both locks so that we can free the pseudo code. … … 486 442 irq_spinlock_unlock(&box->irq_lock, false); 487 443 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 488 444 489 445 code_free(irq->notif_cfg.code); 490 446 free(irq); … … 536 492 537 493 for (size_t i = 0; i < code->cmdcount; i++) { 494 uint32_t dstval; 495 538 496 uintptr_t srcarg = code->cmds[i].srcarg; 539 497 uintptr_t dstarg = code->cmds[i].dstarg; 540 498 499 if (srcarg >= IPC_CALL_LEN) 500 break; 501 502 if (dstarg >= IPC_CALL_LEN) 503 break; 504 541 505 switch (code->cmds[i].cmd) { 542 506 case CMD_PIO_READ_8: 543 scratch[dstarg] = 544 pio_read_8((ioport8_t *) code->cmds[i].addr); 507 dstval = pio_read_8((ioport8_t *) code->cmds[i].addr); 508 if (dstarg) 509 scratch[dstarg] = dstval; 545 510 break; 546 511 case CMD_PIO_READ_16: 547 scratch[dstarg] = 548 pio_read_16((ioport16_t *) code->cmds[i].addr); 512 dstval = pio_read_16((ioport16_t *) code->cmds[i].addr); 513 if (dstarg) 514 scratch[dstarg] = dstval; 549 515 break; 550 516 case CMD_PIO_READ_32: 551 scratch[dstarg] = 552 pio_read_32((ioport32_t *) code->cmds[i].addr); 517 dstval = pio_read_32((ioport32_t *) code->cmds[i].addr); 518 if (dstarg) 519 scratch[dstarg] = dstval; 553 520 break; 554 521 case CMD_PIO_WRITE_8: … … 565 532 break; 566 533 case CMD_PIO_WRITE_A_8: 567 pio_write_8((ioport8_t *) code->cmds[i].addr, 568 (uint8_t) scratch[srcarg]); 534 if (srcarg) { 535 pio_write_8((ioport8_t *) code->cmds[i].addr, 536 (uint8_t) scratch[srcarg]); 537 } 569 538 break; 570 539 case CMD_PIO_WRITE_A_16: 571 pio_write_16((ioport16_t *) code->cmds[i].addr, 572 (uint16_t) scratch[srcarg]); 540 if (srcarg) { 541 pio_write_16((ioport16_t *) code->cmds[i].addr, 542 (uint16_t) scratch[srcarg]); 543 } 573 544 break; 574 545 case CMD_PIO_WRITE_A_32: 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; 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 } 584 556 break; 585 557 case CMD_PREDICATE: 586 if ( scratch[srcarg] == 0)558 if ((srcarg) && (!scratch[srcarg])) { 587 559 i += code->cmds[i].value; 588 560 continue; 561 } 589 562 break; 590 563 case CMD_ACCEPT: … … 609 582 { 610 583 ASSERT(irq); 611 584 612 585 ASSERT(interrupts_disabled()); 613 586 ASSERT(irq_spinlock_locked(&irq->lock)); -
uspace/drv/block/ahci/ahci.c
r7deca26 r0b293a6 49 49 #define NAME "ahci" 50 50 51 /** Number of ticks for watchdog timer. */ 52 #define AHCI_TIMER_TICKS 800000 53 54 /** Number of ticks for timer based interrupt. */ 55 #define AHCI_TIMER_NO_INTR_TICKS 8000 56 51 57 #define LO(ptr) \ 52 58 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff)) … … 54 60 #define HI(ptr) \ 55 61 ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32)) 56 57 /** Interrupt pseudocode for a single port58 *59 * The interrupt handling works as follows:60 *61 * 1. Port interrupt status register is read62 * (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 read66 * and cleared (any potential interrupts from67 * 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 }113 62 114 63 static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *); … … 294 243 /*----------------------------------------------------------------------------*/ 295 244 296 /** Wait for interrupt event.245 /** Get and clear AHCI port interrupt state register. 297 246 * 298 247 * @param sata SATA device structure. … … 301 250 * 302 251 */ 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; 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; 312 260 313 261 if (ahci_port_is_permanent_error(pxis)) 314 262 sata->is_invalid_device = true; 315 263 316 fibril_mutex_unlock(&sata-> event_lock);264 fibril_mutex_unlock(&sata->pxis_lock); 317 265 318 266 return pxis; … … 327 275 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys) 328 276 { 277 /* Clear interrupt state registers */ 278 ahci_get_and_clear_pxis(sata); 279 sata->shadow_pxis.u32 = 0; 280 329 281 volatile sata_std_command_frame_t *cmd = 330 282 (sata_std_command_frame_t *) sata->cmd_table; … … 356 308 sata->cmd_header->flags = 357 309 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 358 AHCI_CMDHDR_FLAGS_2DWCMD; 310 AHCI_CMDHDR_FLAGS_2DWCMD; 359 311 sata->cmd_header->bytesprocessed = 0; 360 312 … … 372 324 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys) 373 325 { 374 volatile sata_std_command_frame_t *cmd = 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 = 375 331 (sata_std_command_frame_t *) sata->cmd_table; 376 332 … … 399 355 400 356 sata->cmd_header->prdtl = 1; 401 sata->cmd_header->flags = 357 sata->cmd_header->flags = 402 358 AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK | 403 359 AHCI_CMDHDR_FLAGS_2DWCMD; … … 426 382 void *phys; 427 383 sata_identify_data_t *idata; 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); 384 dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys, 385 (void **) &idata); 386 bzero(idata, 512); 436 387 437 388 fibril_mutex_lock(&sata->lock); 438 389 439 390 ahci_identify_device_cmd(sata, phys); 440 ahci_port_is_t pxis = ahci_wait_event(sata); 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; 441 398 442 399 if (sata->is_invalid_device) { … … 448 405 if (ahci_port_is_tfes(pxis)) { 449 406 ahci_identify_packet_device_cmd(sata, phys); 450 pxis = ahci_wait_event(sata); 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; 451 414 452 415 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 478 441 "%s: Sector length other than 512 B not supported", 479 442 sata->model); 480 goto error; 443 goto error; 481 444 } 482 445 … … 486 449 "%s: Sector length other than 512 B not supported", 487 450 sata->model); 488 goto error; 451 goto error; 489 452 } 490 453 } … … 525 488 goto error; 526 489 } else { 527 for (u int8_t i = 0; i < 7; i++) {490 for (unsigned int i = 0; i < 7; i++) { 528 491 if (udma_mask & (1 << i)) 529 492 sata->highest_udma_mode = i; … … 552 515 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode) 553 516 { 517 /* Clear interrupt state registers */ 518 ahci_get_and_clear_pxis(sata); 519 sata->shadow_pxis.u32 = 0; 520 554 521 volatile sata_std_command_frame_t *cmd = 555 522 (sata_std_command_frame_t *) sata->cmd_table; … … 632 599 uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07); 633 600 ahci_set_mode_cmd(sata, phys, mode); 634 ahci_port_is_t pxis = ahci_wait_event(sata); 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; 635 608 636 609 if (sata->is_invalid_device) { … … 668 641 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 669 642 { 643 /* Clear interrupt state registers */ 644 ahci_get_and_clear_pxis(sata); 645 sata->shadow_pxis.u32 = 0; 646 670 647 volatile sata_ncq_command_frame_t *cmd = 671 648 (sata_ncq_command_frame_t *) sata->cmd_table; … … 732 709 733 710 ahci_rb_fpdma_cmd(sata, phys, blocknum); 734 ahci_port_is_t pxis = ahci_wait_event(sata); 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; 735 718 736 719 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 754 737 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum) 755 738 { 756 volatile sata_ncq_command_frame_t *cmd = 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 = 757 744 (sata_ncq_command_frame_t *) sata->cmd_table; 758 745 … … 780 767 cmd->lba5 = (blocknum >> 40) & 0xff; 781 768 782 volatile ahci_cmd_prdt_t * prdt =769 volatile ahci_cmd_prdt_t * prdt = 783 770 (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]); 784 771 … … 819 806 820 807 ahci_wb_fpdma_cmd(sata, phys, blocknum); 821 ahci_port_is_t pxis = ahci_wait_event(sata); 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; 822 815 823 816 if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) { … … 831 824 832 825 /*----------------------------------------------------------------------------*/ 833 /*-- Interrupts handling -----------------------------------------------------*/826 /*-- Interrupts and timer unified handling -----------------------------------*/ 834 827 /*----------------------------------------------------------------------------*/ 835 828 … … 837 830 { 838 831 .base = 0, 839 .size = 0,832 .size = 32, 840 833 } 841 834 }; 842 835 843 836 static irq_cmd_t ahci_cmds[] = { 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) 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 } 876 857 }; 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 else 927 fibril_timer_set(ahci->timer, AHCI_TIMER_NO_INTR_TICKS, 928 ahci_timer, ahci); 929 } 877 930 878 931 /** AHCI interrupt handler. … … 886 939 { 887 940 ahci_dev_t *ahci = (ahci_dev_t *) dev->driver_data; 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 } 941 942 ahci_interrupt_or_timer(ahci, 0); 943 944 /* Enable interrupt. */ 945 ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE; 908 946 } 909 947 … … 913 951 914 952 /** Allocate SATA device structure with buffers for hardware. 915 * 953 * 916 954 * @param port AHCI port structure 917 955 * … … 922 960 { 923 961 size_t size = 4096; 924 void *phys = NULL;925 void *virt_fb = NULL;926 void *virt_cmd = NULL;927 void *virt_table = NULL;962 void* phys = NULL; 963 void* virt_fb = NULL; 964 void* virt_cmd = NULL; 965 void* virt_table = NULL; 928 966 929 967 sata_dev_t *sata = malloc(sizeof(sata_dev_t)); … … 1016 1054 1017 1055 /** Create and initialize connected SATA structure device 1018 * 1056 * 1019 1057 * @param ahci AHCI device structure. 1020 1058 * @param dev DDF device structure. … … 1040 1078 /* Initialize synchronization structures */ 1041 1079 fibril_mutex_initialize(&sata->lock); 1080 fibril_mutex_initialize(&sata->pxis_lock); 1042 1081 fibril_mutex_initialize(&sata->event_lock); 1043 1082 fibril_condvar_initialize(&sata->event_condvar); 1044 1083 1045 1084 ahci_sata_hw_start(sata); 1046 1085 1047 1086 /* Identify device. */ 1048 1087 if (ahci_identify_device(sata) != EOK) … … 1111 1150 1112 1151 /** Create AHCI device structure, intialize it and register interrupt routine. 1113 * 1152 * 1114 1153 * @param dev DDF device structure. 1115 1154 * … … 1126 1165 1127 1166 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; 1128 1172 1129 1173 hw_res_list_parsed_t hw_res_parsed; … … 1143 1187 /* Register interrupt handler */ 1144 1188 ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address; 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 } 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; 1161 1198 1162 1199 irq_code_t ct; … … 1168 1205 int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0], 1169 1206 ahci_interrupt, &ct); 1207 1170 1208 if (rc != EOK) { 1171 ddf_msg(LVL_ERROR, "Failed register ing interrupt handler.");1209 ddf_msg(LVL_ERROR, "Failed register_interrupt_handler function."); 1172 1210 goto error_register_interrupt_handler; 1173 1211 } … … 1192 1230 1193 1231 error_get_res_parsed: 1232 fibril_timer_destroy(ahci->timer); 1233 1234 error_create_timer: 1194 1235 free(ahci); 1195 1236 return NULL; … … 1208 1249 ccc.u32 = ahci->memregs->ghc.ccc_ctl; 1209 1250 ccc.en = 0; 1210 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1251 ahci->memregs->ghc.ccc_ctl = ccc.u32; 1211 1252 1212 1253 /* Set master latency timer. */ … … 1222 1263 1223 1264 /* Enable AHCI and interrupt. */ 1224 ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 1265 ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 1225 1266 } 1226 1267 … … 1249 1290 dev->driver_data = ahci; 1250 1291 1251 /* Start AHCI hardware. */ 1292 /* Set timer and AHCI hardware start. */ 1293 fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci); 1252 1294 ahci_ahci_hw_start(ahci); 1253 1295 -
uspace/drv/block/ahci/ahci.h
r7deca26 r0b293a6 48 48 volatile ahci_memregs_t *memregs; 49 49 50 /** AHCI device global timer. */ 51 fibril_timer_t *timer; 52 50 53 /** Pointers to sata devices. */ 51 void *sata_devs[AHCI_MAX_PORTS]; 54 void *sata_devs[32]; 55 56 /** Device has harware interrupt. */ 57 bool is_hw_interrupt; 52 58 } ahci_dev_t; 53 59 … … 57 63 ahci_dev_t *ahci; 58 64 59 /** SATA port number 65 /** SATA port number(0-31). */ 60 66 uint8_t port_num; 67 68 /** Port interrupt states shadow registers. */ 69 ahci_port_is_t shadow_pxis; 61 70 62 71 /** Device in invalid state (disconnected and so on). */ … … 75 84 fibril_mutex_t lock; 76 85 86 /** Mutex for port interrupt state register manipulation. */ 87 fibril_mutex_t pxis_lock; 88 77 89 /** Mutex for event signaling condition variable. */ 78 90 fibril_mutex_t event_lock; 79 80 91 /** Event signaling condition variable. */ 81 92 fibril_condvar_t event_condvar; 82 93 83 /** Event interrupt state. */84 ahci_port_is_t event_pxis;85 86 94 /** Block device service id. */ 87 service_id_t service_id; 95 service_id_t service_id; 88 96 89 97 /** Number of device data blocks. */ 90 98 uint64_t blocks; 91 92 99 /** Size of device data blocks. */ 93 100 size_t block_size; -
uspace/drv/block/ahci/ahci_hw.h
r7deca26 r0b293a6 374 374 } ahci_ghc_ghc_t; 375 375 376 /** AHCI GHC register offset. */ 377 #define AHCI_GHC_GHC_REGISTER_OFFSET 1 378 376 379 /** AHCI Enable mask bit. */ 377 380 #define AHCI_GHC_GHC_AE 0x80000000 … … 381 384 382 385 /** AHCI Memory register Interrupt pending register. */ 383 typedef uint32_t ahci_ghc_is_t; 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; 384 392 385 393 /** AHCI GHC register offset. */ 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 394 #define AHCI_GHC_IS_REGISTER_OFFSET 2 396 395 397 396 /** AHCI Memory register Ports implemented. */ … … 532 531 uint32_t ghc; 533 532 /** Interrupt Status */ 534 ahci_ghc_is_t is;533 uint32_t is; 535 534 /** Ports Implemented */ 536 535 uint32_t pi; … … 604 603 605 604 /** AHCI Memory register Port x Interrupt Status. */ 606 typedef uint32_t ahci_port_is_t; 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; 607 648 608 649 #define AHCI_PORT_IS_DHRS (1 << 0) … … 659 700 static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is) 660 701 { 661 return port_is & AHCI_PORT_END_OF_OPERATION;702 return port_is.u32 & AHCI_PORT_END_OF_OPERATION; 662 703 } 663 704 … … 671 712 static inline int ahci_port_is_error(ahci_port_is_t port_is) 672 713 { 673 return port_is & AHCI_PORT_IS_ERROR;714 return port_is.u32 & AHCI_PORT_IS_ERROR; 674 715 } 675 716 … … 683 724 static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is) 684 725 { 685 return port_is & AHCI_PORT_IS_PERMANENT_ERROR;726 return port_is.u32 & AHCI_PORT_IS_PERMANENT_ERROR; 686 727 } 687 728 … … 695 736 static inline int ahci_port_is_tfes(ahci_port_is_t port_is) 696 737 { 697 return port_is & AHCI_PORT_IS_TFES;738 return port_is.u32 & AHCI_PORT_IS_TFES; 698 739 } 699 740 … … 953 994 uint32_t pxfbu; 954 995 /** Port x Interrupt Status. */ 955 ahci_port_is_t pxis;996 uint32_t pxis; 956 997 /** Port x Interrupt Enable. */ 957 998 uint32_t pxie; … … 989 1030 ahci_ghc_t ghc; 990 1031 /** Reserved. */ 991 uint32_t reserved[13]; 1032 uint32_t reserved[13]; 992 1033 /** Reserved for NVMHCI. */ 993 1034 uint32_t reservedfornvmhci[16]; … … 995 1036 uint32_t vendorspecificsregs[24]; 996 1037 /** Ports. */ 997 ahci_port_t ports[ AHCI_MAX_PORTS];1038 ahci_port_t ports[32]; 998 1039 } ahci_memregs_t; 999 1040 -
uspace/drv/bus/usb/ohci/hc.c
r7deca26 r0b293a6 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 28 /** @addtogroup drvusbohcihc 30 29 * @{ … … 33 32 * @brief OHCI Host controller driver routines 34 33 */ 35 36 34 #include <errno.h> 37 35 #include <str_error.h> … … 51 49 static const irq_pio_range_t ohci_pio_ranges[] = { 52 50 { 53 .base = 0, 51 .base = 0, /* filled later */ 54 52 .size = sizeof(ohci_regs_t) 55 53 } … … 57 55 58 56 static const irq_cmd_t ohci_irq_commands[] = { 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 } 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 }, 83 62 }; 84 63 … … 97 76 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t); 98 77 } 78 99 79 100 80 /** Get number of commands used in IRQ code. … … 131 111 ohci_regs_t *registers = (ohci_regs_t *) regs; 132 112 cmds[0].addr = (void *) ®isters->interrupt_status; 113 cmds[1].value = OHCI_USED_INTERRUPTS; 133 114 cmds[3].addr = (void *) ®isters->interrupt_status; 134 115 … … 464 445 return; 465 446 } 466 467 447 const unsigned hc_status = C_HCFS_GET(instance->registers->control); 468 448 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ -
uspace/drv/bus/usb/uhci/hc.c
r7deca26 r0b293a6 50 50 static const irq_pio_range_t uhci_irq_pio_ranges[] = { 51 51 { 52 .base = 0, 52 .base = 0, /* filled later */ 53 53 .size = sizeof(uhci_regs_t) 54 54 } … … 56 56 57 57 static const irq_cmd_t uhci_irq_commands[] = { 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 } 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 }, 82 64 }; 83 65 -
uspace/drv/char/i8042/i8042.c
r7deca26 r0b293a6 120 120 }, 121 121 { 122 .cmd = CMD_ AND,122 .cmd = CMD_BTEST, 123 123 .value = i8042_OUTPUT_FULL, 124 124 .srcarg = 1, -
uspace/drv/nic/ne2k/ne2k.c
r7deca26 r0b293a6 83 83 { 84 84 /* Mask supported interrupt causes */ 85 .cmd = CMD_ AND,85 .cmd = CMD_BTEST, 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
r7deca26 r0b293a6 84 84 }, 85 85 { 86 .cmd = CMD_ AND,86 .cmd = CMD_BTEST, 87 87 .value = LSR_DATA_READY, 88 88 .srcarg = 1, -
uspace/srv/hid/input/port/pl050.c
r7deca26 r0b293a6 80 80 }, 81 81 { 82 .cmd = CMD_ AND,82 .cmd = CMD_BTEST, 83 83 .value = PL050_STAT_RXFULL, 84 84 .srcarg = 1, -
uspace/srv/hw/bus/cuda_adb/cuda_adb.c
r7deca26 r0b293a6 116 116 { 117 117 .cmd = CMD_PIO_READ_8, 118 .addr = NULL, 118 .addr = NULL, /* will be patched in run-time */ 119 119 .dstarg = 1 120 120 }, 121 121 { 122 .cmd = CMD_ AND,122 .cmd = CMD_BTEST, 123 123 .value = SR_INT, 124 124 .srcarg = 1,
Note:
See TracChangeset
for help on using the changeset viewer.