GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_device_classes/src/ux_device_class_storage_start_stop.c Lines: 15 19 78.9 %
Date: 2026-03-06 18:57:10 Branches: 10 14 71.4 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** USBX Component                                                        */
17
/**                                                                       */
18
/**   Device Storage Class                                                */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define UX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "ux_api.h"
29
#include "ux_device_class_storage.h"
30
#include "ux_device_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_device_class_storage_start_stop                 PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function starts or stops the media. The device load or eject   */
46
/*    the medium.                                                         */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    storage                               Pointer to storage class      */
51
/*    lun                                   Logical unit number           */
52
/*    endpoint_in                           Pointer to IN endpoint        */
53
/*    endpoint_out                          Pointer to OUT endpoint       */
54
/*    cbwcb                                 Pointer to CBWCB              */
55
/*                                                                        */
56
/*  OUTPUT                                                                */
57
/*                                                                        */
58
/*    Completion Status                                                   */
59
/*                                                                        */
60
/*  CALLS                                                                 */
61
/*                                                                        */
62
/*    None                                                                */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    Device Storage Class                                                */
67
/*                                                                        */
68
/**************************************************************************/
69
4
UINT  _ux_device_class_storage_start_stop(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
70
                                            UX_SLAVE_ENDPOINT *endpoint_in,
71
                                            UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb)
72
{
73
74
ULONG   power_condition;
75
ULONG   start;
76
ULONG   load_eject;
77
78
    UX_PARAMETER_NOT_USED(endpoint_in);
79
    UX_PARAMETER_NOT_USED(endpoint_out);
80
81
    /* If trace is enabled, insert this event into the trace buffer.  */
82
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_START_STOP, storage, lun, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
83
84
    /* Parse START/STOP (SBC-2 0x1B): byte 4 has LOEJ (bit1) and START (bit0).  */
85
4
    power_condition = (ULONG)((cbwcb[4] & 0xF0) >> 0x04);
86
4
    start = (ULONG)(cbwcb[4] & 0x01);
87
4
    load_eject  = (ULONG)((cbwcb[4] & 0x02) >> 0x01);
88
89
4
    if ((load_eject == 1) &&
90
2
        (storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_prevent_medium_removal == 1) &&
91
        (storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_removable_flag == UX_SLAVE_CLASS_STORAGE_MEDIA_IS_NOT_REMOVABLE))
92
    {
93
        /* Update the REQUEST SENSE codes.  */
94
        storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status =
95
            UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST,
96
                                                 UX_SLAVE_CLASS_STORAGE_ASC_KEY_INVALID_COMMAND, 0x00);
97
98
        /* Set the CSW with failure.  */
99
        storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_FAILED;
100
101
        /* Return error.  */
102
        return(UX_ERROR);
103
    }
104
105
    /*  power_condition = 0, load_eject = 0 : no action regarding loading or ejecting the medium.
106
        power_condition = 0, load_eject = 1, start = 0 : unload the medium.
107
        power_condition = 0, load_eject = 1, start = 1 : load the medium.
108
        */
109
4
    if (power_condition == UX_SLAVE_CLASS_STORAGE_POWER_CONDITION_START_VALID)
110
    {
111
4
        if (load_eject != 0)
112
        {
113
2
            if (start == 0)
114
            {
115
                /* Eject media: mark as empty. */
116
1
                storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_medium_loaded_status = 0;
117
            }
118
            else
119
            {
120
                /* Load media: mark as present/complete.  */
121
1
                storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_medium_loaded_status = 1;
122
            }
123
        }
124
    }
125
126
    /* Call the media start/stop function if available.  */
127
4
    if (storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_start_stop != UX_NULL)
128
2
        storage -> ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_start_stop(
129
                    storage, lun, power_condition, start, load_eject);
130
131
    /* We set the CSW with success.  */
132
4
    storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED;
133
134
    /* Return successful completion.  */
135
4
    return(UX_SUCCESS);
136
}