Subversion Repositories HelenOS

Rev

Rev 4420 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4420 Rev 4439
Line 82... Line 82...
82
 
82
 
83
typedef struct {
83
typedef struct {
84
    uint8_t buffer[512];
84
    uint8_t buffer[512];
85
} gxe_buf_t;
85
} gxe_buf_t;
86
 
86
 
87
static size_t maxblock_size = 512;
87
static const size_t block_size = 512;
-
 
88
static size_t comm_size;
-
 
89
 
88
static uintptr_t dev_physical = 0x13000000;
90
static uintptr_t dev_physical = 0x13000000;
89
static gxe_bd_t *dev;
91
static gxe_bd_t *dev;
90
static gxe_buf_t *devbuf;
92
static gxe_buf_t *devbuf;
91
 
93
 
92
static uint32_t disk_id = 0;
94
static uint32_t disk_id = 0;
93
 
95
 
94
static atomic_t dev_futex = FUTEX_INITIALIZER;
96
static atomic_t dev_futex = FUTEX_INITIALIZER;
95
 
97
 
96
static int gxe_bd_init(void);
98
static int gxe_bd_init(void);
97
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
99
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
98
static int gxe_bd_read_block(uint64_t offset, size_t block_size, void *buf);
100
static int gx_bd_rdwr(ipcarg_t method, off_t offset, off_t size, void *buf);
99
static int gxe_bd_write_block(uint64_t offset, size_t block_size,
101
static int gxe_bd_read_block(uint64_t offset, size_t size, void *buf);
100
    const void *buf);
102
static int gxe_bd_write_block(uint64_t offset, size_t size, const void *buf);
101
 
103
 
