Changeset 645d3832 in mainline for uspace/lib/ata/src/ata.c


Ignore:
Timestamp:
2024-06-10T17:29:13Z (4 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
a38d504
Parents:
69c376b5
git-author:
Jiri Svoboda <jiri@…> (2024-06-10 17:24:58)
git-committer:
Jiri Svoboda <jiri@…> (2024-06-10 17:29:13)
Message:

Add DMA support to PCI-IDE / libata (register commands)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ata/src/ata.c

    r69c376b5 r645d3832  
    118118    unsigned);
    119119static errno_t wait_irq(ata_channel_t *, uint8_t *, unsigned);
     120static void ata_dma_chan_setup(ata_device_t *, void *, size_t, ata_dma_dir_t);
     121static void ata_dma_chan_teardown(ata_device_t *);
    120122
    121123static bd_ops_t ata_bd_ops = {
     
    849851}
    850852
     853/** DMA command protocol.
     854 *
     855 * @param device ATA device
     856 * @param cmd Command code
     857 * @param buf Data buffer
     858 * @param buf_size Data buffer size in bytes
     859 * @param dir DMA direction
     860 *
     861 * @return EOK on success or an error code
     862 */
     863static errno_t ata_dma_proto(ata_device_t *device, uint8_t cmd, void *buf,
     864    size_t buf_size, ata_dma_dir_t dir)
     865{
     866        ata_channel_t *chan = device->chan;
     867        uint8_t status;
     868        errno_t rc;
     869
     870        /* Set up DMA channel */
     871        ata_dma_chan_setup(device, buf, buf_size, dir);
     872
     873        ata_write_cmd_8(chan, REG_COMMAND, cmd);
     874
     875        if (chan->params.have_irq)
     876                rc = wait_irq(chan, &status, TIMEOUT_BSY);
     877        else
     878                rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
     879
     880        if (rc != EOK) {
     881                ata_msg_debug(chan, "wait_irq/wait_status failed");
     882                return EIO;
     883        }
     884
     885        /* Tear down DMA channel */
     886        ata_dma_chan_teardown(device);
     887
     888        if ((status & SR_ERR) != 0) {
     889                ata_msg_debug(chan, "status & SR_ERR != 0");
     890                return EIO;
     891        }
     892
     893        return EOK;
     894}
     895
    851896/** Issue IDENTIFY DEVICE command.
    852897 *
     
    11841229        uint8_t drv_head;
    11851230        block_coord_t bc;
     1231        uint8_t cmd;
    11861232        errno_t rc;
    11871233
     
    12221268        coord_sc_program(chan, &bc, blk_cnt);
    12231269
    1224         ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
    1225             CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
    1226 
    1227         rc = ata_pio_data_in(device, buf, blk_cnt * device->block_size,
    1228             device->block_size, blk_cnt);
     1270        if (chan->params.use_dma) {
     1271                cmd = (device->amode == am_lba48) ? CMD_READ_DMA_EXT :
     1272                    CMD_READ_DMA;
     1273
     1274                rc = ata_dma_proto(device, cmd, buf,
     1275                    blk_cnt * device->block_size, ata_dma_read);
     1276                if (rc != EOK) {
     1277                        ata_msg_note(chan, "ata_rcmd_read() -> dma_proto->%d",
     1278                            rc);
     1279                }
     1280        } else {
     1281                ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
     1282                    CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
     1283
     1284                rc = ata_pio_data_in(device, buf, blk_cnt * device->block_size,
     1285                    device->block_size, blk_cnt);
     1286                if (rc != EOK) {
     1287                        ata_msg_note(chan, "ata_rcmd_read() -> pio_data_in->%d",
     1288                            rc);
     1289                }
     1290        }
    12291291
    12301292        fibril_mutex_unlock(&chan->lock);
    12311293
    1232         if (rc != EOK)
    1233                 ata_msg_note(chan, "ata_rcmd_read() -> pio_data_in->%d", rc);
    12341294        return rc;
    12351295}
     
    12501310        uint8_t drv_head;
    12511311        block_coord_t bc;
     1312        uint8_t cmd;
    12521313        errno_t rc;
    12531314
     
    12841345        coord_sc_program(chan, &bc, cnt);
    12851346
    1286         ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
    1287             CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
    1288 
    1289         rc = ata_pio_data_out(device, buf, cnt * device->block_size,
    1290             device->block_size, cnt);
     1347        if (chan->params.use_dma) {
     1348                cmd = (device->amode == am_lba48) ? CMD_WRITE_DMA_EXT :
     1349                    CMD_WRITE_DMA;
     1350
     1351                rc = ata_dma_proto(device, cmd, (void *)buf,
     1352                    cnt * device->block_size, ata_dma_write);
     1353                if (rc != EOK) {
     1354                        ata_msg_note(chan, "ata_rcmd_write() -> dma_proto->%d",
     1355                            rc);
     1356                }
     1357        } else {
     1358                ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
     1359                    CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
     1360
     1361                rc = ata_pio_data_out(device, buf, cnt * device->block_size,
     1362                    device->block_size, cnt);
     1363                if (rc != EOK) {
     1364                        ata_msg_note(chan,
     1365                            "ata_rcmd_read() -> pio_data_out->%d", rc);
     1366                }
     1367        }
    12911368
    12921369        fibril_mutex_unlock(&chan->lock);
     
    15221599}
    15231600
     1601/** Set up DMA channel.
     1602 *
     1603 * @param device ATA device
     1604 * @param buf Data buffer
     1605 * @param buf_size Data buffer size in bytes
     1606 * @param dir DMA direction
     1607 */
     1608static void ata_dma_chan_setup(ata_device_t *device, void *buf,
     1609    size_t buf_size, ata_dma_dir_t dir)
     1610{
     1611        device->chan->params.dma_chan_setup(device->chan->params.arg,
     1612            buf, buf_size, dir);
     1613}
     1614
     1615/** Tear down DMA channel.
     1616 *
     1617 * @param device ATA device
     1618 */
     1619static void ata_dma_chan_teardown(ata_device_t *device)
     1620{
     1621        device->chan->params.dma_chan_teardown(device->chan->params.arg);
     1622}
     1623
    15241624/** Interrupt handler.
    15251625 *
Note: See TracChangeset for help on using the changeset viewer.