Subversion Repositories HelenOS

Rev

Rev 4531 | Rev 4545 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4531 Rev 4532
Line 74... Line 74...
74
static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
74
static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
75
static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, off_t size,
75
static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, off_t size,
76
    void *buf);
76
    void *buf);
77
static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
77
static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
78
    void *buf);
78
    void *buf);
-
 
79
static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
-
 
80
    const void *buf);
79
static int drive_identify(int drive_id, disk_t *d);
81
static int drive_identify(int drive_id, disk_t *d);
80
 
82
 
81
int main(int argc, char **argv)
83
int main(int argc, char **argv)
82
{
84
{
83
    uint8_t status;
85
    uint8_t status;
Line 304... Line 306...
304
            return EINVAL;
306
            return EINVAL;
305
 
307
 
306
        if (method == BD_READ_BLOCK)
308
        if (method == BD_READ_BLOCK)
307
            rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
309
            rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
308
        else
310
        else
309
            rc = ENOTSUP;
311
            rc = ata_bd_write_block(disk_id, blk_idx, 1, buf);
310
 
312
 
311
        if (rc != EOK)
313
        if (rc != EOK)
312
            return rc;
314
            return rc;
313
 
315
 
314
        buf += block_size;
316
        buf += block_size;
Line 376... Line 378...
376
    }
378
    }
377
 
379
 
378
    futex_up(&dev_futex);
380
    futex_up(&dev_futex);
379
    return EOK;
381
    return EOK;
380
}
382
}
-
 
383
 
-
 
384
static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
-
 
385
    const void *buf)
-
 
386
{
-
 
387
    size_t i;
-
 
388
    uint8_t status;
-
 
389
    uint64_t c, h, s;
-
 
390
    uint64_t idx;
-
 
391
    uint8_t drv_head;
-
 
392
    disk_t *d;
-
 
393
 
-
 
394
    d = &disk[disk_id];
-
 
395
 
-
 
396
    /* Check device bounds. */
-
 
397
    if (blk_idx >= d->blocks)
-
 
398
        return EINVAL;
-
 
399
 
-
 
400
    /* Compute CHS. */
-
 
401
    c = blk_idx / (d->heads * d->sectors);
-
 
402
    idx = blk_idx % (d->heads * d->sectors);
-
 
403
 
-
 
404
    h = idx / d->sectors;
-
 
405
    s = 1 + (idx % d->sectors);
-
 
406
 
-
 
407
    /* New value for Drive/Head register */
-
 
408
    drv_head =
-
 
409
        ((disk_id != 0) ? DHR_DRV : 0) |
-
 
410
        (h & 0x0f);
-
 
411
 
-
 
412
    futex_down(&dev_futex);
-
 
413
 
-
 
414
    /* Program a Read Sectors operation. */
-
 
415
 
-
 
416
    pio_write_8(&cmd->drive_head, drv_head);
-
 
417
    pio_write_8(&cmd->sector_count, 1);
-
 
418
    pio_write_8(&cmd->sector_number, s);
-
 
419
    pio_write_8(&cmd->cylinder_low, c & 0xff);
-
 
420
    pio_write_8(&cmd->cylinder_high, c >> 16);
-
 
421
    pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
-
 
422
 
-
 
423
    /* Write data to the disk buffer. */
-
 
424
 
-
 
425
    for (i = 0; i < block_size / 2; i++) {
-
 
426
        do {
-
 
427
            status = pio_read_8(&cmd->status);
-
 
428
        } while ((status & SR_DRDY) == 0);
-
 
429
 
-
 
430
        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
-
 
431
    }
-
 
432
 
-
 
433
    futex_up(&dev_futex);
-
 
434
    return EOK;
-
 
435
}
381
 
436
 
382
 
437
 
383
/**
438
/**
384
 * @}
439
 * @}
385
 */
440
 */