102
int main(int argc, char **argv)
104
int main(int argc, char **argv)
103
{
105
{
104
    printf(NAME ": GXemul disk driver\n");
106
    printf(NAME ": GXemul disk driver\n");
105
 
107
 
Line 154... Line 156...
154
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
156
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
155
{
157
{
156
    void *fs_va = NULL;
158
    void *fs_va = NULL;
157
    ipc_callid_t callid;
159
    ipc_callid_t callid;
158
    ipc_call_t call;
160
    ipc_call_t call;
-
 
161
    ipcarg_t method;
159
    int flags;
162
    int flags;
160
    int retval;
163
    int retval;
161
    off_t offset;
164
    off_t idx;
162
    size_t block_size;
165
    off_t size;
163
 
166
 
164
    /* Answer the IPC_M_CONNECT_ME_TO call. */
167
    /* Answer the IPC_M_CONNECT_ME_TO call. */
165
    ipc_answer_0(iid, EOK);
168
    ipc_answer_0(iid, EOK);
166
 
169
 
167
    if (!ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
170
    if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
168
        ipc_answer_0(callid, EHANGUP);
171
        ipc_answer_0(callid, EHANGUP);
169
        return;
172
        return;
170
    }
173
    }
171
    maxblock_size = 512;
-
 
172
 
174
 
173
    fs_va = as_get_mappable_page(maxblock_size);
175
    fs_va = as_get_mappable_page(comm_size);
174
    if (fs_va == NULL) {
176
    if (fs_va == NULL) {
175
        ipc_answer_0(callid, EHANGUP);
177
        ipc_answer_0(callid, EHANGUP);
176
        return;
178
        return;
177
    }
179
    }
178
 
180
 
179
    (void) ipc_share_out_finalize(callid, fs_va);
181
    (void) ipc_share_out_finalize(callid, fs_va);
180
 
182
 
181
    while (1) {
183
    while (1) {
182
        callid = async_get_call(&call);
184
        callid = async_get_call(&call);
183
        switch (IPC_GET_METHOD(call)) {
185
        method = IPC_GET_METHOD(call);
-
 
186
        switch (method) {
184
        case IPC_M_PHONE_HUNGUP:
187
        case IPC_M_PHONE_HUNGUP:
185
            /* The other side has hung up. */
188
            /* The other side has hung up. */
186
            ipc_answer_0(callid, EOK);
189
            ipc_answer_0(callid, EOK);
187
            return;
190
            return;
188
        case BD_READ_BLOCK:
191
        case BD_READ_BLOCK:
189
            offset = IPC_GET_ARG1(call);
-
 
190
            block_size = IPC_GET_ARG2(call);
-
 
191
            retval = gxe_bd_read_block(offset, block_size, fs_va);
-
 
192
            break;
-
 
193
        case BD_WRITE_BLOCK:
192
        case BD_WRITE_BLOCK:
194
            offset = IPC_GET_ARG1(call);
193
            idx = IPC_GET_ARG1(call);
195
            block_size = IPC_GET_ARG2(call);
194
            size = IPC_GET_ARG2(call);
-
 
195
            if (size > comm_size) {
-
 
196
                retval = EINVAL;
-
 
197
                break;
-
 
198
            }
196
            retval = gxe_bd_write_block(offset, block_size, fs_va);
199
            retval = gx_bd_rdwr(method, idx * size, size, fs_va);
197
            break;
200
            break;
198
        default:
201
        default:
199
            retval = EINVAL;
202
            retval = EINVAL;
200
            break;
203
            break;
201
        }
204
        }
202
        ipc_answer_0(callid, retval);
205
        ipc_answer_0(callid, retval);
203
    }
206
    }
204
}
207
}
205
 
208
 
-
 
209
static int gx_bd_rdwr(ipcarg_t method, off_t offset, off_t size, void *buf)
-
 
210
{
-
 
211
    int rc;
-
 
212
    size_t now;
-
 
213
 
-
 
214
    while (size > 0) {
-
 
215
        now = size < block_size ? size : block_size;
-
 
216
 
-
 
217
        if (method == BD_READ_BLOCK)
-
 
218
            rc = gxe_bd_read_block(offset, now, buf);
-
 
219
        else
-
 
220
            rc = gxe_bd_write_block(offset, now, buf);
-
 
221
 
-
 
222
        if (rc != EOK)
-
 
223
            return rc;
-
 
224
 
-
 
225
        buf += block_size;
-
 
226
        offset += block_size;
-
 
227
 
-
 
228
        if (size > block_size)
-
 
229
            size -= block_size;
-
 
230
        else
-
 
231
            size = 0;
-
 
232
    }
-
 
233
 
-
 
234
    return EOK;
-
 
235
}
-
 
236
 
206
static int gxe_bd_read_block(uint64_t offset, size_t block_size, void *buf)
237
static int gxe_bd_read_block(uint64_t offset, size_t size, void *buf)
207
{
238
{
208
    uint32_t status;
239
    uint32_t status;
209
    size_t i;
240
    size_t i;
210
    uint32_t w;
241
    uint32_t w;
211
 
242
 
212
    if (block_size != maxblock_size) {
-
 
213
        printf("Failed: bs = %d, mbs = %d\n", block_size,
-
 
214
            maxblock_size);
-
 
215
        return EINVAL;
-
 
216
    }
-
 
217
 
-
 
218
    futex_down(&dev_futex);
243
    futex_down(&dev_futex);
219
    pio_write_32(&dev->offset_lo, (uint32_t) offset);
244
    pio_write_32(&dev->offset_lo, (uint32_t) offset);
220
    pio_write_32(&dev->offset_hi, offset >> 32);
245
    pio_write_32(&dev->offset_hi, offset >> 32);
221
    pio_write_32(&dev->disk_id, disk_id);
246
    pio_write_32(&dev->disk_id, disk_id);
222
    pio_write_32(&dev->control, CTL_READ_START);
247
    pio_write_32(&dev->control, CTL_READ_START);
Line 224... Line 249...
224
    status = pio_read_32(&dev->status);
249
    status = pio_read_32(&dev->status);
225
    if (status == STATUS_FAILURE) {
250
    if (status == STATUS_FAILURE) {
226
        return EIO;
251
        return EIO;
227
    }
252
    }
228
 
253
 
229
    for (i = 0; i < maxblock_size; i++) {
254
    for (i = 0; i < size; i++) {
230
        ((uint8_t *) buf)[i] = w =
255
        ((uint8_t *) buf)[i] = w =
231
            pio_read_8(&devbuf->buffer[i]);
256
            pio_read_8(&devbuf->buffer[i]);
232
    }
257
    }
233
 
258
 
234
    futex_up(&dev_futex);
259
    futex_up(&dev_futex);
235
    return EOK;
260
    return EOK;
236
}
261
}
237
 
262
 
238
static int gxe_bd_write_block(uint64_t offset, size_t block_size,
263
static int gxe_bd_write_block(uint64_t offset, size_t size, const void *buf)
239
    const void *buf)
-
 
240
{
264
{
241
    uint32_t status;
265
    uint32_t status;
242
    size_t i;
266
    size_t i;
243
    uint32_t w;
267
    uint32_t w;
244
 
268
 
245
    if (block_size != maxblock_size) {
-
 
246
        printf("Failed: bs = %d, mbs = %d\n", block_size,
-
 
247
            maxblock_size);
-
 
248
        return EINVAL;
-
 
249
    }
-
 
250
 
-
 
251
    for (i = 0; i < maxblock_size; i++) {
269
    for (i = 0; i < size; i++) {
252
        pio_write_8(&devbuf->buffer[i], ((const uint8_t *) buf)[i]);
270
        pio_write_8(&devbuf->buffer[i], ((const uint8_t *) buf)[i]);
253
    }
271
    }
254
 
272
 
255
    futex_down(&dev_futex);
273
    futex_down(&dev_futex);
256
    pio_write_32(&dev->offset_lo, (uint32_t) offset);
274
    pio_write_32(&dev->offset_lo, (uint32_t) offset);