Changeset 4285f384 in mainline for uspace/lib


Ignore:
Timestamp:
2025-02-25T20:25:43Z (5 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
d30e067, f35749e
Parents:
d231a54
Message:

Allow physically ejecting CD-ROM using vol eject -s

Location:
uspace/lib
Files:
12 edited

Legend:

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

    rd231a54 r4285f384  
    9696static errno_t ata_bd_get_block_size(bd_srv_t *, size_t *);
    9797static errno_t ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     98static errno_t ata_bd_eject(bd_srv_t *);
    9899static errno_t ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
    99100
     
    105106static errno_t ata_identify_dev(ata_device_t *, void *);
    106107static errno_t ata_identify_pkt_dev(ata_device_t *, void *);
    107 static errno_t ata_cmd_packet(ata_device_t *, const void *, size_t, void *,
     108static errno_t ata_cmd_packet_nondata(ata_device_t *, const void *, size_t);
     109static errno_t ata_cmd_packet_din(ata_device_t *, const void *, size_t, void *,
    108110    size_t, size_t *);
    109111static errno_t ata_pcmd_inquiry(ata_device_t *, void *, size_t, size_t *);
     
    111113static errno_t ata_pcmd_read_capacity(ata_device_t *, uint64_t *, size_t *);
    112114static errno_t ata_pcmd_read_toc(ata_device_t *, uint8_t, void *, size_t);
     115static errno_t ata_pcmd_start_stop_unit(ata_device_t *, uint8_t);
    113116static void disk_print_summary(ata_device_t *);
    114117static size_t ata_disk_maxnb(ata_device_t *);
     
    129132        .get_block_size = ata_bd_get_block_size,
    130133        .get_num_blocks = ata_bd_get_num_blocks,
    131         .sync_cache = ata_bd_sync_cache
     134        .sync_cache = ata_bd_sync_cache,
     135        .eject = ata_bd_eject
    132136};
    133137
     
    758762}
    759763
     764/** Eject medium. */
     765static errno_t ata_bd_eject(bd_srv_t *bd)
     766{
     767        ata_device_t *device = bd_srv_device(bd);
     768
     769        ata_msg_debug(device->chan, "ata_bd_eject()");
     770        return ata_pcmd_start_stop_unit(device, ssf_pc_no_change |
     771            ssf_loej);
     772}
     773
    760774/** PIO data-in command protocol. */
    761775static errno_t ata_pio_data_in(ata_device_t *device, void *obuf, size_t obuf_size,
     
    10881102}
    10891103
    1090 /** Issue packet command (i. e. write a command packet to the device).
    1091  *
    1092  * Only data-in commands are supported (e.g. inquiry, read).
     1104/** Issue packet command (i. e. write a command packet to the device)
     1105 * with no data transfer.
    10931106 *
    10941107 * @param device        Device
     1108 * @param cpkt          Command packet
     1109 * @param cpkt_size     Command packet size in bytes
     1110 *
     1111 * @return EOK on success, EIO on error.
     1112 */
     1113static errno_t ata_cmd_packet_nondata(ata_device_t *device, const void *cpkt,
     1114    size_t cpkt_size)
     1115{
     1116        ata_channel_t *chan = device->chan;
     1117        uint8_t status;
     1118        uint8_t drv_head;
     1119        errno_t rc;
     1120
     1121        ata_msg_debug(chan, "ata_cmd_packet_nondata()");
     1122
     1123        fibril_mutex_lock(&chan->lock);
     1124
     1125        /* New value for Drive/Head register */
     1126        drv_head =
     1127            ((disk_dev_idx(device) != 0) ? DHR_DRV : 0);
     1128
     1129        if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
     1130                fibril_mutex_unlock(&chan->lock);
     1131                return EIO;
     1132        }
     1133
     1134        ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
     1135
     1136        if (wait_status(chan, 0, ~(SR_BSY | SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
     1137                fibril_mutex_unlock(&chan->lock);
     1138                return EIO;
     1139        }
     1140
     1141        ata_write_cmd_8(chan, REG_COMMAND, CMD_PACKET);
     1142
     1143        if (wait_status(chan, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     1144                if (chan->params.use_dma)
     1145                        ata_dma_chan_teardown(device);
     1146                fibril_mutex_unlock(&chan->lock);
     1147                return EIO;
     1148        }
     1149
     1150        /* Write command packet. */
     1151        ata_write_data_16(chan, ((uint16_t *) cpkt), (cpkt_size + 1) / 2);
     1152
     1153        rc = ata_pio_nondata(device);
     1154
     1155        fibril_mutex_unlock(&chan->lock);
     1156
     1157        return rc;
     1158}
     1159
     1160/** Issue packet command (i. e. write a command packet to the device)
     1161 * performing data-in transfer.
     1162 *
     1163 * @param device        Device
     1164 * @param cpkt          Command packet
     1165 * @param cpkt_size     Command packet size in bytes
    10951166 * @param obuf          Buffer for storing data read from device
    10961167 * @param obuf_size     Size of obuf in bytes
     
    10991170 * @return EOK on success, EIO on error.
    11001171 */
    1101 static errno_t ata_cmd_packet(ata_device_t *device, const void *cpkt, size_t cpkt_size,
    1102     void *obuf, size_t obuf_size, size_t *rcvd_size)
     1172static errno_t ata_cmd_packet_din(ata_device_t *device, const void *cpkt,
     1173    size_t cpkt_size, void *obuf, size_t obuf_size, size_t *rcvd_size)
    11031174{
    11041175        ata_channel_t *chan = device->chan;
     
    11951266        cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff));
    11961267
    1197         rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size);
     1268        rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size,
     1269            rcvd_size);
    11981270        if (rc != EOK)
    11991271                return rc;
     
    12211293        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    12221294
    1223         rc = ata_cmd_packet(device, &cdb, sizeof(cdb), &data, sizeof(data), &rsize);
     1295        rc = ata_cmd_packet_din(device, &cdb, sizeof(cdb), &data, sizeof(data),
     1296            &rsize);
    12241297        if (rc != EOK)
    12251298                return rc;
     
    12621335        cp.xfer_len = host2uint32_t_be(cnt);
    12631336
    1264         rc = ata_cmd_packet(device, &cp, sizeof(cp), obuf, obuf_size, NULL);
     1337        rc = ata_cmd_packet_din(device, &cp, sizeof(cp), obuf, obuf_size, NULL);
    12651338        if (rc != EOK)
    12661339                return rc;
     
    13021375        cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
    13031376
    1304         rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, NULL);
     1377        rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size,
     1378            NULL);
    13051379        if (rc != EOK)
    13061380                return rc;
     1381
     1382        return EOK;
     1383}
     1384
     1385/** Issue Start Stop Unit command.
     1386 *
     1387 * @param device        Device
     1388 * @param flags         Flags field of Start Stop Unit command (ssf_*)
     1389 * @return EOK on success, EIO on error.
     1390 */
     1391static errno_t ata_pcmd_start_stop_unit(ata_device_t *device, uint8_t flags)
     1392{
     1393        uint8_t cpb[12];
     1394        scsi_cdb_start_stop_unit_t *cp = (scsi_cdb_start_stop_unit_t *)cpb;
     1395        errno_t rc;
     1396
     1397        ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(device, 0x%x)",
     1398            flags);
     1399
     1400        memset(cpb, 0, sizeof(cpb));
     1401
     1402        /*
     1403         * For SFF 8020 compliance the command must be padded to 12 bytes.
     1404         */
     1405        cp->op_code = SCSI_CMD_START_STOP_UNIT;
     1406        cp->immed = 0;
     1407        cp->flags = flags;
     1408        cp->control = 0;
     1409
     1410        rc = ata_cmd_packet_nondata(device, cpb, sizeof(cpb));
     1411        if (rc != EOK)
     1412                return rc;
     1413
     1414        ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(): "
     1415            "ata_cmd_packet_nondata -> %d", rc);
    13071416
    13081417        return EOK;
  • uspace/lib/device/include/bd.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151extern errno_t bd_get_block_size(bd_t *, size_t *);
    5252extern errno_t bd_get_num_blocks(bd_t *, aoff64_t *);
     53extern errno_t bd_eject(bd_t *);
    5354
    5455#endif
  • uspace/lib/device/include/bd_srv.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6666        errno_t (*get_block_size)(bd_srv_t *, size_t *);
    6767        errno_t (*get_num_blocks)(bd_srv_t *, aoff64_t *);
     68        errno_t (*eject)(bd_srv_t *);
    6869};
    6970
  • uspace/lib/device/include/ipc/bd.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4444        BD_SYNC_CACHE,
    4545        BD_WRITE_BLOCKS,
    46         BD_READ_TOC
     46        BD_READ_TOC,
     47        BD_EJECT
    4748} bd_request_t;
    4849
  • uspace/lib/device/include/ipc/vol.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5454} vol_request_t;
    5555
     56/** Volume eject flags */
     57typedef enum {
     58        /** No flags */
     59        vef_none = 0x0,
     60        /** Physically eject medium */
     61        vef_physical = 0x1
     62} vol_eject_flags_t;
     63
    5664#endif
    5765
  • uspace/lib/device/include/types/vol.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
  • uspace/lib/device/include/vol.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848extern errno_t vol_part_add(vol_t *, service_id_t);
    4949extern errno_t vol_part_info(vol_t *, service_id_t, vol_part_info_t *);
    50 extern errno_t vol_part_eject(vol_t *, service_id_t);
     50extern errno_t vol_part_eject(vol_t *, service_id_t, vol_eject_flags_t);
    5151extern errno_t vol_part_empty(vol_t *, service_id_t);
    5252extern errno_t vol_part_insert(vol_t *, service_id_t);
  • uspace/lib/device/src/bd.c

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    196196}
    197197
     198errno_t bd_eject(bd_t *bd)
     199{
     200        async_exch_t *exch = async_exchange_begin(bd->sess);
     201
     202        errno_t rc = async_req_0_0(exch, BD_EJECT);
     203        async_exchange_end(exch);
     204
     205        return rc;
     206}
     207
    198208static void bd_cb_conn(ipc_call_t *icall, void *arg)
    199209{
  • uspace/lib/device/src/bd_srv.c

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    206206}
    207207
     208static void bd_eject_srv(bd_srv_t *srv, ipc_call_t *call)
     209{
     210        errno_t rc;
     211
     212        if (srv->srvs->ops->eject == NULL) {
     213                async_answer_0(call, ENOTSUP);
     214                return;
     215        }
     216
     217        rc = srv->srvs->ops->eject(srv);
     218        async_answer_0(call, rc);
     219}
     220
    208221static bd_srv_t *bd_srv_create(bd_srvs_t *srvs)
    209222{
     
    276289                        bd_get_num_blocks_srv(srv, &call);
    277290                        break;
     291                case BD_EJECT:
     292                        bd_eject_srv(srv, &call);
     293                        break;
    278294                default:
    279295                        async_answer_0(&call, EINVAL);
  • uspace/lib/device/src/vol.c

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    253253 * @param vol Volume service
    254254 * @param sid Service ID of the partition
    255  * @return EOK on success or an error code
    256  */
    257 errno_t vol_part_eject(vol_t *vol, service_id_t sid)
    258 {
    259         async_exch_t *exch;
    260         errno_t retval;
    261 
    262         exch = async_exchange_begin(vol->sess);
    263         retval = async_req_1_0(exch, VOL_PART_EJECT, sid);
     255 * @param flags Ejection flags
     256 * @return EOK on success or an error code
     257 */
     258errno_t vol_part_eject(vol_t *vol, service_id_t sid, vol_eject_flags_t flags)
     259{
     260        async_exch_t *exch;
     261        errno_t retval;
     262
     263        exch = async_exchange_begin(vol->sess);
     264        retval = async_req_2_0(exch, VOL_PART_EJECT, sid, flags);
    264265        async_exchange_end(exch);
    265266
  • uspace/lib/fdisk/src/fdisk.c

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    819819        errno_t rc;
    820820
    821         rc = vol_part_eject(part->dev->fdisk->vol, part->svc_id);
     821        rc = vol_part_eject(part->dev->fdisk->vol, part->svc_id, vef_none);
    822822        if (rc != EOK)
    823823                return EIO;
  • uspace/lib/scsi/include/scsi/sbc.h

    rd231a54 r4285f384  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5050        SCSI_CMD_READ_CAPACITY_16       = 0x9e,
    5151
     52        SCSI_CMD_START_STOP_UNIT        = 0x1b,
     53
    5254        SCSI_CMD_SYNC_CACHE_10          = 0x35,
    5355        SCSI_CMD_SYNC_CACHE_16          = 0x91,
     
    214216} __attribute__((packed)) scsi_cdb_write_16_t;
    215217
     218/** SCSI Start Stop Unit command */
     219typedef struct {
     220        /** Operation code (SCSI_CMD_START_STOP_UNIT) */
     221        uint8_t op_code;
     222        /** Immediate */
     223        uint8_t immed;
     224        /** Reserved */
     225        uint8_t reserved_2;
     226        /** Reserved */
     227        uint8_t reserved_3;
     228        /** Power Conditions | Reserved | LoEj | Start */
     229        uint8_t flags;
     230        /** Control */
     231        uint8_t control;
     232} __attribute__((packed)) scsi_cdb_start_stop_unit_t;
     233
     234/** Constants for values in sccsi_cdb_start_stop_unit_t.flags */
     235enum scsi_start_stop_flags {
     236        ssf_pc_no_change = 0x00,
     237        ssf_pc_idle = 0x10,
     238        ssf_pc_standby = 0x20,
     239        ssf_pc_sleep = 0x50,
     240        ssf_loej = 0x02,
     241        ssf_start = 0x01
     242};
     243
    216244#endif
    217245
Note: See TracChangeset for help on using the changeset viewer.