Changeset b50b5af2 in mainline for uspace


Ignore:
Timestamp:
2009-08-22T10:48:00Z (17 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04803bf
Parents:
1ea99cc (diff), a71c158 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace
Files:
1 added
37 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/app/trace/syscalls.c

    r1ea99cc rb50b5af2  
    6262    [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow",      3,      V_ERRNO },
    6363    [SYS_IPC_WAIT] = { "ipc_wait_for_call",             3,      V_HASH },
     64    [SYS_IPC_POKE] = { "ipc_poke",                      0,      V_ERRNO },
    6465    [SYS_IPC_HANGUP] = { "ipc_hangup",                  1,      V_ERRNO },
    6566    [SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq",      4,      V_ERRNO },
  • uspace/lib/libc/generic/async.c

    r1ea99cc rb50b5af2  
    106106
    107107atomic_t async_futex = FUTEX_INITIALIZER;
     108
     109/** Number of threads waiting for IPC in the kernel. */
     110atomic_t threads_in_ipc_wait = { 0 };
    108111
    109112/** Structures of this type represent a waiting fibril. */
     
    683686               
    684687                futex_up(&async_futex);
     688
     689                atomic_inc(&threads_in_ipc_wait);
    685690               
    686691                ipc_call_t call;
     
    688693                    SYNCH_FLAGS_NONE);
    689694               
     695                atomic_dec(&threads_in_ipc_wait);
     696
    690697                if (!callid) {
    691698                        handle_expired_timeouts();
  • uspace/lib/libc/generic/fibril_sync.c

    r1ea99cc rb50b5af2  
    4040#include <assert.h>
    4141
     42static void optimize_execution_power(void)
     43{
     44        /*
     45         * When waking up a worker fibril previously blocked in fibril
     46         * synchronization, chances are that there is an idle manager fibril
     47         * waiting for IPC, that could start executing the awakened worker
     48         * fibril right away. We try to detect this and bring the manager
     49         * fibril back to fruitful work.
     50         */
     51        if (atomic_get(&threads_in_ipc_wait) > 0)
     52                ipc_poke();
     53}
     54
    4255void fibril_mutex_initialize(fibril_mutex_t *fm)
    4356{
     
    8497                list_remove(&f->link);
    8598                fibril_add_ready((fid_t) f);
     99                optimize_execution_power();
    86100        }
    87101}
     
    152166                        fibril_add_ready((fid_t) f);
    153167                        frw->writers++;
     168                        optimize_execution_power();
    154169                        break;
    155170                } else {
     
    157172                        fibril_add_ready((fid_t) f);
    158173                        frw->readers++;
     174                        optimize_execution_power();
    159175                }
    160176        }
     
    200216                list_remove(&f->link);
    201217                fibril_add_ready((fid_t) f);
     218                optimize_execution_power();
    202219                if (once)
    203220                        break;
  • uspace/lib/libc/generic/io/printf_core.c

    r1ea99cc rb50b5af2  
    490490                counter += retval;
    491491       
    492         /* Print tailing spaces */
     492        /* Print trailing spaces */
    493493       
    494494        while (width-- > 0) {
  • uspace/lib/libc/generic/io/vsnprintf.c

    r1ea99cc rb50b5af2  
    100100        }
    101101       
    102         /* Buffer is big enought to print the whole string */
     102        /* Buffer is big enough to print the whole string */
    103103        memcpy((void *)(data->dst + data->len), (void *) str, size);
    104104        data->len += size;
  • uspace/lib/libc/generic/ipc.c

    r1ea99cc rb50b5af2  
    565565}
    566566
     567/** Interrupt one thread of this task from waiting for IPC. */
     568void ipc_poke(void)
     569{
     570        __SYSCALL0(SYS_IPC_POKE);
     571}
     572
    567573/** Ask destination to do a callback connection.
    568574 *
  • uspace/lib/libc/generic/malloc.c

    r1ea99cc rb50b5af2  
    392392                if (orig_size - real_size >= STRUCT_OVERHEAD) {
    393393                        /* Split the original block to a full block
    394                            and a tailing free block */
     394                           and a trailing free block */
    395395                        block_init((void *) head, real_size, false);
    396396                        block_init((void *) head + real_size,
  • uspace/lib/libc/generic/vfs/vfs.c

    r1ea99cc rb50b5af2  
    122122        int res;
    123123        ipcarg_t rc;
     124        ipcarg_t rc_orig;
    124125        aid_t req;
    125126        dev_handle_t dev_handle;
     
    141142        rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    142143        if (rc != EOK) {
    143                 async_wait_for(req, NULL);
     144                async_wait_for(req, &rc_orig);
    144145                async_serialize_end();
    145146                futex_up(&vfs_phone_futex);
    146147                free(mpa);
    147                 return (int) rc;
     148                if (rc_orig == EOK)
     149                        return (int) rc;
     150                else
     151                        return (int) rc_orig;
    148152        }
    149153       
    150154        rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    151155        if (rc != EOK) {
    152                 async_wait_for(req, NULL);
     156                async_wait_for(req, &rc_orig);
    153157                async_serialize_end();
    154158                futex_up(&vfs_phone_futex);
    155159                free(mpa);
    156                 return (int) rc;
     160                if (rc_orig == EOK)
     161                        return (int) rc;
     162                else
     163                        return (int) rc_orig;
    157164        }
    158165
    159166        rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    160167        if (rc != EOK) {
    161                 async_wait_for(req, NULL);
     168                async_wait_for(req, &rc_orig);
    162169                async_serialize_end();
    163170                futex_up(&vfs_phone_futex);
    164171                free(mpa);
    165                 return (int) rc;
     172                if (rc_orig == EOK)
     173                        return (int) rc;
     174                else
     175                        return (int) rc_orig;
    166176        }
    167177
     
    169179        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    170180        if (rc != EOK) {
    171                 async_wait_for(req, NULL);
     181                async_wait_for(req, &rc_orig);
    172182                async_serialize_end();
    173183                futex_up(&vfs_phone_futex);
    174184                free(mpa);
    175                 return (int) rc;
     185                if (rc_orig == EOK)
     186                        return (int) rc;
     187                else
     188                        return (int) rc_orig;
    176189        }
    177190       
     
    202215        rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    203216        if (rc != EOK) {
    204                 async_wait_for(req, NULL);
     217                ipcarg_t rc_orig;
     218       
     219                async_wait_for(req, &rc_orig);
    205220                async_serialize_end();
    206221                futex_up(&vfs_phone_futex);
    207222                free(pa);
    208                 return (int) rc;
     223                if (rc_orig == EOK)
     224                        return (int) rc;
     225                else
     226                        return (int) rc_orig;
    209227        }
    210228        async_wait_for(req, &rc);
     
    240258       
    241259        if (rc != EOK)
    242             return (int) rc;
     260                return (int) rc;
    243261       
    244262        return (int) IPC_GET_ARG1(answer);
     
    274292        rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
    275293        if (rc != EOK) {
    276                 async_wait_for(req, NULL);
    277                 async_serialize_end();
    278                 futex_up(&vfs_phone_futex);
    279                 return (ssize_t) rc;
     294                ipcarg_t rc_orig;
     295       
     296                async_wait_for(req, &rc_orig);
     297                async_serialize_end();
     298                futex_up(&vfs_phone_futex);
     299                if (rc_orig == EOK)
     300                        return (ssize_t) rc;
     301                else
     302                        return (ssize_t) rc_orig;
    280303        }
    281304        async_wait_for(req, &rc);
     
    301324        rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
    302325        if (rc != EOK) {
    303                 async_wait_for(req, NULL);
    304                 async_serialize_end();
    305                 futex_up(&vfs_phone_futex);
    306                 return (ssize_t) rc;
     326                ipcarg_t rc_orig;
     327       
     328                async_wait_for(req, &rc_orig);
     329                async_serialize_end();
     330                futex_up(&vfs_phone_futex);
     331                if (rc_orig == EOK)
     332                        return (ssize_t) rc;
     333                else
     334                        return (ssize_t) rc_orig;
    307335        }
    308336        async_wait_for(req, &rc);
     
    376404        rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
    377405        if (rc != EOK) {
    378                 async_wait_for(req, NULL);
    379                 async_serialize_end();
    380                 futex_up(&vfs_phone_futex);
    381                 return (ssize_t) rc;
     406                ipcarg_t rc_orig;
     407               
     408                async_wait_for(req, &rc_orig);
     409                async_serialize_end();
     410                futex_up(&vfs_phone_futex);
     411                if (rc_orig == EOK)
     412                        return (ssize_t) rc;
     413                else
     414                        return (ssize_t) rc_orig;
    382415        }
    383416        async_wait_for(req, &rc);
     
    391424{
    392425        ipcarg_t rc;
     426        ipcarg_t rc_orig;
    393427        aid_t req;
    394428       
     
    405439        rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    406440        if (rc != EOK) {
    407                 async_wait_for(req, NULL);
     441                async_wait_for(req, &rc_orig);
    408442                async_serialize_end();
    409443                futex_up(&vfs_phone_futex);
    410444                free(pa);
    411                 return (int) rc;
     445                if (rc_orig == EOK)
     446                        return (int) rc;
     447                else
     448                        return (int) rc_orig;
    412449        }
    413450        rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
    414451        if (rc != EOK) {
    415                 async_wait_for(req, NULL);
     452                async_wait_for(req, &rc_orig);
    416453                async_serialize_end();
    417454                futex_up(&vfs_phone_futex);
    418455                free(pa);
    419                 return (int) rc;
     456                if (rc_orig == EOK)
     457                        return (int) rc;
     458                else
     459                        return (int) rc_orig;
    420460        }
    421461        async_wait_for(req, &rc);
     
    476516        rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    477517        if (rc != EOK) {
    478                 async_wait_for(req, NULL);
     518                ipcarg_t rc_orig;
     519       
     520                async_wait_for(req, &rc_orig);
    479521                async_serialize_end();
    480522                futex_up(&vfs_phone_futex);
    481523                free(pa);
    482                 return (int) rc;
     524                if (rc_orig == EOK)
     525                        return (int) rc;
     526                else
     527                        return (int) rc_orig;
    483528        }
    484529        async_wait_for(req, &rc);
     
    506551        rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    507552        if (rc != EOK) {
    508                 async_wait_for(req, NULL);
     553                ipcarg_t rc_orig;
     554
     555                async_wait_for(req, &rc_orig);
    509556                async_serialize_end();
    510557                futex_up(&vfs_phone_futex);
    511558                free(pa);
    512                 return (int) rc;
     559                if (rc_orig == EOK)
     560                        return (int) rc;
     561                else
     562                        return (int) rc_orig;
    513563        }
    514564        async_wait_for(req, &rc);
     
    532582{
    533583        ipcarg_t rc;
     584        ipcarg_t rc_orig;
    534585        aid_t req;
    535586       
     
    553604        rc = ipc_data_write_start(vfs_phone, olda, olda_size);
    554605        if (rc != EOK) {
    555                 async_wait_for(req, NULL);
     606                async_wait_for(req, &rc_orig);
    556607                async_serialize_end();
    557608                futex_up(&vfs_phone_futex);
    558609                free(olda);
    559610                free(newa);
    560                 return (int) rc;
     611                if (rc_orig == EOK)
     612                        return (int) rc;
     613                else
     614                        return (int) rc_orig;
    561615        }
    562616        rc = ipc_data_write_start(vfs_phone, newa, newa_size);
    563617        if (rc != EOK) {
    564                 async_wait_for(req, NULL);
     618                async_wait_for(req, &rc_orig);
    565619                async_serialize_end();
    566620                futex_up(&vfs_phone_futex);
    567621                free(olda);
    568622                free(newa);
    569                 return (int) rc;
     623                if (rc_orig == EOK)
     624                        return (int) rc;
     625                else
     626                        return (int) rc_orig;
    570627        }
    571628        async_wait_for(req, &rc);
  • uspace/lib/libc/include/async.h

    r1ea99cc rb50b5af2  
    4747extern atomic_t async_futex;
    4848
     49extern atomic_t threads_in_ipc_wait;
     50
    4951extern int __async_init(void);
    5052extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
  • uspace/lib/libc/include/ipc/ipc.h

    r1ea99cc rb50b5af2  
    192192extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
    193193extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
     194extern void ipc_poke(void);
    194195
    195196static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
  • uspace/srv/bd/ata_bd/ata_bd.c

    r1ea99cc rb50b5af2  
    3636 *
    3737 * This driver currently works only with CHS addressing and uses PIO.
    38  * Currently based on the (now obsolete) ANSI X3.221-1994 (ATA-1) standard.
    39  * At this point only reading is possible, not writing.
     38 * Currently based on the (now obsolete) ATA-1, ATA-2 standards.
    4039 *
    4140 * The driver services a single controller which can have up to two disks
     
    6160#define NAME "ata_bd"
    6261
     62/** Physical block size. Should be always 512. */
    6363static const size_t block_size = 512;
     64
     65/** Size of the communication area. */
    6466static size_t comm_size;
    6567
     68/** I/O base address of the command registers. */
    6669static uintptr_t cmd_physical = 0x1f0;
     70/** I/O base address of the control registers. */
    6771static uintptr_t ctl_physical = 0x170;
     72
    6873static ata_cmd_t *cmd;
    6974static ata_ctl_t *ctl;
     
    8186    const void *buf);
    8287static int drive_identify(int drive_id, disk_t *d);
     88static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
     89    unsigned timeout);
    8390
    8491int main(int argc, char **argv)
    8592{
    86         uint8_t status;
    8793        char name[16];
    8894        int i, rc;
     
    96102                return -1;
    97103
    98         /* Put drives to reset, disable interrupts. */
    99         printf("Reset drives... ");
    100         fflush(stdout);
    101 
    102         pio_write_8(&ctl->device_control, DCR_SRST);
    103         /* FIXME: Find out how to do this properly. */
    104         async_usleep(100);
    105         pio_write_8(&ctl->device_control, 0);
    106 
    107         do {
    108                 status = pio_read_8(&cmd->status);
    109         } while ((status & SR_BSY) != 0);
    110         printf("Done\n");
    111 
    112         (void) drive_identify(0, &disk[0]);
    113         (void) drive_identify(1, &disk[1]);
     104        for (i = 0; i < MAX_DISKS; i++) {
     105                printf("Identify drive %d... ", i);
     106                fflush(stdout);
     107
     108                rc = drive_identify(i, &disk[i]);
     109
     110                if (rc == EOK) {
     111                        printf("%u cylinders, %u heads, %u sectors\n",
     112                            disk[i].cylinders, disk[i].heads, disk[i].sectors);
     113                } else {
     114                        printf("Not found.\n");
     115                }
     116        }
    114117
    115118        n_disks = 0;
     
    144147}
    145148
    146 static int drive_identify(int disk_id, disk_t *d)
    147 {
    148         uint16_t data;
    149         uint8_t status;
    150         size_t i;
    151 
    152         printf("Identify drive %d... ", disk_id);
    153         fflush(stdout);
    154 
    155         pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
    156         async_usleep(100);
    157         pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    158 
    159         status = pio_read_8(&cmd->status);
    160 
    161         d->present = false;
    162 
    163         /*
    164          * Detect if drive is present. This is Qemu only! Need to
    165          * do the right thing to work with real drives.
    166          */
    167         if ((status & SR_DRDY) == 0) {
    168                 printf("None attached.\n");
    169                 return ENOENT;
    170         }
    171 
    172         for (i = 0; i < block_size / 2; i++) {
    173                 do {
    174                         status = pio_read_8(&cmd->status);
    175                 } while ((status & SR_DRDY) == 0);
    176 
    177                 data = pio_read_16(&cmd->data_port);
    178 
    179                 switch (i) {
    180                 case 1: d->cylinders = data; break;
    181                 case 3: d->heads = data; break;
    182                 case 6: d->sectors = data; break;
    183                 }
    184         }
    185 
    186         d->blocks = d->cylinders * d->heads * d->sectors;
    187 
    188         printf("Geometry: %u cylinders, %u heads, %u sectors\n",
    189                 d->cylinders, d->heads, d->sectors);
    190 
    191         d->present = true;
    192         fibril_mutex_initialize(&d->lock);
    193 
    194         return EOK;
    195 }
    196 
     149
     150/** Register driver and enable device I/O. */
    197151static int ata_bd_init(void)
    198152{
     
    226180}
    227181
     182/** Block device connection handler */
    228183static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
    229184{
     
    296251}
    297252
     253/** Transfer a logical block from/to the device.
     254 *
     255 * @param disk_id       Device index (0 or 1)
     256 * @param method        @c BD_READ_BLOCK or @c BD_WRITE_BLOCK
     257 * @param blk_idx       Index of the first block.
     258 * @param size          Size of the logical block.
     259 * @param buf           Data buffer.
     260 *
     261 * @return EOK on success, EIO on error.
     262 */
    298263static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size,
    299264    void *buf)
     
    327292}
    328293
    329 
     294/** Issue IDENTIFY command.
     295 *
     296 * This is used to detect whether an ATA device is present and if so,
     297 * to determine its parameters. The parameters are written to @a d.
     298 *
     299 * @param disk_id       Device ID, 0 or 1.
     300 * @param d             Device structure to store parameters in.
     301 */
     302static int drive_identify(int disk_id, disk_t *d)
     303{
     304        uint16_t data;
     305        uint8_t status;
     306        uint8_t drv_head;
     307        size_t i;
     308
     309        drv_head = ((disk_id != 0) ? DHR_DRV : 0);
     310        d->present = false;
     311
     312        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     313                return EIO;
     314
     315        pio_write_8(&cmd->drive_head, drv_head);
     316
     317        /*
     318         * This is where we would most likely expect a non-existing device to
     319         * show up by not setting SR_DRDY.
     320         */
     321        if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     322                return EIO;
     323
     324        pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
     325
     326        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     327                return EIO;
     328
     329        /* Read data from the disk buffer. */
     330
     331        if ((status & SR_DRQ) != 0) {
     332//              for (i = 0; i < block_size / 2; i++) {
     333//                      data = pio_read_16(&cmd->data_port);
     334//                      ((uint16_t *) buf)[i] = data;
     335//              }
     336
     337                for (i = 0; i < block_size / 2; i++) {
     338                        data = pio_read_16(&cmd->data_port);
     339
     340                        switch (i) {
     341                        case 1: d->cylinders = data; break;
     342                        case 3: d->heads = data; break;
     343                        case 6: d->sectors = data; break;
     344                        }
     345                }
     346        }
     347
     348        if ((status & SR_ERR) != 0)
     349                return EIO;
     350
     351        d->blocks = d->cylinders * d->heads * d->sectors;
     352
     353        d->present = true;
     354        fibril_mutex_initialize(&d->lock);
     355
     356        return EOK;
     357}
     358
     359/** Read a physical from the device.
     360 *
     361 * @param disk_id       Device index (0 or 1)
     362 * @param blk_idx       Index of the first block.
     363 * @param blk_cnt       Number of blocks to transfer.
     364 * @param buf           Buffer for holding the data.
     365 *
     366 * @return EOK on success, EIO on error.
     367 */
    330368static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
    331369    void *buf)
     
    361399        /* Program a Read Sectors operation. */
    362400
     401        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     402                fibril_mutex_unlock(&d->lock);
     403                return EIO;
     404        }
     405
    363406        pio_write_8(&cmd->drive_head, drv_head);
     407
     408        if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     409                fibril_mutex_unlock(&d->lock);
     410                return EIO;
     411        }
     412
    364413        pio_write_8(&cmd->sector_count, 1);
    365414        pio_write_8(&cmd->sector_number, s);
    366415        pio_write_8(&cmd->cylinder_low, c & 0xff);
    367416        pio_write_8(&cmd->cylinder_high, c >> 16);
     417
    368418        pio_write_8(&cmd->command, CMD_READ_SECTORS);
    369419
    370         /* Read data from the disk buffer. */
    371 
    372         for (i = 0; i < block_size / 2; i++) {
    373                 do {
    374                         status = pio_read_8(&cmd->status);
    375                 } while ((status & SR_DRDY) == 0);
    376 
    377                 data = pio_read_16(&cmd->data_port);
    378                 ((uint16_t *) buf)[i] = data;
    379         }
     420        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     421                fibril_mutex_unlock(&d->lock);
     422                return EIO;
     423        }
     424
     425        if ((status & SR_DRQ) != 0) {
     426                /* Read data from the device buffer. */
     427
     428                for (i = 0; i < block_size / 2; i++) {
     429                        data = pio_read_16(&cmd->data_port);
     430                        ((uint16_t *) buf)[i] = data;
     431                }
     432        }
     433
     434        if ((status & SR_ERR) != 0)
     435                return EIO;
    380436
    381437        fibril_mutex_unlock(&d->lock);
     
    383439}
    384440
     441/** Write a physical block to the device.
     442 *
     443 * @param disk_id       Device index (0 or 1)
     444 * @param blk_idx       Index of the first block.
     445 * @param blk_cnt       Number of blocks to transfer.
     446 * @param buf           Buffer holding the data to write.
     447 *
     448 * @return EOK on success, EIO on error.
     449 */
    385450static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
    386451    const void *buf)
     
    413478        fibril_mutex_lock(&d->lock);
    414479
    415         /* Program a Read Sectors operation. */
     480        /* Program a Write Sectors operation. */
     481
     482        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     483                fibril_mutex_unlock(&d->lock);
     484                return EIO;
     485        }
    416486
    417487        pio_write_8(&cmd->drive_head, drv_head);
     488
     489        if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     490                fibril_mutex_unlock(&d->lock);
     491                return EIO;
     492        }
     493
    418494        pio_write_8(&cmd->sector_count, 1);
    419495        pio_write_8(&cmd->sector_number, s);
    420496        pio_write_8(&cmd->cylinder_low, c & 0xff);
    421497        pio_write_8(&cmd->cylinder_high, c >> 16);
     498
    422499        pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
    423500
    424         /* Write data to the disk buffer. */
    425 
    426         for (i = 0; i < block_size / 2; i++) {
    427                 do {
    428                         status = pio_read_8(&cmd->status);
    429                 } while ((status & SR_DRDY) == 0);
    430 
    431                 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
     501        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     502                fibril_mutex_unlock(&d->lock);
     503                return EIO;
     504        }
     505
     506        if ((status & SR_DRQ) != 0) {
     507                /* Write data to the device buffer. */
     508
     509                for (i = 0; i < block_size / 2; i++) {
     510                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
     511                }
    432512        }
    433513
    434514        fibril_mutex_unlock(&d->lock);
     515
     516        if (status & SR_ERR)
     517                return EIO;
     518
    435519        return EOK;
    436520}
    437521
     522/** Wait until some status bits are set and some are reset.
     523 *
     524 * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become
     525 * set and SR_BSY to become reset.
     526 *
     527 * @param set           Combination if bits which must be all set.
     528 * @param n_reset       Negated combination of bits which must be all reset.
     529 * @param pstatus       Pointer where to store last read status or NULL.
     530 * @param timeout       Timeout in 10ms units.
     531 *
     532 * @return              EOK on success, EIO on timeout.
     533 */
     534static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
     535    unsigned timeout)
     536{
     537        uint8_t status;
     538        int cnt;
     539
     540        status = pio_read_8(&cmd->status);
     541
     542        /*
     543         * This is crude, yet simple. First try with 1us delays
     544         * (most likely the device will respond very fast). If not,
     545         * start trying every 10 ms.
     546         */
     547
     548        cnt = 100;
     549        while ((status & ~n_reset) != 0 || (status & set) != set) {
     550                async_usleep(1);
     551                --cnt;
     552                if (cnt <= 0) break;
     553
     554                status = pio_read_8(&cmd->status);
     555        }
     556
     557        cnt = timeout;
     558        while ((status & ~n_reset) != 0 || (status & set) != set) {
     559                async_usleep(10000);
     560                --cnt;
     561                if (cnt <= 0) break;
     562
     563                status = pio_read_8(&cmd->status);
     564        }
     565
     566        if (pstatus)
     567                *pstatus = status;
     568
     569        if (cnt == 0)
     570                return EIO;
     571
     572        return EOK;
     573}
    438574
    439575/**
  • uspace/srv/bd/ata_bd/ata_bd.h

    r1ea99cc rb50b5af2  
    135135};
    136136
     137/** Timeout definitions. Unit is 10 ms. */
     138enum ata_timeout {
     139        TIMEOUT_PROBE   =  100, /*  1 s */
     140        TIMEOUT_BSY     =  100, /*  1 s */
     141        TIMEOUT_DRDY    = 1000  /* 10 s */
     142};
     143
    137144typedef struct {
    138145        bool present;
  • uspace/srv/console/Makefile

    r1ea99cc rb50b5af2  
    3535include $(LIBC_PREFIX)/Makefile.toolchain
    3636
    37 CFLAGS += -I. -I../kbd/include -I../fb
     37CFLAGS += -I.
    3838
    3939LIBS = $(LIBC_PREFIX)/libc.a
     
    4747        console.c \
    4848        screenbuffer.c \
    49         ../kbd/generic/keybuffer.c \
     49        keybuffer.c \
    5050        gcons.c
    5151
  • uspace/srv/console/console.c

    r1ea99cc rb50b5af2  
    3434
    3535#include <libc.h>
    36 #include <fb.h>
    3736#include <ipc/ipc.h>
    38 #include <kbd.h>
     37#include <ipc/kbd.h>
    3938#include <io/keycode.h>
    4039#include <ipc/fb.h>
  • uspace/srv/fs/fat/fat_fat.c

    r1ea99cc rb50b5af2  
    451451}
    452452
     453void
     454fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c)
     455{
     456        int i;
     457        block_t *b;
     458        unsigned bps;
     459
     460        bps = uint16_t_le2host(bs->bps);
     461       
     462        for (i = 0; i < bs->spc; i++) {
     463                b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD);
     464                memset(b->data, 0, bps);
     465                b->dirty = true;
     466                block_put(b);
     467        }
     468}
     469
    453470/**
    454471 * @}
  • uspace/srv/fs/fat/fat_fat.h

    r1ea99cc rb50b5af2  
    8484extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
    8585    off_t);
     86extern void fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
    8687
    8788#endif
  • uspace/srv/fs/fat/fat_ops.c

    r1ea99cc rb50b5af2  
    332332        /* idxp->lock held */
    333333        if (flags & L_DIRECTORY) {
    334                 int i;
    335                 block_t *b;
    336 
    337                 /*
    338                  * Populate the new cluster with unused dentries.
    339                  */
    340                 for (i = 0; i < bs->spc; i++) {
    341                         b = _fat_block_get(bs, dev_handle, mcl, i,
    342                             BLOCK_FLAGS_NOREAD);
    343                         /* mark all dentries as never-used */
    344                         memset(b->data, 0, bps);
    345                         b->dirty = false;
    346                         block_put(b);
    347                 }
     334                /* Populate the new cluster with unused dentries. */
     335                fat_zero_cluster(bs, dev_handle, mcl);
    348336                nodep->type = FAT_DIRECTORY;
    349337                nodep->firstc = mcl;
     
    462450         * We need to grow the parent in order to create a new unused dentry.
    463451         */
    464         if (parentp->idx->pfc == FAT_CLST_ROOT) {
     452        if (parentp->firstc == FAT_CLST_ROOT) {
    465453                /* Can't grow the root directory. */
    466454                fibril_mutex_unlock(&parentp->idx->lock);
     
    472460                return rc;
    473461        }
     462        fat_zero_cluster(bs, parentp->idx->dev_handle, mcl);
    474463        fat_append_clusters(bs, parentp, mcl);
    475         b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NOREAD);
     464        parentp->size += bps * bs->spc;
     465        parentp->dirty = true;          /* need to sync node */
     466        b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
    476467        d = (fat_dentry_t *)b->data;
    477         /*
    478          * Clear all dentries in the block except for the first one (the first
    479          * dentry will be cleared in the next step).
    480          */
    481         memset(d + 1, 0, bps - sizeof(fat_dentry_t));
    482468
    483469hit:
  • uspace/srv/kbd/Makefile

    r1ea99cc rb50b5af2  
    4545        generic/kbd.c \
    4646        genarch/gsp.c \
    47         genarch/stroke.c \
    48         generic/keybuffer.c
     47        genarch/stroke.c
    4948
    5049ARCH_SOURCES =
  • uspace/srv/kbd/ctl/gxe_fb.c

    r1ea99cc rb50b5af2  
    225225}
    226226
     227void kbd_ctl_set_ind(unsigned mods)
     228{
     229        (void) mods;
     230}
     231
    227232/**
    228233 * @}
  • uspace/srv/kbd/ctl/pc.c

    r1ea99cc rb50b5af2  
    4040#include <io/keycode.h>
    4141#include <kbd_ctl.h>
     42#include <kbd_port.h>
    4243#include <gsp.h>
    4344
     
    4546        ds_s,
    4647        ds_e
     48};
     49
     50enum special_code {
     51        SC_ACK = 0xfa,
     52        SC_NAK = 0xfe
     53};
     54
     55enum lock_ind_bits {
     56        LI_SCROLL       = 0x01,
     57        LI_NUM          = 0x02,
     58        LI_CAPS         = 0x04
     59};
     60
     61enum kbd_command {
     62        KBD_CMD_SET_LEDS = 0xed
    4763};
    4864
     
    194210        size_t map_length;
    195211
     212        /*
     213         * ACK/NAK are returned as response to us sending a command.
     214         * We are not interested in them.
     215         */
     216        if (scancode == SC_ACK || scancode == SC_NAK)
     217                return;
     218
    196219        if (scancode == 0xe0) {
    197220                ds = ds_e;
     
    230253}
    231254
     255void kbd_ctl_set_ind(unsigned mods)
     256{
     257        uint8_t b;
     258
     259        b = 0;
     260        if ((mods & KM_CAPS_LOCK) != 0)
     261                b = b | LI_CAPS;
     262        if ((mods & KM_NUM_LOCK) != 0)
     263                b = b | LI_NUM;
     264        if ((mods & KM_SCROLL_LOCK) != 0)
     265                b = b | LI_SCROLL;
     266
     267        kbd_port_write(KBD_CMD_SET_LEDS);
     268        kbd_port_write(b);
     269}
     270
    232271/**
    233272 * @}
  • uspace/srv/kbd/ctl/pl050.c

    r1ea99cc rb50b5af2  
    258258}
    259259
     260void kbd_ctl_set_ind(unsigned mods)
     261{
     262        (void) mods;
     263}
     264
    260265/**
    261266 * @}
  • uspace/srv/kbd/ctl/stty.c

    r1ea99cc rb50b5af2  
    224224}
    225225
     226void kbd_ctl_set_ind(unsigned mods)
     227{
     228        (void) mods;
     229}
     230
    226231/**
    227232 * @}
  • uspace/srv/kbd/ctl/sun.c

    r1ea99cc rb50b5af2  
    7272        if (key != 0)
    7373                kbd_push_ev(type, key);
     74}
     75
     76void kbd_ctl_set_ind(unsigned mods)
     77{
     78        (void) mods;
    7479}
    7580
  • uspace/srv/kbd/generic/kbd.c

    r1ea99cc rb50b5af2  
    3838#include <ipc/ipc.h>
    3939#include <ipc/services.h>
     40#include <ipc/kbd.h>
    4041#include <sysinfo.h>
    4142#include <stdio.h>
     
    5152
    5253#include <kbd.h>
    53 #include <keybuffer.h>
    5454#include <kbd_port.h>
    5555#include <kbd_ctl.h>
     
    6060int cons_connected = 0;
    6161int phone2cons = -1;
    62 keybuffer_t keybuffer;
    6362
    6463/** Currently active modifiers. */
     
    125124                        mods = mods ^ (mod_mask & ~lock_keys);
    126125                        lock_keys = lock_keys | mod_mask;
     126
     127                        /* Update keyboard lock indicator lights. */
     128                        kbd_ctl_set_ind(mods);
    127129                } else {
    128130                        lock_keys = lock_keys & ~mod_mask;
     
    239241        layout[active_layout]->reset();
    240242       
    241         /* Initialize key buffer */
    242         keybuffer_init(&keybuffer);
    243        
    244243        async_set_client_connection(console_connection);
    245244
  • uspace/srv/kbd/include/kbd.h

    r1ea99cc rb50b5af2  
    3838#define KBD_KBD_H_
    3939
    40 #include <keybuffer.h>
    41 #include <ipc/ipc.h>
    42 
    43 #define KBD_EVENT      1024
    44 #define KBD_MS_LEFT    1025
    45 #define KBD_MS_RIGHT   1026
    46 #define KBD_MS_MIDDLE  1027
    47 #define KBD_MS_MOVE    1028
    48 
    49 typedef enum {
    50         KBD_YIELD = IPC_FIRST_USER_METHOD,
    51         KBD_RECLAIM
    52 } kbd_request_t;
    53 
    5440extern int cir_service;
    5541extern int cir_phone;
  • uspace/srv/kbd/include/kbd_ctl.h

    r1ea99cc rb50b5af2  
    4040extern void kbd_ctl_parse_scancode(int);
    4141extern int kbd_ctl_init(void);
    42 
     42extern void kbd_ctl_set_ind(unsigned);
    4343
    4444#endif
  • uspace/srv/kbd/include/kbd_port.h

    r1ea99cc rb50b5af2  
    3838#define KBD_PORT_H_
    3939
     40#include <sys/types.h>
     41
    4042extern int kbd_port_init(void);
    4143extern void kbd_port_yield(void);
    4244extern void kbd_port_reclaim(void);
     45extern void kbd_port_write(uint8_t);
    4346
    4447#endif
  • uspace/srv/kbd/port/dummy.c

    r1ea99cc rb50b5af2  
    5151}
    5252
     53void kbd_port_write(uint8_t data)
     54{
     55        (void) data;
     56}
     57
    5358/** @}
    5459*/
  • uspace/srv/kbd/port/gxemul.c

    r1ea99cc rb50b5af2  
    7878}
    7979
     80void kbd_port_write(uint8_t data)
     81{
     82        (void) data;
     83}
     84
    8085/** Process data sent when a key is pressed.
    8186 * 
  • uspace/srv/kbd/port/i8042.c

    r1ea99cc rb50b5af2  
    160160}
    161161
     162void kbd_port_write(uint8_t data)
     163{
     164        pio_write_8(&i8042->data, data);
     165        wait_ready();
     166}
     167
    162168static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
    163169{
  • uspace/srv/kbd/port/msim.c

    r1ea99cc rb50b5af2  
    7878}
    7979
     80void kbd_port_write(uint8_t data)
     81{
     82        (void) data;
     83}
     84
    8085static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
    8186{
  • uspace/srv/kbd/port/pl050.c

    r1ea99cc rb50b5af2  
    102102}
    103103
     104void kbd_port_write(uint8_t data)
     105{
     106        (void) data;
     107}
     108
    104109static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
    105110{
  • uspace/srv/kbd/port/sgcn.c

    r1ea99cc rb50b5af2  
    133133}
    134134
     135void kbd_port_write(uint8_t data)
     136{
     137        (void) data;
     138}
     139
    135140/**
    136141 * Handler of the "key pressed" event. Reads codes of all the pressed keys from
  • uspace/srv/kbd/port/ski.c

    r1ea99cc rb50b5af2  
    7878}
    7979
     80void kbd_port_write(uint8_t data)
     81{
     82        (void) data;
     83}
     84
    8085/** Thread to poll Ski for keypresses. */
    8186static void *ski_thread_impl(void *arg)
  • uspace/srv/kbd/port/sun.c

    r1ea99cc rb50b5af2  
    7171}
    7272
     73void kbd_port_write(uint8_t data)
     74{
     75        (void) data;
     76}
     77
    7378/** @}
    7479*/
  • uspace/srv/ns/task.h

    r1ea99cc rb50b5af2  
    3535
    3636#include <ipc/ipc.h>
    37 #include <event.h>
    3837
    3938extern int task_init(void);
    4039extern void process_pending_wait(void);
    4140
    42 extern void wait_notification(wait_type_t et, task_id_t id);
    4341extern void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid);
    4442
  • uspace/srv/vfs/vfs_node.c

    r1ea99cc rb50b5af2  
    188188        }
    189189
    190         assert(node->size == result->size);
     190        assert(node->size == result->size || node->type != VFS_NODE_FILE);
    191191        assert(node->lnkcnt == result->lnkcnt);
    192192        assert(node->type == result->type || result->type == VFS_NODE_UNKNOWN);
Note: See TracChangeset for help on using the changeset viewer.