Changes in / [7deca26:0b293a6] in mainline


Ignore:
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • abi/include/ddi/irq.h

    r7deca26 r0b293a6  
    4242
    4343typedef 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. */
    4845        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. */
    5447        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. */
    6049        CMD_PIO_READ_32,
    6150       
    62         /** Write 1 byte to the I/O space.
    63          *
    64          * value(8) -> *addr
    65          */
     51        /** Write 1 byte to the I/O space. */
    6652        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. */
    7254        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. */
    7856        CMD_PIO_WRITE_32,
    7957       
    80         /** Write 1 byte to the I/O space.
    81          *
    82          * scratch[srcarg](8) -> *addr
     58        /**
     59         * Write 1 byte from the source argument
     60         * to the I/O space.
    8361         */
    8462        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.
    8966         */
    9067        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.
    9571         */
    9672        CMD_PIO_WRITE_A_32,
    9773       
    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.
    10177         */
    102         CMD_LOAD,
     78        CMD_BTEST,
    10379       
    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.
    11484         */
    11585        CMD_PREDICATE,
  • kernel/generic/include/ipc/irq.h

    r7deca26 r0b293a6  
    3737
    3838/** Maximum number of IPC IRQ programmed I/O ranges. */
    39 #define IRQ_MAX_RANGE_COUNT  8
     39#define IRQ_MAX_RANGE_COUNT     8
    4040
    4141/** Maximum length of IPC IRQ program. */
    42 #define IRQ_MAX_PROG_SIZE  256
     42#define IRQ_MAX_PROG_SIZE  20
    4343
    4444#include <ipc/ipc.h>
  • kernel/generic/src/ipc/irq.c

    r7deca26 r0b293a6  
    3939 * when interrupt is detected. The application may provide a simple 'top-half'
    4040 * handler as part of its registration, which can perform simple operations
    41  * (read/write port/memory, add information to notification IPC message).
     41 * (read/write port/memory, add information to notification ipc message).
    4242 *
    4343 * The structure of a notification message is as follows:
    4444 * - IMETHOD: interface and method as registered by
    4545 *            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
    5151 * - in_phone_hash: interrupt counter (may be needed to assure correct order
    5252 *                  in multithreaded drivers)
     
    8787static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount)
    8888{
    89         for (size_t i = 0; i < rangecount; i++) {
     89        size_t i;
     90
     91        for (i = 0; i < rangecount; i++) {
    9092#ifdef IO_SPACE_BOUNDARY
    9193                if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY)
     
    98100    irq_cmd_t *cmds, size_t cmdcount)
    99101{
     102        uintptr_t *pbase;
     103        size_t i, j;
     104
    100105        /* Copy the physical base addresses aside. */
    101         uintptr_t *pbase = malloc(rangecount * sizeof(uintptr_t), 0);
    102         for (size_t i = 0; i < rangecount; i++)
     106        pbase = malloc(rangecount * sizeof(uintptr_t), 0);
     107        for (i = 0; i < rangecount; i++)
    103108                pbase[i] = ranges[i].base;
    104        
     109
    105110        /* Map the PIO ranges into the kernel virtual address space. */
    106         for (size_t i = 0; i < rangecount; i++) {
     111        for (i = 0; i < rangecount; i++) {
    107112#ifdef IO_SPACE_BOUNDARY
    108113                if ((void *) ranges[i].base < IO_SPACE_BOUNDARY)
     
    117122                }
    118123        }
    119        
     124
    120125        /* Rewrite the pseudocode addresses from physical to kernel virtual. */
    121         for (size_t i = 0; i < cmdcount; i++) {
     126        for (i = 0; i < cmdcount; i++) {
    122127                uintptr_t addr;
    123128                size_t size;
    124                
     129
    125130                /* Process only commands that use an address. */
    126131                switch (cmds[i].cmd) {
    127132                case CMD_PIO_READ_8:
    128                 case CMD_PIO_WRITE_8:
    129                 case CMD_PIO_WRITE_A_8:
     133                case CMD_PIO_WRITE_8:
     134                case CMD_PIO_WRITE_A_8:
    130135                        size = 1;
    131136                        break;
    132                 case CMD_PIO_READ_16:
    133                 case CMD_PIO_WRITE_16:
    134                 case CMD_PIO_WRITE_A_16:
     137                case CMD_PIO_READ_16:
     138                case CMD_PIO_WRITE_16:
     139                case CMD_PIO_WRITE_A_16:
    135140                        size = 2;
    136141                        break;
    137                 case CMD_PIO_READ_32:
    138                 case CMD_PIO_WRITE_32:
    139                 case CMD_PIO_WRITE_A_32:
     142                case CMD_PIO_READ_32:
     143                case CMD_PIO_WRITE_32:
     144                case CMD_PIO_WRITE_A_32:
    140145                        size = 4;
    141146                        break;
     
    144149                        continue;
    145150                }
    146                
     151
    147152                addr = (uintptr_t) cmds[i].addr;
    148153               
    149                 size_t j;
    150154                for (j = 0; j < rangecount; j++) {
     155
    151156                        /* Find the matching range. */
    152157                        if (!iswithin(pbase[j], ranges[j].size, addr, size))
    153158                                continue;
    154                        
     159
    155160                        /* Switch the command to a kernel virtual address. */
    156161                        addr -= pbase[j];
    157162                        addr += ranges[j].base;
    158                        
     163
    159164                        cmds[i].addr = (void *) addr;
    160165                        break;
    161166                }
    162                
     167
    163168                if (j == rangecount) {
    164169                        /*
     
    171176                }
    172177        }
    173        
     178
    174179        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        
    215180        return EOK;
    216181}
     
    242207        irq_pio_range_t *ranges = NULL;
    243208        irq_cmd_t *cmds = NULL;
    244        
     209
    245210        irq_code_t *code = malloc(sizeof(*code), 0);
    246211        int rc = copy_from_uspace(code, ucode, sizeof(*code));
     
    257222        if (rc != EOK)
    258223                goto error;
    259        
     224
    260225        cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
    261226        rc = copy_from_uspace(cmds, code->cmds,
     
    263228        if (rc != EOK)
    264229                goto error;
    265        
    266         rc = code_check(cmds, code->cmdcount);
    267         if (rc != EOK)
    268                 goto error;
    269        
     230
    270231        rc = ranges_map_and_apply(ranges, code->rangecount, cmds,
    271232            code->cmdcount);
    272233        if (rc != EOK)
    273234                goto error;
    274        
     235
    275236        code->ranges = ranges;
    276237        code->cmds = cmds;
    277        
     238
    278239        return code;
    279        
     240
    280241error:
    281242        if (cmds)
    282243                free(cmds);
    283        
    284244        if (ranges)
    285245                free(ranges);
    286        
    287246        free(code);
    288247        return NULL;
     
    291250/** Register an answerbox as a receiving end for IRQ notifications.
    292251 *
    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.
    301259 *
    302260 */
     
    308266                (sysarg_t) devno
    309267        };
    310        
     268
    311269        if ((inr < 0) || (inr > last_inr))
    312270                return ELIMIT;
     
    371329/** Unregister task from IRQ notification.
    372330 *
    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.
    379335 */
    380336int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
     
    384340                (sysarg_t) devno
    385341        };
    386        
     342
    387343        if ((inr < 0) || (inr > last_inr))
    388344                return ELIMIT;
     
    480436                /* Remove from the hash table. */
    481437                hash_table_remove(&irq_uspace_hash_table, key, 2);
    482                
     438
    483439                /*
    484440                 * Release both locks so that we can free the pseudo code.
     
    486442                irq_spinlock_unlock(&box->irq_lock, false);
    487443                irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    488                
     444
    489445                code_free(irq->notif_cfg.code);
    490446                free(irq);
     
    536492       
    537493        for (size_t i = 0; i < code->cmdcount; i++) {
     494                uint32_t dstval;
     495               
    538496                uintptr_t srcarg = code->cmds[i].srcarg;
    539497                uintptr_t dstarg = code->cmds[i].dstarg;
    540498               
     499                if (srcarg >= IPC_CALL_LEN)
     500                        break;
     501               
     502                if (dstarg >= IPC_CALL_LEN)
     503                        break;
     504       
    541505                switch (code->cmds[i].cmd) {
    542506                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;
    545510                        break;
    546511                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;
    549515                        break;
    550516                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;
    553520                        break;
    554521                case CMD_PIO_WRITE_8:
     
    565532                        break;
    566533                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                        }
    569538                        break;
    570539                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                        }
    573544                        break;
    574545                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                        }
    584556                        break;
    585557                case CMD_PREDICATE:
    586                         if (scratch[srcarg] == 0)
     558                        if ((srcarg) && (!scratch[srcarg])) {
    587559                                i += code->cmds[i].value;
    588                        
     560                                continue;
     561                        }
    589562                        break;
    590563                case CMD_ACCEPT:
     
    609582{
    610583        ASSERT(irq);
    611        
     584
    612585        ASSERT(interrupts_disabled());
    613586        ASSERT(irq_spinlock_locked(&irq->lock));
  • uspace/drv/block/ahci/ahci.c

    r7deca26 r0b293a6  
    4949#define NAME  "ahci"
    5050
     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
    5157#define LO(ptr) \
    5258        ((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
     
    5460#define HI(ptr) \
    5561        ((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         }
    11362
    11463static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *);
     
    294243/*----------------------------------------------------------------------------*/
    295244
    296 /** Wait for interrupt event.
     245/** Get and clear AHCI port interrupt state register.
    297246 *
    298247 * @param sata SATA device structure.
     
    301250 *
    302251 */
    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;
     252static 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;
    312260       
    313261        if (ahci_port_is_permanent_error(pxis))
    314262                sata->is_invalid_device = true;
    315263       
    316         fibril_mutex_unlock(&sata->event_lock);
     264        fibril_mutex_unlock(&sata->pxis_lock);
    317265       
    318266        return pxis;
     
    327275static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys)
    328276{
     277        /* Clear interrupt state registers */
     278        ahci_get_and_clear_pxis(sata);
     279        sata->shadow_pxis.u32 = 0;
     280       
    329281        volatile sata_std_command_frame_t *cmd =
    330282            (sata_std_command_frame_t *) sata->cmd_table;
     
    356308        sata->cmd_header->flags =
    357309            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    358             AHCI_CMDHDR_FLAGS_2DWCMD;
     310            AHCI_CMDHDR_FLAGS_2DWCMD; 
    359311        sata->cmd_header->bytesprocessed = 0;
    360312       
     
    372324static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys)
    373325{
    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 =
    375331            (sata_std_command_frame_t *) sata->cmd_table;
    376332       
     
    399355       
    400356        sata->cmd_header->prdtl = 1;
    401         sata->cmd_header->flags =
     357        sata->cmd_header->flags = 
    402358            AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
    403359            AHCI_CMDHDR_FLAGS_2DWCMD;
     
    426382        void *phys;
    427383        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);
    436387       
    437388        fibril_mutex_lock(&sata->lock);
    438389       
    439390        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;
    441398       
    442399        if (sata->is_invalid_device) {
     
    448405        if (ahci_port_is_tfes(pxis)) {
    449406                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;
    451414               
    452415                if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     
    478441                            "%s: Sector length other than 512 B not supported",
    479442                            sata->model);
    480                         goto error;
     443                        goto error;     
    481444                }
    482445               
     
    486449                            "%s: Sector length other than 512 B not supported",
    487450                            sata->model);
    488                         goto error;
     451                        goto error;     
    489452                }
    490453        }
     
    525488                goto error;
    526489        } else {
    527                 for (uint8_t i = 0; i < 7; i++) {
     490                for (unsigned int i = 0; i < 7; i++) {
    528491                        if (udma_mask & (1 << i))
    529492                                sata->highest_udma_mode = i;
     
    552515static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode)
    553516{
     517        /* Clear interrupt state registers */
     518        ahci_get_and_clear_pxis(sata);
     519        sata->shadow_pxis.u32 = 0;
     520       
    554521        volatile sata_std_command_frame_t *cmd =
    555522            (sata_std_command_frame_t *) sata->cmd_table;
     
    632599        uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07);
    633600        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;
    635608       
    636609        if (sata->is_invalid_device) {
     
    668641static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    669642{
     643        /* Clear interrupt state registers */
     644        ahci_get_and_clear_pxis(sata);
     645        sata->shadow_pxis.u32 = 0;
     646       
    670647        volatile sata_ncq_command_frame_t *cmd =
    671648            (sata_ncq_command_frame_t *) sata->cmd_table;
     
    732709       
    733710        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;
    735718       
    736719        if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     
    754737static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
    755738{
    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 =
    757744            (sata_ncq_command_frame_t *) sata->cmd_table;
    758745       
     
    780767        cmd->lba5 = (blocknum >> 40) & 0xff;
    781768       
    782         volatile ahci_cmd_prdt_t *prdt =
     769        volatile ahci_cmd_prdt_t * prdt =
    783770            (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
    784771       
     
    819806       
    820807        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;
    822815       
    823816        if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
     
    831824
    832825/*----------------------------------------------------------------------------*/
    833 /*-- Interrupts handling -----------------------------------------------------*/
     826/*-- Interrupts and timer unified handling -----------------------------------*/
    834827/*----------------------------------------------------------------------------*/
    835828
     
    837830        {
    838831                .base = 0,
    839                 .size = 0,
     832                .size = 32,
    840833        }
    841834};
    842835
    843836static 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        }
    876857};
     858
     859/** Unified AHCI interrupt and timer interrupt handler.
     860 *
     861 * @param ahci     AHCI device.
     862 * @param is_timer Indicate timer interrupt.
     863 *
     864 */
     865static 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 */
     918static 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}
    877930
    878931/** AHCI interrupt handler.
     
    886939{
    887940        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;
    908946}
    909947
     
    913951
    914952/** Allocate SATA device structure with buffers for hardware.
    915  *
     953 * 
    916954 * @param port AHCI port structure
    917955 *
     
    922960{
    923961        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;
    928966       
    929967        sata_dev_t *sata = malloc(sizeof(sata_dev_t));
     
    10161054
    10171055/** Create and initialize connected SATA structure device
    1018  *
     1056 * 
    10191057 * @param ahci     AHCI device structure.
    10201058 * @param dev      DDF device structure.
     
    10401078        /* Initialize synchronization structures */
    10411079        fibril_mutex_initialize(&sata->lock);
     1080        fibril_mutex_initialize(&sata->pxis_lock);
    10421081        fibril_mutex_initialize(&sata->event_lock);
    10431082        fibril_condvar_initialize(&sata->event_condvar);
    1044        
     1083
    10451084        ahci_sata_hw_start(sata);
    1046        
     1085
    10471086        /* Identify device. */
    10481087        if (ahci_identify_device(sata) != EOK)
     
    11111150
    11121151/** Create AHCI device structure, intialize it and register interrupt routine.
    1113  *
     1152 * 
    11141153 * @param dev DDF device structure.
    11151154 *
     
    11261165       
    11271166        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;
    11281172       
    11291173        hw_res_list_parsed_t hw_res_parsed;
     
    11431187        /* Register interrupt handler */
    11441188        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;
    11611198       
    11621199        irq_code_t ct;
     
    11681205        int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
    11691206            ahci_interrupt, &ct);
     1207       
    11701208        if (rc != EOK) {
    1171                 ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
     1209                ddf_msg(LVL_ERROR, "Failed register_interrupt_handler function.");
    11721210                goto error_register_interrupt_handler;
    11731211        }
     
    11921230       
    11931231error_get_res_parsed:
     1232        fibril_timer_destroy(ahci->timer);
     1233       
     1234error_create_timer:
    11941235        free(ahci);
    11951236        return NULL;
     
    12081249        ccc.u32 = ahci->memregs->ghc.ccc_ctl;
    12091250        ccc.en = 0;
    1210         ahci->memregs->ghc.ccc_ctl = ccc.u32;
     1251        ahci->memregs->ghc.ccc_ctl = ccc.u32;   
    12111252       
    12121253        /* Set master latency timer. */
     
    12221263       
    12231264        /* 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; 
    12251266}
    12261267
     
    12491290        dev->driver_data = ahci;
    12501291       
    1251         /* Start AHCI hardware. */
     1292        /* Set timer and AHCI hardware start. */
     1293        fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
    12521294        ahci_ahci_hw_start(ahci);
    12531295       
  • uspace/drv/block/ahci/ahci.h

    r7deca26 r0b293a6  
    4848        volatile ahci_memregs_t *memregs;
    4949       
     50        /** AHCI device global timer. */
     51        fibril_timer_t *timer;
     52       
    5053        /** 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;
    5258} ahci_dev_t;
    5359
     
    5763        ahci_dev_t *ahci;
    5864       
    59         /** SATA port number (0-31). */
     65        /** SATA port number(0-31). */
    6066        uint8_t port_num;
     67       
     68        /** Port interrupt states shadow registers. */
     69        ahci_port_is_t shadow_pxis;
    6170       
    6271        /** Device in invalid state (disconnected and so on). */
     
    7584        fibril_mutex_t lock;
    7685       
     86        /** Mutex for port interrupt state register manipulation. */
     87        fibril_mutex_t pxis_lock;
     88       
    7789        /** Mutex for event signaling condition variable. */
    7890        fibril_mutex_t event_lock;
    79        
    8091        /** Event signaling condition variable. */
    8192        fibril_condvar_t event_condvar;
    8293       
    83         /** Event interrupt state. */
    84         ahci_port_is_t event_pxis;
    85        
    8694        /** Block device service id. */
    87         service_id_t service_id;
     95        service_id_t service_id; 
    8896       
    8997        /** Number of device data blocks. */
    9098        uint64_t blocks;
    91        
    9299        /** Size of device data blocks. */
    93100        size_t block_size;
  • uspace/drv/block/ahci/ahci_hw.h

    r7deca26 r0b293a6  
    374374} ahci_ghc_ghc_t;
    375375
     376/** AHCI GHC register offset. */
     377#define AHCI_GHC_GHC_REGISTER_OFFSET  1
     378
    376379/** AHCI Enable mask bit. */
    377380#define AHCI_GHC_GHC_AE  0x80000000
     
    381384
    382385/** AHCI Memory register Interrupt pending register. */
    383 typedef uint32_t ahci_ghc_is_t;
     386typedef 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;
    384392
    385393/** 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 
    396395
    397396/** AHCI Memory register Ports implemented. */
     
    532531        uint32_t ghc;
    533532        /** Interrupt Status */
    534         ahci_ghc_is_t is;
     533        uint32_t is;
    535534        /** Ports Implemented */
    536535        uint32_t pi;
     
    604603
    605604/** AHCI Memory register Port x Interrupt Status. */
    606 typedef uint32_t ahci_port_is_t;
     605typedef 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;
    607648
    608649#define AHCI_PORT_IS_DHRS  (1 << 0)
     
    659700static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is)
    660701{
    661         return port_is & AHCI_PORT_END_OF_OPERATION;
     702        return port_is.u32 & AHCI_PORT_END_OF_OPERATION;
    662703}
    663704
     
    671712static inline int ahci_port_is_error(ahci_port_is_t port_is)
    672713{
    673         return port_is & AHCI_PORT_IS_ERROR;
     714        return port_is.u32 & AHCI_PORT_IS_ERROR;
    674715}
    675716
     
    683724static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is)
    684725{
    685         return port_is & AHCI_PORT_IS_PERMANENT_ERROR;
     726        return port_is.u32 & AHCI_PORT_IS_PERMANENT_ERROR;
    686727}
    687728
     
    695736static inline int ahci_port_is_tfes(ahci_port_is_t port_is)
    696737{
    697         return port_is & AHCI_PORT_IS_TFES;
     738        return port_is.u32 & AHCI_PORT_IS_TFES;
    698739}
    699740
     
    953994        uint32_t pxfbu;
    954995        /** Port x Interrupt Status. */
    955         ahci_port_is_t pxis;
     996        uint32_t pxis;
    956997        /** Port x Interrupt Enable. */
    957998        uint32_t pxie;
     
    9891030        ahci_ghc_t ghc;
    9901031        /** Reserved. */
    991         uint32_t reserved[13];
     1032        uint32_t reserved[13]; 
    9921033        /** Reserved for NVMHCI. */
    9931034        uint32_t reservedfornvmhci[16];
     
    9951036        uint32_t vendorspecificsregs[24];
    9961037        /** Ports. */
    997         ahci_port_t ports[AHCI_MAX_PORTS];
     1038        ahci_port_t ports[32];
    9981039} ahci_memregs_t;
    9991040
  • uspace/drv/bus/usb/ohci/hc.c

    r7deca26 r0b293a6  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    2928/** @addtogroup drvusbohcihc
    3029 * @{
     
    3332 * @brief OHCI Host controller driver routines
    3433 */
    35 
    3634#include <errno.h>
    3735#include <str_error.h>
     
    5149static const irq_pio_range_t ohci_pio_ranges[] = {
    5250        {
    53                 .base = 0,
     51                .base = 0,      /* filled later */
    5452                .size = sizeof(ohci_regs_t)
    5553        }
     
    5755
    5856static 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 },
    8362};
    8463
     
    9776        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
    9877}
     78
    9979
    10080/** Get number of commands used in IRQ code.
     
    131111        ohci_regs_t *registers = (ohci_regs_t *) regs;
    132112        cmds[0].addr = (void *) &registers->interrupt_status;
     113        cmds[1].value = OHCI_USED_INTERRUPTS;
    133114        cmds[3].addr = (void *) &registers->interrupt_status;
    134115
     
    464445                return;
    465446        }
    466 
    467447        const unsigned hc_status = C_HCFS_GET(instance->registers->control);
    468448        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
  • uspace/drv/bus/usb/uhci/hc.c

    r7deca26 r0b293a6  
    5050static const irq_pio_range_t uhci_irq_pio_ranges[] = {
    5151        {
    52                 .base = 0,
     52                .base = 0,      /* filled later */
    5353                .size = sizeof(uhci_regs_t)
    5454        }
     
    5656
    5757static 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 },
    8264};
    8365
  • uspace/drv/char/i8042/i8042.c

    r7deca26 r0b293a6  
    120120        },
    121121        {
    122                 .cmd = CMD_AND,
     122                .cmd = CMD_BTEST,
    123123                .value = i8042_OUTPUT_FULL,
    124124                .srcarg = 1,
  • uspace/drv/nic/ne2k/ne2k.c

    r7deca26 r0b293a6  
    8383        {
    8484                /* Mask supported interrupt causes */
    85                 .cmd = CMD_AND,
     85                .cmd = CMD_BTEST,
    8686                .value = (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW |
    8787                    ISR_CNT | ISR_RDC),
  • uspace/srv/hid/input/port/ns16550.c

    r7deca26 r0b293a6  
    8484        },
    8585        {
    86                 .cmd = CMD_AND,
     86                .cmd = CMD_BTEST,
    8787                .value = LSR_DATA_READY,
    8888                .srcarg = 1,
  • uspace/srv/hid/input/port/pl050.c

    r7deca26 r0b293a6  
    8080        },
    8181        {
    82                 .cmd = CMD_AND,
     82                .cmd = CMD_BTEST,
    8383                .value = PL050_STAT_RXFULL,
    8484                .srcarg = 1,
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    r7deca26 r0b293a6  
    116116        {
    117117                .cmd = CMD_PIO_READ_8,
    118                 .addr = NULL,
     118                .addr = NULL,   /* will be patched in run-time */
    119119                .dstarg = 1
    120120        },
    121121        {
    122                 .cmd = CMD_AND,
     122                .cmd = CMD_BTEST,
    123123                .value = SR_INT,
    124124                .srcarg = 1,
Note: See TracChangeset for help on using the changeset viewer.