Changeset 0d247f5 in mainline


Ignore:
Timestamp:
2011-02-01T06:40:33Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb0eab1
Parents:
88743b5
Message:

Implement ATAPI read(12) command.

Location:
uspace/srv/bd/ata_bd
Files:
2 edited

Legend:

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

    r88743b5 r0d247f5  
    7474#define LEGACY_CTLS 4
    7575
    76 /** Physical block size. Should be always 512. */
    77 static const size_t block_size = 512;
     76/**
     77 * Size of data returned from Identify Device or Identify Packet Device
     78 * command.
     79 */
     80static const size_t identify_data_size = 512;
    7881
    7982/** Size of the communication area. */
     
    106109static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    107110    const void *buf);
    108 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
     111static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    109112    void *buf);
    110 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
     113static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
    111114    const void *buf);
    112115static int disk_init(disk_t *d, int disk_id);
     
    116119    void *obuf, size_t obuf_size);
    117120static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size);
     121static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
     122    void *obuf, size_t obuf_size);
    118123static void disk_print_summary(disk_t *d);
    119124static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
     
    323328                            IPC_GET_ARG2(call));
    324329                        cnt = IPC_GET_ARG3(call);
    325                         if (cnt * block_size > comm_size) {
     330                        if (cnt * disk[disk_id].block_size > comm_size) {
    326331                                retval = ELIMIT;
    327332                                break;
     
    333338                            IPC_GET_ARG2(call));
    334339                        cnt = IPC_GET_ARG3(call);
    335                         if (cnt * block_size > comm_size) {
     340                        if (cnt * disk[disk_id].block_size > comm_size) {
    336341                                retval = ELIMIT;
    337342                                break;
     
    340345                        break;
    341346                case BD_GET_BLOCK_SIZE:
    342                         ipc_answer_1(callid, EOK, block_size);
     347                        ipc_answer_1(callid, EOK, disk[disk_id].block_size);
    343348                        continue;
    344349                case BD_GET_NUM_BLOCKS:
     
    476481                if ((inq_buf[0] & 0x1f) != 0x05)
    477482                        printf("Warning: Peripheral device type is not CD-ROM.\n");
     483
     484                /* XXX Test some reading */
     485                uint8_t rdbuf[4096];
     486                rc = ata_pcmd_read_12(0, 0, 1, rdbuf, 4096);
     487                if (rc != EOK) {
     488                        printf("read(12) failed\n");
     489                } else {
     490                        printf("read(12) succeeded\n");
     491                }
     492
     493                /* Assume 2k block size for now. */
     494                d->block_size = 2048;
     495        } else {
     496                /* Assume register Read always uses 512-byte blocks. */
     497                d->block_size = 512;
    478498        }
    479499
     
    489509
    490510        while (cnt > 0) {
    491                 rc = ata_bd_read_block(disk_id, ba, 1, buf);
     511                if (disk[disk_id].dev_type == ata_reg_dev)
     512                        rc = ata_rcmd_read(disk_id, ba, 1, buf);
     513                else
     514                        rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
     515                            disk[disk_id].block_size);
     516
    492517                if (rc != EOK)
    493518                        return rc;
     
    495520                ++ba;
    496521                --cnt;
    497                 buf += block_size;
     522                buf += disk[disk_id].block_size;
    498523        }
    499524
     
    507532        int rc;
    508533
     534        if (disk[disk_id].dev_type != ata_reg_dev)
     535                return ENOTSUP;
     536
    509537        while (cnt > 0) {
    510                 rc = ata_bd_write_block(disk_id, ba, 1, buf);
     538                rc = ata_rcmd_write(disk_id, ba, 1, buf);
    511539                if (rc != EOK)
    512540                        return rc;
     
    514542                ++ba;
    515543                --cnt;
    516                 buf += block_size;
     544                buf += disk[disk_id].block_size;
    517545        }
    518546
     
    560588
    561589        if ((status & SR_DRQ) != 0) {
    562                 for (i = 0; i < block_size / 2; i++) {
     590                for (i = 0; i < identify_data_size / 2; i++) {
    563591                        data = pio_read_16(&cmd->data_port);
    564592                        ((uint16_t *) buf)[i] = data;
     
    607635
    608636        if ((status & SR_DRQ) != 0) {
    609                 for (i = 0; i < block_size / 2; i++) {
     637                for (i = 0; i < identify_data_size / 2; i++) {
    610638                        data = pio_read_16(&cmd->data_port);
    611639                        ((uint16_t *) buf)[i] = data;
     
    686714        data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +
    687715            ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);
     716        printf("data_size = %u\n", data_size);
    688717
    689718        /* Check whether data fits into output buffer. */
     
    734763}
    735764
     765static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
     766    void *obuf, size_t obuf_size)
     767{
     768        uint8_t cp[12];
     769        int rc;
     770
     771        if (ba > 0xffffffff)
     772                return EINVAL;
     773
     774        memset(cp, 0, 12);
     775        cp[0] = 0xa8; /* Read(12) */
     776        cp[2] = (ba >> 24) & 0xff;
     777        cp[3] = (ba >> 16) & 0xff;
     778        cp[4] = (ba >> 8) & 0xff;
     779        cp[5] = ba & 0xff;
     780
     781        cp[6] = (cnt >> 24) & 0xff;
     782        cp[7] = (cnt >> 16) & 0xff;
     783        cp[8] = (cnt >> 8) & 0xff;
     784        cp[9] = cnt & 0xff;
     785
     786        rc = ata_cmd_packet(0, cp, 12, obuf, obuf_size);
     787        if (rc != EOK)
     788                return rc;
     789
     790        return EOK;
     791}
     792
    736793/** Read a physical from the device.
    737794 *
     
    743800 * @return EOK on success, EIO on error.
    744801 */
    745 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
     802static int ata_rcmd_read(int disk_id, uint64_t ba, size_t blk_cnt,
    746803    void *buf)
    747804{
     
    798855                /* Read data from the device buffer. */
    799856
    800                 for (i = 0; i < block_size / 2; i++) {
     857                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    801858                        data = pio_read_16(&cmd->data_port);
    802859                        ((uint16_t *) buf)[i] = data;
     
    820877 * @return EOK on success, EIO on error.
    821878 */
    822 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
     879static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
    823880    const void *buf)
    824881{
     
    874931                /* Write data to the device buffer. */
    875932
    876                 for (i = 0; i < block_size / 2; i++) {
     933                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    877934                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    878935                }
  • uspace/srv/bd/ata_bd/ata_bd.h

    r88743b5 r0d247f5  
    111111
    112112        uint64_t blocks;
     113        size_t block_size;
    113114
    114115        char model[STR_BOUNDS(40) + 1];
Note: See TracChangeset for help on using the changeset viewer.