Changeset f6b5593 in mainline for uspace/srv/bd/ata_bd/ata_bd.c


Ignore:
Timestamp:
2009-09-21T11:53:03Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4098e38
Parents:
2f636b6 (diff), c1618ed (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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r2f636b6 rf6b5593  
    6262#include <bool.h>
    6363#include <task.h>
     64#include <macros.h>
    6465
    6566#include "ata_bd.h"
     
    8687static int ata_bd_init(void);
    8788static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
    88 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
     89static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    8990    void *buf);
    90 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     91static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     92    const void *buf);
     93static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
    9194    void *buf);
    92 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     95static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
    9396    const void *buf);
    9497static int disk_init(disk_t *d, int disk_id);
    9598static int drive_identify(int drive_id, void *buf);
    9699static void disk_print_summary(disk_t *d);
    97 static int coord_calc(disk_t *d, uint64_t blk_idx, block_coord_t *bc);
     100static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
    98101static void coord_sc_program(const block_coord_t *bc, uint16_t scnt);
    99102static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
     
    228231        int flags;
    229232        int retval;
    230         off_t idx;
    231         size_t size;
     233        uint64_t ba;
     234        size_t cnt;
    232235        int disk_id, i;
    233236
     
    270273                        ipc_answer_0(callid, EOK);
    271274                        return;
    272                 case BD_READ_BLOCK:
    273                 case BD_WRITE_BLOCK:
    274                         idx = IPC_GET_ARG1(call);
    275                         size = IPC_GET_ARG2(call);
    276                         if (size > comm_size) {
    277                                 retval = EINVAL;
     275                case BD_READ_BLOCKS:
     276                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     277                            IPC_GET_ARG2(call));
     278                        cnt = IPC_GET_ARG3(call);
     279                        if (cnt * block_size > comm_size) {
     280                                retval = ELIMIT;
    278281                                break;
    279282                        }
    280                         retval = ata_bd_rdwr(disk_id, method, idx,
    281                             size, fs_va);
     283                        retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va);
    282284                        break;
     285                case BD_WRITE_BLOCKS:
     286                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     287                            IPC_GET_ARG2(call));
     288                        cnt = IPC_GET_ARG3(call);
     289                        if (cnt * block_size > comm_size) {
     290                                retval = ELIMIT;
     291                                break;
     292                        }
     293                        retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va);
     294                        break;
     295                case BD_GET_BLOCK_SIZE:
     296                        ipc_answer_1(callid, EOK, block_size);
     297                        continue;
    283298                default:
    284299                        retval = EINVAL;
     
    373388}
    374389
    375 /** Transfer a logical block from/to the device.
    376  *
    377  * @param disk_id       Device index (0 or 1)
    378  * @param method        @c BD_READ_BLOCK or @c BD_WRITE_BLOCK
    379  * @param blk_idx       Index of the first block.
    380  * @param size          Size of the logical block.
    381  * @param buf           Data buffer.
    382  *
    383  * @return EOK on success, EIO on error.
    384  */
    385 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size,
    386     void *buf)
    387 {
     390/** Read multiple blocks from the device. */
     391static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     392    void *buf) {
     393
    388394        int rc;
    389         size_t now;
    390 
    391         while (size > 0) {
    392                 now = size < block_size ? size : block_size;
    393                 if (now != block_size)
    394                         return EINVAL;
    395 
    396                 if (method == BD_READ_BLOCK)
    397                         rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
    398                 else
    399                         rc = ata_bd_write_block(disk_id, blk_idx, 1, buf);
    400 
     395
     396        while (cnt > 0) {
     397                rc = ata_bd_read_block(disk_id, ba, 1, buf);
    401398                if (rc != EOK)
    402399                        return rc;
    403400
     401                ++ba;
     402                --cnt;
    404403                buf += block_size;
    405                 blk_idx++;
    406 
    407                 if (size > block_size)
    408                         size -= block_size;
    409                 else
    410                         size = 0;
     404        }
     405
     406        return EOK;
     407}
     408
     409/** Write multiple blocks to the device. */
     410static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     411    const void *buf) {
     412
     413        int rc;
     414
     415        while (cnt > 0) {
     416                rc = ata_bd_write_block(disk_id, ba, 1, buf);
     417                if (rc != EOK)
     418                        return rc;
     419
     420                ++ba;
     421                --cnt;
     422                buf += block_size;
    411423        }
    412424
     
    466478 *
    467479 * @param disk_id       Device index (0 or 1)
    468  * @param blk_idx       Index of the first block.
    469  * @param blk_cnt       Number of blocks to transfer.
     480 * @param ba            Address the first block.
     481 * @param cnt           Number of blocks to transfer.
    470482 * @param buf           Buffer for holding the data.
    471483 *
    472484 * @return EOK on success, EIO on error.
    473485 */
    474 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     486static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
    475487    void *buf)
    476488{
     
    486498
    487499        /* Compute block coordinates. */
    488         if (coord_calc(d, blk_idx, &bc) != EOK)
     500        if (coord_calc(d, ba, &bc) != EOK)
    489501                return EINVAL;
    490502
     
    541553 *
    542554 * @param disk_id       Device index (0 or 1)
    543  * @param blk_idx       Index of the first block.
    544  * @param blk_cnt       Number of blocks to transfer.
     555 * @param ba            Address of the first block.
     556 * @param cnt           Number of blocks to transfer.
    545557 * @param buf           Buffer holding the data to write.
    546558 *
    547559 * @return EOK on success, EIO on error.
    548560 */
    549 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     561static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
    550562    const void *buf)
    551563{
     
    560572
    561573        /* Compute block coordinates. */
    562         if (coord_calc(d, blk_idx, &bc) != EOK)
     574        if (coord_calc(d, ba, &bc) != EOK)
    563575                return EINVAL;
    564576
     
    620632 * @return EOK on success or EINVAL if block index is past end of device.
    621633 */
    622 static int coord_calc(disk_t *d, uint64_t blk_idx, block_coord_t *bc)
     634static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc)
    623635{
    624636        uint64_t c;
     
    626638
    627639        /* Check device bounds. */
    628         if (blk_idx >= d->blocks)
     640        if (ba >= d->blocks)
    629641                return EINVAL;
    630642
     
    634646        case am_chs:
    635647                /* Compute CHS coordinates. */
    636                 c = blk_idx / (d->geom.heads * d->geom.sectors);
    637                 idx = blk_idx % (d->geom.heads * d->geom.sectors);
     648                c = ba / (d->geom.heads * d->geom.sectors);
     649                idx = ba % (d->geom.heads * d->geom.sectors);
    638650
    639651                bc->cyl_lo = c & 0xff;
     
    645657        case am_lba28:
    646658                /* Compute LBA-28 coordinates. */
    647                 bc->c0 = blk_idx & 0xff;                /* bits 0-7 */
    648                 bc->c1 = (blk_idx >> 8) & 0xff;         /* bits 8-15 */
    649                 bc->c2 = (blk_idx >> 16) & 0xff;        /* bits 16-23 */
    650                 bc->h  = (blk_idx >> 24) & 0x0f;        /* bits 24-27 */
     659                bc->c0 = ba & 0xff;             /* bits 0-7 */
     660                bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
     661                bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
     662                bc->h  = (ba >> 24) & 0x0f;     /* bits 24-27 */
    651663                break;
    652664
    653665        case am_lba48:
    654666                /* Compute LBA-48 coordinates. */
    655                 bc->c0 = blk_idx & 0xff;                /* bits 0-7 */
    656                 bc->c1 = (blk_idx >> 8) & 0xff;         /* bits 8-15 */
    657                 bc->c2 = (blk_idx >> 16) & 0xff;        /* bits 16-23 */
    658                 bc->c3 = (blk_idx >> 24) & 0xff;        /* bits 24-31 */
    659                 bc->c4 = (blk_idx >> 32) & 0xff;        /* bits 32-39 */
    660                 bc->c5 = (blk_idx >> 40) & 0xff;        /* bits 40-47 */
     667                bc->c0 = ba & 0xff;             /* bits 0-7 */
     668                bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
     669                bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
     670                bc->c3 = (ba >> 24) & 0xff;     /* bits 24-31 */
     671                bc->c4 = (ba >> 32) & 0xff;     /* bits 32-39 */
     672                bc->c5 = (ba >> 40) & 0xff;     /* bits 40-47 */
    661673                bc->h  = 0;
    662674                break;
Note: See TracChangeset for help on using the changeset viewer.