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


Ignore:
Timestamp:
2011-05-12T16:49:44Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f36787d7
Parents:
e80329d6 (diff), 750636a (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

    re80329d6 rb5e68c8  
    5151#include <libarch/ddi.h>
    5252#include <ddi.h>
    53 #include <ipc/ipc.h>
    5453#include <ipc/bd.h>
    5554#include <async.h>
    5655#include <as.h>
    5756#include <fibril_synch.h>
     57#include <stdint.h>
    5858#include <str.h>
    5959#include <devmap.h>
     
    6262#include <errno.h>
    6363#include <bool.h>
     64#include <byteorder.h>
    6465#include <task.h>
    6566#include <macros.h>
    6667
     68#include "ata_hw.h"
    6769#include "ata_bd.h"
    6870
     
    7072#define NAMESPACE  "bd"
    7173
    72 /** Physical block size. Should be always 512. */
    73 static const size_t block_size = 512;
     74/** Number of defined legacy controller base addresses. */
     75#define LEGACY_CTLS 4
     76
     77/**
     78 * Size of data returned from Identify Device or Identify Packet Device
     79 * command.
     80 */
     81static const size_t identify_data_size = 512;
    7482
    7583/** Size of the communication area. */
     
    7785
    7886/** I/O base address of the command registers. */
    79 static uintptr_t cmd_physical = 0x1f0;
     87static uintptr_t cmd_physical;
    8088/** I/O base address of the control registers. */
    81 static uintptr_t ctl_physical = 0x170;
     89static uintptr_t ctl_physical;
     90
     91/** I/O base addresses for legacy (ISA-compatible) controllers. */
     92static ata_base_t legacy_base[LEGACY_CTLS] = {
     93        { 0x1f0, 0x3f0 },
     94        { 0x170, 0x370 },
     95        { 0x1e8, 0x3e8 },
     96        { 0x168, 0x368 }
     97};
    8298
    8399static ata_cmd_t *cmd;
     
    87103static disk_t disk[MAX_DISKS];
    88104
     105static void print_syntax(void);
    89106static int ata_bd_init(void);
    90107static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
     
    93110static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    94111    const void *buf);
    95 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
     112static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    96113    void *buf);
    97 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
     114static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
    98115    const void *buf);
    99116static int disk_init(disk_t *d, int disk_id);
    100117static int drive_identify(int drive_id, void *buf);
     118static int identify_pkt_dev(int dev_idx, void *buf);
     119static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size,
     120    void *obuf, size_t obuf_size);
     121static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size);
     122static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
     123    void *obuf, size_t obuf_size);
    101124static void disk_print_summary(disk_t *d);
    102125static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
     
    110133        int i, rc;
    111134        int n_disks;
     135        unsigned ctl_num;
     136        char *eptr;
    112137
    113138        printf(NAME ": ATA disk driver\n");
    114139
    115         printf("I/O address %p/%p\n", ctl_physical, cmd_physical);
     140        if (argc > 1) {
     141                ctl_num = strtoul(argv[1], &eptr, 0);
     142                if (*eptr != '\0' || ctl_num == 0 || ctl_num > 4) {
     143                        printf("Invalid argument.\n");
     144                        print_syntax();
     145                        return -1;
     146                }
     147        } else {
     148                ctl_num = 1;
     149        }
     150
     151        cmd_physical = legacy_base[ctl_num - 1].cmd;
     152        ctl_physical = legacy_base[ctl_num - 1].ctl;
     153
     154        printf("I/O address %p/%p\n", (void *) cmd_physical,
     155            (void *) ctl_physical);
    116156
    117157        if (ata_bd_init() != EOK)
     
    138178                        continue;
    139179               
    140                 snprintf(name, 16, "%s/disk%d", NAMESPACE, i);
    141                 rc = devmap_device_register(name, &disk[i].dev_handle);
     180                snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
     181                rc = devmap_device_register(name, &disk[i].devmap_handle);
    142182                if (rc != EOK) {
    143                         devmap_hangup_phone(DEVMAP_DRIVER);
    144183                        printf(NAME ": Unable to register device %s.\n", name);
    145184                        return rc;
     
    161200}
    162201
     202
     203static void print_syntax(void)
     204{
     205        printf("Syntax: " NAME " <controller_number>\n");
     206        printf("Controller number = 1..4\n");
     207}
     208
    163209/** Print one-line device summary. */
    164210static void disk_print_summary(disk_t *d)
     
    168214        printf("%s: ", d->model);
    169215
    170         switch (d->amode) {
    171         case am_chs:
    172                 printf("CHS %u cylinders, %u heads, %u sectors",
    173                     disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
    174                 break;
    175         case am_lba28:
    176                 printf("LBA-28");
    177                 break;
    178         case am_lba48:
    179                 printf("LBA-48");
    180                 break;
    181         }
    182 
    183         printf(" %" PRIu64 " blocks", d->blocks, d->blocks / (2 * 1024));
     216        if (d->dev_type == ata_reg_dev) {
     217                switch (d->amode) {
     218                case am_chs:
     219                        printf("CHS %u cylinders, %u heads, %u sectors",
     220                            disk->geom.cylinders, disk->geom.heads,
     221                            disk->geom.sectors);
     222                        break;
     223                case am_lba28:
     224                        printf("LBA-28");
     225                        break;
     226                case am_lba48:
     227                        printf("LBA-48");
     228                        break;
     229                }
     230        } else {
     231                printf("PACKET");
     232        }
     233
     234        printf(" %" PRIu64 " blocks", d->blocks);
    184235
    185236        mbytes = d->blocks / (2 * 1024);
     
    228279        ipc_callid_t callid;
    229280        ipc_call_t call;
    230         ipcarg_t method;
    231         dev_handle_t dh;
    232         int flags;
     281        sysarg_t method;
     282        devmap_handle_t dh;
     283        unsigned int flags;
    233284        int retval;
    234285        uint64_t ba;
     
    242293        disk_id = -1;
    243294        for (i = 0; i < MAX_DISKS; i++)
    244                 if (disk[i].dev_handle == dh)
     295                if (disk[i].devmap_handle == dh)
    245296                        disk_id = i;
    246297
    247298        if (disk_id < 0 || disk[disk_id].present == false) {
    248                 ipc_answer_0(iid, EINVAL);
     299                async_answer_0(iid, EINVAL);
    249300                return;
    250301        }
    251302
    252303        /* Answer the IPC_M_CONNECT_ME_TO call. */
    253         ipc_answer_0(iid, EOK);
     304        async_answer_0(iid, EOK);
    254305
    255306        if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    256                 ipc_answer_0(callid, EHANGUP);
     307                async_answer_0(callid, EHANGUP);
    257308                return;
    258309        }
     
    260311        fs_va = as_get_mappable_page(comm_size);
    261312        if (fs_va == NULL) {
    262                 ipc_answer_0(callid, EHANGUP);
     313                async_answer_0(callid, EHANGUP);
    263314                return;
    264315        }
     
    268319        while (1) {
    269320                callid = async_get_call(&call);
    270                 method = IPC_GET_METHOD(call);
     321                method = IPC_GET_IMETHOD(call);
    271322                switch (method) {
    272323                case IPC_M_PHONE_HUNGUP:
    273324                        /* The other side has hung up. */
    274                         ipc_answer_0(callid, EOK);
     325                        async_answer_0(callid, EOK);
    275326                        return;
    276327                case BD_READ_BLOCKS:
     
    278329                            IPC_GET_ARG2(call));
    279330                        cnt = IPC_GET_ARG3(call);
    280                         if (cnt * block_size > comm_size) {
     331                        if (cnt * disk[disk_id].block_size > comm_size) {
    281332                                retval = ELIMIT;
    282333                                break;
     
    288339                            IPC_GET_ARG2(call));
    289340                        cnt = IPC_GET_ARG3(call);
    290                         if (cnt * block_size > comm_size) {
     341                        if (cnt * disk[disk_id].block_size > comm_size) {
    291342                                retval = ELIMIT;
    292343                                break;
     
    295346                        break;
    296347                case BD_GET_BLOCK_SIZE:
    297                         ipc_answer_1(callid, EOK, block_size);
     348                        async_answer_1(callid, EOK, disk[disk_id].block_size);
    298349                        continue;
    299350                case BD_GET_NUM_BLOCKS:
    300                         ipc_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
     351                        async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
    301352                            UPPER32(disk[disk_id].blocks));
    302353                        continue;
     
    305356                        break;
    306357                }
    307                 ipc_answer_0(callid, retval);
     358                async_answer_0(callid, retval);
    308359        }
    309360}
     
    318369        identify_data_t idata;
    319370        uint8_t model[40];
     371        ata_inquiry_data_t inq_data;
    320372        uint16_t w;
    321373        uint8_t c;
     374        uint16_t bc;
    322375        size_t pos, len;
    323376        int rc;
    324377        unsigned i;
    325378
     379        d->present = false;
     380        fibril_mutex_initialize(&d->lock);
     381
     382        /* Try identify command. */
    326383        rc = drive_identify(disk_id, &idata);
    327         if (rc != EOK) {
    328                 d->present = false;
    329                 return rc;
    330         }
    331 
    332         if ((idata.caps & cap_lba) == 0) {
     384        if (rc == EOK) {
     385                /* Success. It's a register (non-packet) device. */
     386                printf("ATA register-only device found.\n");
     387                d->dev_type = ata_reg_dev;
     388        } else if (rc == EIO) {
     389                /*
     390                 * There is something, but not a register device. Check to see
     391                 * whether the IDENTIFY command left the packet signature in
     392                 * the registers in case this is a packet device.
     393                 *
     394                 * According to the ATA specification, the LBA low and
     395                 * interrupt reason registers should be set to 0x01. However,
     396                 * there are many devices that do not follow this and only set
     397                 * the byte count registers. So, only check these.
     398                 */
     399                bc = ((uint16_t)pio_read_8(&cmd->cylinder_high) << 8) |
     400                    pio_read_8(&cmd->cylinder_low);
     401
     402                if (bc == PDEV_SIGNATURE_BC) {
     403                        rc = identify_pkt_dev(disk_id, &idata);
     404                        if (rc == EOK) {
     405                                /* We have a packet device. */
     406                                d->dev_type = ata_pkt_dev;
     407                        } else {
     408                                return EIO;
     409                        }
     410                } else {
     411                        /* Nope. Something's there, but not recognized. */
     412                        return EIO;
     413                }
     414        } else {
     415                /* Operation timed out. That means there is no device there. */
     416                return EIO;
     417        }
     418
     419        if (d->dev_type == ata_pkt_dev) {
     420                /* Packet device */
     421                d->amode = 0;
     422
     423                d->geom.cylinders = 0;
     424                d->geom.heads = 0;
     425                d->geom.sectors = 0;
     426
     427                d->blocks = 0;
     428        } else if ((idata.caps & rd_cap_lba) == 0) {
    333429                /* Device only supports CHS addressing. */
    334430                d->amode = am_chs;
     
    387483        d->model[pos] = '\0';
    388484
     485        if (d->dev_type == ata_pkt_dev) {
     486                /* Send inquiry. */
     487                rc = ata_pcmd_inquiry(0, &inq_data, sizeof(inq_data));
     488                if (rc != EOK) {
     489                        printf("Device inquiry failed.\n");
     490                        d->present = false;
     491                        return EIO;
     492                }
     493
     494                /* Check device type. */
     495                if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM)
     496                        printf("Warning: Peripheral device type is not CD-ROM.\n");
     497
     498                /* Assume 2k block size for now. */
     499                d->block_size = 2048;
     500        } else {
     501                /* Assume register Read always uses 512-byte blocks. */
     502                d->block_size = 512;
     503        }
     504
    389505        d->present = true;
    390         fibril_mutex_initialize(&d->lock);
    391 
    392506        return EOK;
    393507}
     
    400514
    401515        while (cnt > 0) {
    402                 rc = ata_bd_read_block(disk_id, ba, 1, buf);
     516                if (disk[disk_id].dev_type == ata_reg_dev)
     517                        rc = ata_rcmd_read(disk_id, ba, 1, buf);
     518                else
     519                        rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
     520                            disk[disk_id].block_size);
     521
    403522                if (rc != EOK)
    404523                        return rc;
     
    406525                ++ba;
    407526                --cnt;
    408                 buf += block_size;
     527                buf += disk[disk_id].block_size;
    409528        }
    410529
     
    418537        int rc;
    419538
     539        if (disk[disk_id].dev_type != ata_reg_dev)
     540                return ENOTSUP;
     541
    420542        while (cnt > 0) {
    421                 rc = ata_bd_write_block(disk_id, ba, 1, buf);
     543                rc = ata_rcmd_write(disk_id, ba, 1, buf);
    422544                if (rc != EOK)
    423545                        return rc;
     
    425547                ++ba;
    426548                --cnt;
    427                 buf += block_size;
     549                buf += disk[disk_id].block_size;
    428550        }
    429551
     
    438560 * @param disk_id       Device ID, 0 or 1.
    439561 * @param buf           Pointer to a 512-byte buffer.
     562 *
     563 * @return              ETIMEOUT on timeout (this can mean the device is
     564 *                      not present). EIO if device responds with error.
    440565 */
    441566static int drive_identify(int disk_id, void *buf)
     
    449574
    450575        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    451                 return EIO;
     576                return ETIMEOUT;
    452577
    453578        pio_write_8(&cmd->drive_head, drv_head);
    454579
    455580        /*
    456          * This is where we would most likely expect a non-existing device to
    457          * show up by not setting SR_DRDY.
     581         * Do not wait for DRDY to be set in case this is a packet device.
     582         * We determine whether the device is present by waiting for DRQ to be
     583         * set after issuing the command.
    458584         */
    459         if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    460                 return EIO;
     585        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     586                return ETIMEOUT;
    461587
    462588        pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    463589
    464590        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    465                 return EIO;
     591                return ETIMEOUT;
     592
     593        /*
     594         * If ERR is set, this may be a packet device, so return EIO to cause
     595         * the caller to check for one.
     596         */
     597        if ((status & SR_ERR) != 0) {
     598                return EIO;
     599        }
     600
     601        if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     602                return ETIMEOUT;
    466603
    467604        /* Read data from the disk buffer. */
    468605
     606        for (i = 0; i < identify_data_size / 2; i++) {
     607                data = pio_read_16(&cmd->data_port);
     608                ((uint16_t *) buf)[i] = data;
     609        }
     610
     611        return EOK;
     612}
     613
     614/** Issue Identify Packet Device command.
     615 *
     616 * Reads @c identify data into the provided buffer. This is used to detect
     617 * whether an ATAPI device is present and if so, to determine its parameters.
     618 *
     619 * @param dev_idx       Device index, 0 or 1.
     620 * @param buf           Pointer to a 512-byte buffer.
     621 */
     622static int identify_pkt_dev(int dev_idx, void *buf)
     623{
     624        uint16_t data;
     625        uint8_t status;
     626        uint8_t drv_head;
     627        size_t i;
     628
     629        drv_head = ((dev_idx != 0) ? DHR_DRV : 0);
     630
     631        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     632                return EIO;
     633
     634        pio_write_8(&cmd->drive_head, drv_head);
     635
     636        /* For ATAPI commands we do not need to wait for DRDY. */
     637        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     638                return EIO;
     639
     640        pio_write_8(&cmd->command, CMD_IDENTIFY_PKT_DEV);
     641
     642        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     643                return EIO;
     644
     645        /* Read data from the device buffer. */
     646
    469647        if ((status & SR_DRQ) != 0) {
    470                 for (i = 0; i < block_size / 2; i++) {
     648                for (i = 0; i < identify_data_size / 2; i++) {
    471649                        data = pio_read_16(&cmd->data_port);
    472650                        ((uint16_t *) buf)[i] = data;
     
    476654        if ((status & SR_ERR) != 0)
    477655                return EIO;
     656
     657        return EOK;
     658}
     659
     660/** Issue packet command (i. e. write a command packet to the device).
     661 *
     662 * Only data-in commands are supported (e.g. inquiry, read).
     663 *
     664 * @param dev_idx       Device index (0 or 1)
     665 * @param obuf          Buffer for storing data read from device
     666 * @param obuf_size     Size of obuf in bytes
     667 *
     668 * @return EOK on success, EIO on error.
     669 */
     670static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size,
     671    void *obuf, size_t obuf_size)
     672{
     673        size_t i;
     674        uint8_t status;
     675        uint8_t drv_head;
     676        disk_t *d;
     677        size_t data_size;
     678        uint16_t val;
     679
     680        d = &disk[dev_idx];
     681        fibril_mutex_lock(&d->lock);
     682
     683        /* New value for Drive/Head register */
     684        drv_head =
     685            ((dev_idx != 0) ? DHR_DRV : 0);
     686
     687        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
     688                fibril_mutex_unlock(&d->lock);
     689                return EIO;
     690        }
     691
     692        pio_write_8(&cmd->drive_head, drv_head);
     693
     694        if (wait_status(0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
     695                fibril_mutex_unlock(&d->lock);
     696                return EIO;
     697        }
     698
     699        /* Byte count <- max. number of bytes we can read in one transfer. */
     700        pio_write_8(&cmd->cylinder_low, 0xfe);
     701        pio_write_8(&cmd->cylinder_high, 0xff);
     702
     703        pio_write_8(&cmd->command, CMD_PACKET);
     704
     705        if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     706                fibril_mutex_unlock(&d->lock);
     707                return EIO;
     708        }
     709
     710        /* Write command packet. */
     711        for (i = 0; i < (cpkt_size + 1) / 2; i++)
     712                pio_write_16(&cmd->data_port, ((uint16_t *) cpkt)[i]);
     713
     714        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     715                fibril_mutex_unlock(&d->lock);
     716                return EIO;
     717        }
     718
     719        if ((status & SR_DRQ) == 0) {
     720                fibril_mutex_unlock(&d->lock);
     721                return EIO;
     722        }
     723
     724        /* Read byte count. */
     725        data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +
     726            ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);
     727
     728        /* Check whether data fits into output buffer. */
     729        if (data_size > obuf_size) {
     730                /* Output buffer is too small to store data. */
     731                fibril_mutex_unlock(&d->lock);
     732                return EIO;
     733        }
     734
     735        /* Read data from the device buffer. */
     736        for (i = 0; i < (data_size + 1) / 2; i++) {
     737                val = pio_read_16(&cmd->data_port);
     738                ((uint16_t *) obuf)[i] = val;
     739        }
     740
     741        if (status & SR_ERR) {
     742                fibril_mutex_unlock(&d->lock);
     743                return EIO;
     744        }
     745
     746        fibril_mutex_unlock(&d->lock);
     747
     748        return EOK;
     749}
     750
     751/** Issue ATAPI Inquiry.
     752 *
     753 * @param dev_idx       Device index (0 or 1)
     754 * @param obuf          Buffer for storing inquiry data read from device
     755 * @param obuf_size     Size of obuf in bytes
     756 *
     757 * @return EOK on success, EIO on error.
     758 */
     759static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size)
     760{
     761        ata_pcmd_inquiry_t cp;
     762        int rc;
     763
     764        memset(&cp, 0, sizeof(cp));
     765
     766        cp.opcode = PCMD_INQUIRY;
     767        cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */
     768
     769        rc = ata_cmd_packet(0, &cp, sizeof(cp), obuf, obuf_size);
     770        if (rc != EOK)
     771                return rc;
     772
     773        return EOK;
     774}
     775
     776/** Issue ATAPI read(12) command.
     777 *
     778 * Output buffer must be large enough to hold the data, otherwise the
     779 * function will fail.
     780 *
     781 * @param dev_idx       Device index (0 or 1)
     782 * @param ba            Starting block address
     783 * @param cnt           Number of blocks to read
     784 * @param obuf          Buffer for storing inquiry data read from device
     785 * @param obuf_size     Size of obuf in bytes
     786 *
     787 * @return EOK on success, EIO on error.
     788 */
     789static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
     790    void *obuf, size_t obuf_size)
     791{
     792        ata_pcmd_read_12_t cp;
     793        int rc;
     794
     795        if (ba > UINT32_MAX)
     796                return EINVAL;
     797
     798        memset(&cp, 0, sizeof(cp));
     799
     800        cp.opcode = PCMD_READ_12;
     801        cp.ba = host2uint32_t_be(ba);
     802        cp.nblocks = host2uint32_t_be(cnt);
     803
     804        rc = ata_cmd_packet(0, &cp, sizeof(cp), obuf, obuf_size);
     805        if (rc != EOK)
     806                return rc;
    478807
    479808        return EOK;
     
    489818 * @return EOK on success, EIO on error.
    490819 */
    491 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
     820static int ata_rcmd_read(int disk_id, uint64_t ba, size_t blk_cnt,
    492821    void *buf)
    493822{
     
    544873                /* Read data from the device buffer. */
    545874
    546                 for (i = 0; i < block_size / 2; i++) {
     875                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    547876                        data = pio_read_16(&cmd->data_port);
    548877                        ((uint16_t *) buf)[i] = data;
     
    566895 * @return EOK on success, EIO on error.
    567896 */
    568 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
     897static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
    569898    const void *buf)
    570899{
     
    620949                /* Write data to the device buffer. */
    621950
    622                 for (i = 0; i < block_size / 2; i++) {
     951                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    623952                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    624953                }
Note: See TracChangeset for help on using the changeset viewer.