summaryrefslogtreecommitdiffstats
path: root/c/src/libchip/ide/ide_controller.c
blob: 912f9e31577884ba15b76c4bb7135d9985059f27 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
 * ide_controller.c
 *
 * This is generic rtems driver for IDE controllers.
 *
 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
 * Authors: Alexandra Kossovsky <sasha@oktet.ru>
 *          Eugeny S. Mints <Eugeny.Mints@oktet.ru>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 *
 */

#define IDE_CONTROLLER_TRACE 0

#include <rtems/chain.h>
#include <errno.h>
#include <rtems/blkdev.h>

#include <libchip/ide_ctrl.h>
#include <libchip/ide_ctrl_cfg.h>
#include <libchip/ide_ctrl_io.h>

#if IDE_CONTROLLER_TRACE
int ide_controller_trace = 1;
#endif

/*
 * ide_controller_initialize --
 *     Initializes all configured IDE controllers. Controllers configuration
 *     table is provided by BSP
 *
 * PARAMETERS:
 *     major     - device major number
 *     minor_arg - device minor number
 *     args      - arguments
 *
 * RETURNS:
 *     RTEMS_SUCCESSFUL on success, or error code if
 *     error occured
 */
rtems_device_driver
ide_controller_initialize(rtems_device_major_number  major,
                          rtems_device_minor_number  minor_arg,
                          void                      *args)
{
    unsigned long       minor;

    /* FIXME: may be it should be done on compilation phase */
    if (IDE_Controller_Count > IDE_CTRL_MAX_MINOR_NUMBER)
        rtems_fatal_error_occurred(RTEMS_TOO_MANY);

    for (minor=0; minor < IDE_Controller_Count; minor++)
    {
        IDE_Controller_Table[minor].status = IDE_CTRL_NON_INITIALIZED;

        if ((IDE_Controller_Table[minor].probe == NULL ||
             IDE_Controller_Table[minor].probe(minor)) &&
            (IDE_Controller_Table[minor].fns->ctrl_probe == NULL ||
             IDE_Controller_Table[minor].fns->ctrl_probe(minor)))
        {
            dev_t  dev;
            dev = rtems_filesystem_make_dev_t( major, minor );
            if (mknod(IDE_Controller_Table[minor].name,
                      0777 | S_IFBLK, dev ) < 0)
                rtems_fatal_error_occurred(errno);
            IDE_Controller_Table[minor].fns->ctrl_initialize(minor);
            IDE_Controller_Table[minor].status = IDE_CTRL_INITIALIZED;
        }
    }
    return RTEMS_SUCCESSFUL;
}

/*
 * ide_controller_read_data_block --
 *     Read data block via controller's data register
 *
 * PARAMETERS:
 *     minor      - minor number of controller
 *     block_size - number of bytes to read
 *     bufs       - set of buffers to store data
 *     cbuf       - number of current buffer from the set
 *     pos        - position inside current buffer 'cbuf'
 *
 * RETURNS:
 *     NONE
 */
void
ide_controller_read_data_block(rtems_device_minor_number  minor,
                               uint32_t                   block_size,
                               rtems_blkdev_sg_buffer    *bufs,
                               uint32_t                  *cbuf,
                               uint32_t                  *pos)
{
#if IDE_CONTROLLER_TRACE
    if (ide_controller_trace)
        printk ("IDE data block read: %d:%d\n", *cbuf, bufs[*cbuf].block);
#endif
    IDE_Controller_Table[minor].fns->ctrl_read_block(minor, block_size, bufs,
                                                     cbuf, pos);
}

/*
 * ide_controller_write_data_block --
 *     Write data block via controller's data register
 *
 * PARAMETERS:
 *     minor      - minor number of controller
 *     block_size - number of bytes to write
 *     bufs       - set of buffers which store data
 *     cbuf       - number of current buffer from the set
 *     pos        - position inside current buffer 'cbuf'
 *
 * RETURNS:
 *     NONE
 */
void
ide_controller_write_data_block(rtems_device_minor_number  minor,
                                uint32_t                   block_size,
                                rtems_blkdev_sg_buffer    *bufs,
                                uint32_t                  *cbuf,
                                uint32_t                  *pos)

{
#if IDE_CONTROLLER_TRACE
    if (ide_controller_trace)
        printk ("IDE data block write: %d:%d\n", *cbuf, bufs[*cbuf].block);
#endif
    IDE_Controller_Table[minor].fns->ctrl_write_block(minor, block_size, bufs,
                                                      cbuf, pos);
}

/*
 * ide_controller_read_register --
 *     Read controller's register
 *
 * PARAMETERS:
 *     minor - minor number of controller
 *     reg   - register to read
 *     value - placeholder for result
 *
 * RETURNS
 *     NONE
 */
void
ide_controller_read_register(rtems_device_minor_number  minor,
                             int                        reg,
                             uint16_t                  *value)
{
    IDE_Controller_Table[minor].fns->ctrl_reg_read(minor, reg, value);
#if IDE_CONTROLLER_TRACE
    if (ide_controller_trace)
        printk ("IDE read reg: %d => %04x\n", reg, *value);
#endif
}

/*
 * ide_controller_write_register --
 *     Write controller's register
 *
 * PARAMETERS:
 *     minor - minor number of controller
 *     reg   - register to write
 *     value - value to write
 *
 * RETURNS:
 *     NONE
 */
void
ide_controller_write_register(rtems_device_minor_number minor, int reg,
                              uint16_t   value)
{
#if IDE_CONTROLLER_TRACE
    if (ide_controller_trace)
        printk ("IDE write reg: %d => %04x\n", reg, value);
#endif
    IDE_Controller_Table[minor].fns->ctrl_reg_write(minor, reg, value);
}

/*
 * ide_controller_config_io_speed --
 *     Set controller's speed of IO operations
 *
 * PARAMETERS:
 *     minor           - minor number of controller
 *     modes_available - speeds available
 *
 * RETURNS:
 *     RTEMS_SUCCESSFUL on success, or error code if
 *     error occured
 */
rtems_status_code
ide_controller_config_io_speed(int minor, uint16_t modes_available)
{
    return IDE_Controller_Table[minor].fns->ctrl_config_io_speed(
               minor,
               modes_available);
}