Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/block/ata_bd/ata_bd.c

    rc2844735 r4abe919  
    5454#include <bd_srv.h>
    5555#include <fibril_synch.h>
     56#include <scsi/mmc.h>
    5657#include <scsi/sbc.h>
     58#include <scsi/spc.h>
    5759#include <stdint.h>
    5860#include <str.h>
     
    9597static int ata_bd_get_block_size(bd_srv_t *, size_t *);
    9698static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     99static int ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
    97100
    98101static int ata_rcmd_read(disk_t *disk, uint64_t ba, size_t cnt,
     
    100103static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
    101104    const void *buf);
     105static int ata_rcmd_flush_cache(disk_t *disk);
    102106static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
    103107static int ata_identify_dev(disk_t *disk, void *buf);
     
    127131        .write_blocks = ata_bd_write_blocks,
    128132        .get_block_size = ata_bd_get_block_size,
    129         .get_num_blocks = ata_bd_get_num_blocks
     133        .get_num_blocks = ata_bd_get_num_blocks,
     134        .sync_cache = ata_bd_sync_cache
    130135};
    131136
     
    343348        identify_data_t idata;
    344349        uint8_t model[40];
    345         ata_inquiry_data_t inq_data;
     350        scsi_std_inquiry_data_t inq_data;
    346351        size_t isize;
    347352        uint16_t w;
     
    472477
    473478                /* Check device type. */
    474                 if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM)
     479                if (INQUIRY_PDEV_TYPE(inq_data.pqual_devtype) != SCSI_DEV_CD_DVD)
    475480                        ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM.");
    476481
     
    584589}
    585590
     591/** Flush cache. */
     592static int ata_bd_sync_cache(bd_srv_t *bd, uint64_t ba, size_t cnt)
     593{
     594        disk_t *disk = bd_srv_disk(bd);
     595
     596        /* ATA cannot flush just some blocks, we just flush everything. */
     597        (void)ba;
     598        (void)cnt;
     599
     600        return ata_rcmd_flush_cache(disk);
     601}
     602
    586603/** PIO data-in command protocol. */
    587604static int ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size,
     
    637654                }
    638655        }
     656
     657        if (status & SR_ERR)
     658                return EIO;
     659
     660        return EOK;
     661}
     662
     663/** PIO non-data command protocol. */
     664static int ata_pio_nondata(disk_t *disk)
     665{
     666        ata_ctrl_t *ctrl = disk->ctrl;
     667        uint8_t status;
     668
     669        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     670                return EIO;
    639671
    640672        if (status & SR_ERR)
     
    831863    size_t *rcvd_size)
    832864{
    833         ata_pcmd_inquiry_t cp;
     865        uint8_t cpb[12];
     866        scsi_cdb_inquiry_t *cp = (scsi_cdb_inquiry_t *)cpb;
    834867        int rc;
    835868
    836         memset(&cp, 0, sizeof(cp));
    837 
    838         cp.opcode = PCMD_INQUIRY;
    839         cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */
    840 
    841         rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, rcvd_size);
     869        memset(cpb, 0, sizeof(cpb));
     870
     871        /*
     872         * For SFF 8020 compliance the inquiry must be padded to 12 bytes
     873         * and allocation length must fit in one byte.
     874         */
     875        cp->op_code = SCSI_CMD_INQUIRY;
     876
     877        /* Allocation length */
     878        cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff));
     879
     880        rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size);
    842881        if (rc != EOK)
    843882                return rc;
     
    894933    void *obuf, size_t obuf_size)
    895934{
    896         ata_pcmd_read_12_t cp;
     935        scsi_cdb_read_12_t cp;
    897936        int rc;
    898937
     
    902941        memset(&cp, 0, sizeof(cp));
    903942
    904         cp.opcode = PCMD_READ_12;
    905         cp.ba = host2uint32_t_be(ba);
    906         cp.nblocks = host2uint32_t_be(cnt);
     943        cp.op_code = SCSI_CMD_READ_12;
     944        cp.lba = host2uint32_t_be(ba);
     945        cp.xfer_len = host2uint32_t_be(cnt);
    907946
    908947        rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL);
     
    933972    size_t obuf_size)
    934973{
    935         ata_pcmd_read_toc_t cp;
     974        uint8_t cpb[12];
     975        scsi_cdb_read_toc_t *cp = (scsi_cdb_read_toc_t *)cpb;
    936976        int rc;
    937977
    938         memset(&cp, 0, sizeof(cp));
    939 
    940         cp.opcode = PCMD_READ_TOC;
    941         cp.msf = 0;
    942         cp.format = 0x01; /* 0x01 = multi-session mode */
    943         cp.start = session;
    944         cp.size = host2uint16_t_be(obuf_size);
    945         cp.oldformat = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
    946        
    947         rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL);
     978        memset(cpb, 0, sizeof(cpb));
     979
     980        cp->op_code = SCSI_CMD_READ_TOC;
     981        cp->msf = 0;
     982        cp->format = 0x01; /* 0x01 = multi-session mode */
     983        cp->track_sess_no = session;
     984        cp->alloc_len = host2uint16_t_be(obuf_size);
     985        cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
     986
     987        rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, NULL);
    948988        if (rc != EOK)
    949989                return rc;
    950        
     990
    951991        return EOK;
    952992}
     
    10661106        rc = ata_pio_data_out(disk, buf, cnt * disk->block_size,
    10671107            disk->block_size, cnt);
     1108
     1109        fibril_mutex_unlock(&ctrl->lock);
     1110        return rc;
     1111}
     1112
     1113/** Flush cached data to nonvolatile storage.
     1114 *
     1115 * @param disk          Disk
     1116 *
     1117 * @return EOK on success, EIO on error.
     1118 */
     1119static int ata_rcmd_flush_cache(disk_t *disk)
     1120{
     1121        ata_ctrl_t *ctrl = disk->ctrl;
     1122        uint8_t drv_head;
     1123        int rc;
     1124
     1125        /* New value for Drive/Head register */
     1126        drv_head =
     1127            (disk_dev_idx(disk) != 0) ? DHR_DRV : 0;
     1128
     1129        fibril_mutex_lock(&ctrl->lock);
     1130
     1131        /* Program a Flush Cache operation. */
     1132
     1133        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     1134                fibril_mutex_unlock(&ctrl->lock);
     1135                return EIO;
     1136        }
     1137
     1138        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     1139
     1140        if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     1141                fibril_mutex_unlock(&ctrl->lock);
     1142                return EIO;
     1143        }
     1144
     1145        pio_write_8(&ctrl->cmd->command, CMD_FLUSH_CACHE);
     1146
     1147        rc = ata_pio_nondata(disk);
    10681148
    10691149        fibril_mutex_unlock(&ctrl->lock);
Note: See TracChangeset for help on using the changeset viewer.