OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [ide/] [raid/] [ataraid.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
   ataraid.c  Copyright (C) 2001 Red Hat, Inc. All rights reserved.
3
 
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 2, or (at your option)
7
   any later version.
8
 
9
   You should have received a copy of the GNU General Public License
10
   (for example /usr/src/linux/COPYING); if not, write to the Free
11
   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
12
 
13
   Authors:     Arjan van de Ven <arjanv@redhat.com>
14
 
15
 
16
*/
17
 
18
#include <linux/module.h>
19
#include <linux/init.h>
20
#include <linux/kernel.h>
21
#include <linux/mm.h>
22
#include <asm/semaphore.h>
23
#include <linux/sched.h>
24
#include <linux/smp_lock.h>
25
#include <linux/blkdev.h>
26
#include <linux/blkpg.h>
27
#include <linux/genhd.h>
28
#include <linux/ioctl.h>
29
#include <linux/kdev_t.h>
30
#include <linux/swap.h>
31
 
32
#include <linux/ide.h>
33
#include <asm/uaccess.h>
34
 
35
#include "ataraid.h"
36
 
37
 
38
static int ataraid_hardsect_size[256];
39
static int ataraid_blksize_size[256];
40
 
41
static struct raid_device_operations* ataraid_ops[16];
42
 
43
static int ataraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
44
static int ataraid_open(struct inode * inode, struct file * filp);
45
static int ataraid_release(struct inode * inode, struct file * filp);
46
static void ataraid_split_request(request_queue_t *q, int rw, struct buffer_head * bh);
47
 
48
 
49
struct gendisk ataraid_gendisk;
50
static int ataraid_gendisk_sizes[256];
51
static int ataraid_readahead[256];
52
 
53
static struct block_device_operations ataraid_fops = {
54
        owner:                  THIS_MODULE,
55
        open:                   ataraid_open,
56
        release:                ataraid_release,
57
        ioctl:                  ataraid_ioctl,
58
};
59
 
60
 
61
 
62
static DECLARE_MUTEX(ataraid_sem);
63
 
64
/* Bitmap for the devices currently in use */
65
static unsigned int ataraiduse;
66
 
67
 
68
/* stub fops functions */
69
 
70
static int ataraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
71
{
72
        int minor;
73
        minor = MINOR(inode->i_rdev)>>SHIFT;
74
 
75
        if ((ataraid_ops[minor])&&(ataraid_ops[minor]->ioctl))
76
                return (ataraid_ops[minor]->ioctl)(inode,file,cmd,arg);
77
        return -EINVAL;
78
}
79
 
80
static int ataraid_open(struct inode * inode, struct file * filp)
81
{
82
        int minor;
83
        minor = MINOR(inode->i_rdev)>>SHIFT;
84
 
85
        if ((ataraid_ops[minor])&&(ataraid_ops[minor]->open))
86
                return (ataraid_ops[minor]->open)(inode,filp);
87
        return -EINVAL;
88
}
89
 
90
 
91
static int ataraid_release(struct inode * inode, struct file * filp)
92
{
93
        int minor;
94
        minor = MINOR(inode->i_rdev)>>SHIFT;
95
 
96
        if ((ataraid_ops[minor])&&(ataraid_ops[minor]->release))
97
                return (ataraid_ops[minor]->release)(inode,filp);
98
        return -EINVAL;
99
}
100
 
101
static int ataraid_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
102
{
103
        int minor;
104
        int retval;
105
        minor = MINOR(bh->b_rdev)>>SHIFT;
106
 
107
        if ((ataraid_ops[minor])&&(ataraid_ops[minor]->make_request)) {
108
 
109
                retval= (ataraid_ops[minor]->make_request)(q,rw,bh);
110
                if (retval == -1) {
111
                        ataraid_split_request(q,rw,bh);
112
                        return 0;
113
                } else
114
                        return retval;
115
        }
116
        return -EINVAL;
117
}
118
 
119
struct buffer_head *ataraid_get_bhead(void)
120
{
121
        void *ptr = NULL;
122
        while (!ptr) {
123
                ptr=kmalloc(sizeof(struct buffer_head),GFP_NOIO);
124
                if (!ptr) {
125
                        __set_current_state(TASK_RUNNING);
126
                        yield();
127
                }
128
        }
129
        return ptr;
130
}
131
 
132
EXPORT_SYMBOL(ataraid_get_bhead);
133
 
134
struct ataraid_bh_private *ataraid_get_private(void)
135
{
136
        void *ptr = NULL;
137
        while (!ptr) {
138
                ptr=kmalloc(sizeof(struct ataraid_bh_private),GFP_NOIO);
139
                if (!ptr) {
140
                        __set_current_state(TASK_RUNNING);
141
                        yield();
142
                }
143
        }
144
        return ptr;
145
}
146
 
147
EXPORT_SYMBOL(ataraid_get_private);
148
 
149
void ataraid_end_request(struct buffer_head *bh, int uptodate)
150
{
151
        struct ataraid_bh_private *private = bh->b_private;
152
 
153
        if (private==NULL)
154
                BUG();
155
 
156
        if (atomic_dec_and_test(&private->count)) {
157
                private->parent->b_end_io(private->parent,uptodate);
158
                private->parent = NULL;
159
                kfree(private);
160
        }
161
        kfree(bh);
162
}
163
 
164
EXPORT_SYMBOL(ataraid_end_request);
165
 
166
static void ataraid_split_request(request_queue_t *q, int rw, struct buffer_head * bh)
167
{
168
        struct buffer_head *bh1,*bh2;
169
        struct ataraid_bh_private *private;
170
        bh1=ataraid_get_bhead();
171
        bh2=ataraid_get_bhead();
172
 
173
        /* If either of those ever fails we're doomed */
174
        if ((!bh1)||(!bh2))
175
                BUG();
176
        private = ataraid_get_private();
177
        if (private==NULL)
178
                BUG();
179
 
180
        memcpy(bh1, bh, sizeof(*bh));
181
        memcpy(bh2, bh, sizeof(*bh));
182
 
183
        bh1->b_end_io = ataraid_end_request;
184
        bh2->b_end_io = ataraid_end_request;
185
 
186
        bh2->b_rsector += bh->b_size >> 10;
187
        bh1->b_size /= 2;
188
        bh2->b_size /= 2;
189
        private->parent = bh;
190
 
191
        bh1->b_private = private;
192
        bh2->b_private = private;
193
        atomic_set(&private->count,2);
194
 
195
        bh2->b_data +=  bh->b_size/2;
196
 
197
        generic_make_request(rw,bh1);
198
        generic_make_request(rw,bh2);
199
}
200
 
201
 
202
 
203
 
204
/* device register / release functions */
205
 
206
 
207
int ataraid_get_device(struct raid_device_operations *fops)
208
{
209
        int bit;
210
        down(&ataraid_sem);
211
        if (ataraiduse==~0U) {
212
                up(&ataraid_sem);
213
                return -ENODEV;
214
        }
215
        bit=ffz(ataraiduse);
216
        ataraiduse |= 1<<bit;
217
        ataraid_ops[bit] = fops;
218
        up(&ataraid_sem);
219
        return bit;
220
}
221
 
222
void ataraid_release_device(int device)
223
{
224
        down(&ataraid_sem);
225
 
226
        if ((ataraiduse & (1<<device))==0)
227
                BUG();  /* device wasn't registered at all */
228
 
229
        ataraiduse &= ~(1<<device);
230
        ataraid_ops[device] = NULL;
231
        up(&ataraid_sem);
232
}
233
 
234
void ataraid_register_disk(int device,long size)
235
{
236
        register_disk(&ataraid_gendisk, MKDEV(ATAMAJOR,16*device),16,
237
                &ataraid_fops,size);
238
 
239
}
240
 
241
static __init int ataraid_init(void)
242
{
243
        int i;
244
        for(i=0;i<256;i++)
245
        {
246
                ataraid_hardsect_size[i] = 512;
247
                ataraid_blksize_size[i] = 1024;
248
                ataraid_readahead[i] = 1023;
249
        }
250
 
251
        if (blksize_size[ATAMAJOR]==NULL)
252
                blksize_size[ATAMAJOR] = ataraid_blksize_size;
253
        if (hardsect_size[ATAMAJOR]==NULL)
254
                hardsect_size[ATAMAJOR] = ataraid_hardsect_size;
255
 
256
 
257
        /* setup the gendisk structure */
258
        ataraid_gendisk.part = kmalloc(256 * sizeof(struct hd_struct),GFP_KERNEL);
259
        if (ataraid_gendisk.part==NULL) {
260
                printk(KERN_ERR "ataraid: Couldn't allocate memory, aborting \n");
261
                return -1;
262
        }
263
 
264
        memset(&ataraid_gendisk.part[0],0,256*sizeof(struct hd_struct));
265
 
266
 
267
        ataraid_gendisk.major       = ATAMAJOR;
268
        ataraid_gendisk.major_name  = "ataraid";
269
        ataraid_gendisk.minor_shift = 4;
270
        ataraid_gendisk.max_p       = 15;
271
        ataraid_gendisk.sizes       = &ataraid_gendisk_sizes[0];
272
        ataraid_gendisk.nr_real     = 16;
273
        ataraid_gendisk.fops        = &ataraid_fops;
274
 
275
 
276
        add_gendisk(&ataraid_gendisk);
277
 
278
        if (register_blkdev(ATAMAJOR, "ataraid", &ataraid_fops)) {
279
                printk(KERN_ERR "ataraid: Could not get major %d \n",ATAMAJOR);
280
                return -1;
281
        }
282
 
283
 
284
 
285
        blk_queue_make_request(BLK_DEFAULT_QUEUE(ATAMAJOR),ataraid_make_request);
286
 
287
        return 0;
288
}
289
 
290
 
291
static void __exit ataraid_exit(void)
292
{
293
        unregister_blkdev(ATAMAJOR, "ataraid");
294
        hardsect_size[ATAMAJOR] = NULL;
295
        blk_size[ATAMAJOR] = NULL;
296
        blksize_size[ATAMAJOR] = NULL;
297
        max_readahead[ATAMAJOR] = NULL;
298
 
299
        del_gendisk(&ataraid_gendisk);
300
 
301
        if (ataraid_gendisk.part) {
302
                kfree(ataraid_gendisk.part);
303
                ataraid_gendisk.part = NULL;
304
        }
305
}
306
 
307
module_init(ataraid_init);
308
module_exit(ataraid_exit);
309
 
310
 
311
 
312
EXPORT_SYMBOL(ataraid_get_device);
313
EXPORT_SYMBOL(ataraid_release_device);
314
EXPORT_SYMBOL(ataraid_gendisk);
315
EXPORT_SYMBOL(ataraid_register_disk);
316
MODULE_LICENSE("GPL");
317
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.