update atp870u driver to 0.78 from D-Link source
[linux-2.4.git] / drivers / ide / raid / medley.c
1 /*
2  * MEDLEY SOFTWARE RAID DRIVER (Silicon Image 3112 and others)
3  *
4  * Copyright (C) 2003 Thomas Horsten <thomas@horsten.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * Copyright (C) 2003 Thomas Horsten <thomas@horsten.com>
20  * All Rights Reserved.
21  *
22  * This driver uses the ATA RAID driver framework and is based on
23  * code from Arjan van de Ven's silraid.c and hptraid.c.
24  *
25  * It is a driver for the Medley software RAID, which is used by
26  * some IDE controllers, including the Silicon Image 3112 SATA
27  * controller found onboard many modern motherboards, and the
28  * CMD680 stand-alone PCI RAID controller.
29  *
30  * The author has only tested this on the Silicon Image SiI3112.
31  * If you have any luck using more than 2 drives, and/or more
32  * than one RAID set, and/or any other chip than the SiI3112,
33  * please let me know by sending me mail at the above address.
34  *
35  * Currently, only striped mode is supported for these RAIDs.
36  *
37  * You are welcome to contact me if you have any questions or
38  * suggestions for improvement.
39  *
40  * Change history:
41  *
42  * 20040310 - thomas@horsten.com
43  *   Removed C99 style variable declarations that confused gcc-2.x
44  *   Fixed a bug where more than one RAID set would not be detected correctly
45  *   General cleanup for submission to kernel
46  *
47  * 20031012 - thomas@horsten.com
48  *   Added support for BLKRRPART ioctl to re-read partition table
49  *
50  * 20030801 - thomas@horsten.com
51  *   First test release
52  *
53  */
54
55 #include <linux/version.h>
56 #include <linux/module.h>
57 #include <linux/init.h>
58 #include <linux/kernel.h>
59 #include <linux/sched.h>
60 #include <linux/smp_lock.h>
61 #include <linux/blkdev.h>
62 #include <linux/blkpg.h>
63 #include <linux/genhd.h>
64 #include <linux/ioctl.h>
65
66 #include <linux/ide.h>
67 #include <asm/uaccess.h>
68
69 #include "ataraid.h"
70
71 /*
72  * These options can be tuned if the need should occur.
73  *
74  * Even better, this driver could be changed to allocate the structures
75  * dynamically.
76  */
77 #define MAX_DRIVES_PER_SET 8
78 #define MAX_MEDLEY_ARRAYS 4
79
80 /*
81  * Set to 1 only if you are debugging the driver, or if it doesn't work
82  * the way you expect and you want to to report it.
83  *
84  * This will produce lots of kernel messages, some of which might
85  * help me figure out what is going wrong).
86  */
87 #define DEBUGGING_MEDLEY 0
88
89 #if DEBUGGING_MEDLEY
90 #define dprintk(fmt, args...) printk(fmt, ##args)
91 #else
92 #define dprintk(fmt, args...)
93 #endif
94
95 /*
96  * Medley RAID metadata structure.
97  *
98  * The metadata structure is based on the ATA drive ID from the drive itself,
99  * with the RAID information in the vendor specific regions.
100  *
101  * We do not use all the fields, since we only support Striped Sets.
102  */
103 struct medley_metadata {
104         u8  driveid0[46];
105         u8  ascii_version[8];
106         u8  driveid1[52];
107         u32 total_sectors_low;
108         u32 total_sectors_high;
109         u16 reserved0;
110         u8  driveid2[142];
111         u16 product_id;
112         u16 vendor_id;
113         u16 minor_ver;
114         u16 major_ver;
115         u16 creation_timestamp[3];
116         u16 chunk_size;
117         u16 reserved1;
118         u8  drive_number;
119         u8  raid_type;
120         u8  drives_per_striped_set;
121         u8  striped_set_number;
122         u8  drives_per_mirrored_set;
123         u8  mirrored_set_number;
124         u32 rebuild_ptr_low;
125         u32 rebuild_ptr_high;
126         u32 incarnation_no;
127         u8  member_status;
128         u8  mirrored_set_state;
129         u8  reported_device_location;
130         u8  member_location;
131         u8  auto_rebuild;
132         u8  reserved3[17];
133         u16 checksum;
134 };
135
136 /*
137  * This struct holds the information about a Medley array
138  */
139 struct medley_array {
140         u8       drives;
141         u16      chunk_size;
142         u32      sectors_per_row;
143         u8       chunk_size_log;
144         u16      present;
145         u16      timestamp[3];
146         u32      sectors;
147         int      registered;
148         atomic_t valid;
149         int      access;
150
151         kdev_t   members[MAX_DRIVES_PER_SET];
152         struct   block_device *bdev[MAX_DRIVES_PER_SET];
153 };
154
155 static struct medley_array raid[MAX_MEDLEY_ARRAYS];
156
157 /*
158  * Here we keep the offset of the ATARAID device ID's compared to our
159  * own (this will normally be 0, unless another ATARAID driver has
160  * registered some arrays before us).
161  */
162 static int medley_devid_offset = 0;
163
164 /*
165  * This holds the number of detected arrays.
166  */
167 static int medley_arrays = 0;
168
169 /*
170  * Wait queue for opening device (used when re-reading partition table)
171  */
172 static DECLARE_WAIT_QUEUE_HEAD(medley_wait_open);
173
174 /*
175  * The interface functions used by the ataraid framework.
176  */
177 static int medley_open(struct inode *inode, struct file *filp);
178 static int medley_release(struct inode *inode, struct file *filp);
179 static int medley_ioctl(struct inode *inode, struct file *file,
180                         unsigned int cmd, unsigned long arg);
181 static int medley_make_request(request_queue_t * q, int rw,
182                                struct buffer_head *bh);
183
184 static struct raid_device_operations medley_ops = {
185         open:         medley_open,
186         release:      medley_release,
187         ioctl:        medley_ioctl,
188         make_request: medley_make_request
189 };
190
191 /*
192  * This is the list of devices to probe.
193  */
194 static const kdev_t probelist[] = {
195         MKDEV(IDE0_MAJOR, 0),
196         MKDEV(IDE0_MAJOR, 64),
197         MKDEV(IDE1_MAJOR, 0),
198         MKDEV(IDE1_MAJOR, 64),
199         MKDEV(IDE2_MAJOR, 0),
200         MKDEV(IDE2_MAJOR, 64),
201         MKDEV(IDE3_MAJOR, 0),
202         MKDEV(IDE3_MAJOR, 64),
203         MKDEV(IDE4_MAJOR, 0),
204         MKDEV(IDE4_MAJOR, 64),
205         MKDEV(IDE5_MAJOR, 0),
206         MKDEV(IDE5_MAJOR, 64),
207         MKDEV(IDE6_MAJOR, 0),
208         MKDEV(IDE6_MAJOR, 64),
209         MKDEV(0, 0)
210 };
211
212 /*
213  * Handler for ioctl calls to the virtual device
214  */
215 static int medley_ioctl(struct inode *inode, struct file *file,
216                         unsigned int cmd, unsigned long arg)
217 {
218         unsigned int minor;
219         unsigned long sectors;
220         int devminor = (inode->i_rdev >> SHIFT) & MAJOR_MASK;
221         int device = devminor - medley_devid_offset;
222         int partition;
223
224         dprintk("medley_ioctl\n");
225
226         minor = MINOR(inode->i_rdev) >> SHIFT;
227
228         switch (cmd) {
229
230         case BLKGETSIZE:        /* Return device size */
231                 if (!arg)
232                         return -EINVAL;
233                 sectors =
234                     ataraid_gendisk.part[MINOR(inode->i_rdev)].nr_sects;
235                 dprintk("medley_ioctl: BLKGETSIZE\n");
236                 if (MINOR(inode->i_rdev) & 15)
237                         return put_user(sectors, (unsigned long *) arg);
238                 return put_user(raid[minor - medley_devid_offset].sectors,
239                                 (unsigned long *) arg);
240                 break;
241
242         case HDIO_GETGEO: {
243                         struct hd_geometry *loc =
244                             (struct hd_geometry *) arg;
245                         unsigned short bios_cyl = (unsigned short)
246                             (raid[minor].sectors / 255 / 63);   /* truncate */
247
248                         dprintk("medley_ioctl: HDIO_GETGEO\n");
249                         if (!loc)
250                                 return -EINVAL;
251                         if (put_user(255, (byte *) & loc->heads))
252                                 return -EFAULT;
253                         if (put_user(63, (byte *) & loc->sectors))
254                                 return -EFAULT;
255                         if (put_user
256                             (bios_cyl, (unsigned short *) &loc->cylinders))
257                                 return -EFAULT;
258                         if (put_user
259                             ((unsigned) ataraid_gendisk.
260                              part[MINOR(inode->i_rdev)].start_sect,
261                              (unsigned long *) &loc->start))
262                                 return -EFAULT;
263                         return 0;
264                 }
265
266         case HDIO_GETGEO_BIG: {
267                         struct hd_big_geometry *loc =
268                             (struct hd_big_geometry *) arg;
269
270                         dprintk("medley_ioctl: HDIO_GETGEO_BIG\n");
271                         if (!loc)
272                                 return -EINVAL;
273                         if (put_user(255, (byte *) & loc->heads))
274                                 return -EFAULT;
275                         if (put_user(63, (byte *) & loc->sectors))
276                                 return -EFAULT;
277                         if (put_user
278                             (raid[minor - medley_devid_offset].sectors /
279                              255 / 63, (unsigned int *) &loc->cylinders))
280                                 return -EFAULT;
281                         if (put_user
282                             ((unsigned) ataraid_gendisk.
283                              part[MINOR(inode->i_rdev)].start_sect,
284                              (unsigned long *) &loc->start))
285                                 return -EFAULT;
286                         return 0;
287                 }
288
289         case BLKROSET:
290         case BLKROGET:
291         case BLKSSZGET:
292                 dprintk("medley_ioctl: BLK*\n");
293                 return blk_ioctl(inode->i_rdev, cmd, arg);
294
295         case BLKRRPART: /* Re-read partition tables */
296                 if (!capable(CAP_SYS_ADMIN))
297                         return -EACCES;
298                 if (minor != 0)
299                         return -EINVAL;
300                 if (atomic_read(&(raid[device].valid)) == 0)
301                         return -EINVAL;
302
303                 atomic_set(&(raid[device].valid), 0);
304                 if (raid[device].access != 1) {
305                         atomic_set(&(raid[device].valid), 1);
306                         return -EBUSY;
307                 }
308
309                 for (partition = 15; partition >= 0; partition--) {
310                         invalidate_device(MKDEV(ATARAID_MAJOR,
311                                                 partition + devminor), 1);
312                         ataraid_gendisk.part[partition +
313                                              devminor].start_sect = 0;
314                         ataraid_gendisk.part[partition +
315                                              devminor].nr_sects = 0;
316                 }
317                 ataraid_register_disk(device, raid[device].sectors);
318                 atomic_set(&(raid[device].valid), 1);
319                 wake_up(&medley_wait_open);
320                 return 0;
321
322         default:
323                 return -EINVAL;
324         }
325
326         return 0;
327 }
328
329 /*
330  * Handler to map a request to the real device.
331  * If the request cannot be made because it spans multiple disks,
332  * we return -1, otherwise we modify the request and return 1.
333  */
334 static int medley_make_request(request_queue_t * q, int rw,
335                                struct buffer_head *bh)
336 {
337         u8 disk;
338         u32 rsect = bh->b_rsector;
339         int device =
340             ((bh->b_rdev >> SHIFT) & MAJOR_MASK) - medley_devid_offset;
341         struct medley_array *r = raid + device;
342
343         /* Add the partition offset */
344         rsect = rsect + ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
345
346         dprintk("medley_make_request, rsect=%ul\n", rsect);
347
348         /* Detect if the request crosses a chunk barrier */
349         if (r->chunk_size_log) {
350                 if (((rsect & (r->chunk_size - 1)) +
351                      (bh->b_size / 512)) > (1 << r->chunk_size_log)) {
352                         return -1;
353                 }
354         } else {
355                 if ((rsect / r->chunk_size) !=
356                     ((rsect + (bh->b_size / 512) - 1) / r->chunk_size)) {
357                         return -1;
358                 }
359         }
360
361         /*
362          * Medley arrays are simple enough, since the smallest disk decides the
363          * number of sectors used per disk. So there is no need for the cutoff
364          * magic found in other drivers like hptraid.
365          */
366         if (r->chunk_size_log) {
367                 /* We save some expensive operations (1 div, 1 mul, 1 mod),
368                  * if the chunk size is a power of 2, which is true in most
369                  * cases (at least with my version of the RAID BIOS).
370                  */
371                 disk = (rsect >> r->chunk_size_log) % r->drives;
372                 rsect = ((rsect / r->sectors_per_row) <<
373                          r->chunk_size_log) + (rsect & (r->chunk_size -
374                                                         1));
375         } else {
376                 disk = (rsect / r->chunk_size) % r->drives;
377                 rsect = rsect / r->sectors_per_row * r->chunk_size +
378                     rsect % r->chunk_size;
379         }
380
381         dprintk("medley_make_request :-), disk=%d, rsect=%ul\n", disk,
382                 rsect);
383         bh->b_rdev = r->members[disk];
384         bh->b_rsector = rsect;
385         return 1;
386 }
387
388 /*
389  * Find out which array a drive belongs to, and add it to that array.
390  * If it is not a member of a detected array, add a new array for it.
391  */
392 void medley_add_raiddrive(kdev_t dev, struct medley_metadata *md)
393 {
394         int c;
395
396         dprintk("Candidate drive %02x:%02x - drive %d of %d, stride %d, "
397                 "sectors %ul (%d MB)\n",
398                 MAJOR(dev), MINOR(dev), md->drive_number,
399                 md->drives_per_striped_set, md->chunk_size,
400                 md->total_sectors_low,
401                 md->total_sectors_low / 1024 / 1024 / 2);
402
403         for (c = 0; c < medley_arrays; c++) {
404                 if ((raid[c].timestamp[0] == md->creation_timestamp[0]) &&
405                     (raid[c].timestamp[1] == md->creation_timestamp[1]) &&
406                     (raid[c].timestamp[2] == md->creation_timestamp[2]) &&
407                     (raid[c].drives == md->drives_per_striped_set) &&
408                     (raid[c].chunk_size == md->chunk_size) &&
409                     ((raid[c].present & (1 << md->drive_number)) == 0)) {
410                         dprintk("Existing array %d\n", c);
411                         raid[c].present |= (1 << md->drive_number);
412                         raid[c].members[md->drive_number] = dev;
413                         break;
414                 }
415         }
416         if (c == medley_arrays) {
417                 dprintk("New array %d\n", medley_arrays);
418                 if (medley_arrays == MAX_MEDLEY_ARRAYS) {
419                         printk(KERN_ERR "Medley RAID: "
420                                "Too many RAID sets detected - you can change "
421                                "the max in the driver.\n");
422                 } else {
423                         raid[c].timestamp[0] = md->creation_timestamp[0];
424                         raid[c].timestamp[1] = md->creation_timestamp[1];
425                         raid[c].timestamp[2] = md->creation_timestamp[2];
426                         raid[c].drives = md->drives_per_striped_set;
427                         raid[c].chunk_size = md->chunk_size;
428                         raid[c].sectors_per_row = md->chunk_size *
429                             md->drives_per_striped_set;
430
431                         /* Speedup if chunk size is a power of 2 */
432                         if (((raid[c].chunk_size - 1) &
433                              (raid[c].chunk_size)) == 0) {
434                                 raid[c].chunk_size_log =
435                                     ffs(raid[c].chunk_size) - 1;
436                         } else {
437                                 raid[c].chunk_size_log = 0;
438                         }
439                         raid[c].present = (1 << md->drive_number);
440                         raid[c].members[md->drive_number] = dev;
441                         if (md->major_ver == 1) {
442                                 raid[c].sectors = ((u32 *) (md))[27];
443                         } else {
444                                 raid[c].sectors = md->total_sectors_low;
445                         }
446                         medley_arrays++;
447                 }
448         }
449 }
450
451 /*
452  * Read the Medley metadata from a drive.
453  * Returns the bh if it was found, otherwise NULL.
454  */
455 struct buffer_head *medley_get_metadata(kdev_t dev)
456 {
457         struct buffer_head *bh = NULL;
458         struct pci_dev *pcidev;
459         u32 lba;
460         int pos;
461         struct medley_metadata *md;
462
463         ide_drive_t *drvinfo = ide_info_ptr(dev, 0);
464         if ((drvinfo == NULL) || drvinfo->capacity < 1) {
465                 return NULL;
466         }
467
468         dprintk("Probing %02x:%02x\n", MAJOR(dev), MINOR(dev));
469
470         /* If this drive is not on a PCI controller, it is not Medley RAID.
471          * Medley matches the PCI device ID with the metadata to check if
472          * it is valid. Unfortunately it is the only reliable way to identify
473          * the superblock */
474         pcidev = drvinfo->hwif ? drvinfo->hwif->pci_dev : NULL;
475         if (!pcidev) {
476                 return NULL;
477         }
478
479         /*
480          * 4 copies of the metadata exist, in the following 4 sectors:
481          * last, last-0x200, last-0x400, last-0x600.
482          *
483          * We must try each of these in order, until we find the metadata.
484          * FIXME: This does not take into account drives with 48/64-bit LBA
485          * addressing, even though the Medley RAID version 2 supports these.
486          */
487         lba = drvinfo->capacity - 1;
488         for (pos = 0; pos < 4; pos++, lba -= 0x200) {
489                 bh = bread(dev, lba, 512);
490                 if (!bh) {
491                         printk(KERN_ERR "Medley RAID (%02x:%02x): "
492                                "Error reading metadata (lba=%d)\n",
493                                MAJOR(dev), MINOR(dev), lba);
494                         break;
495                 }
496
497                 /* A valid Medley RAID has the PCI vendor/device ID of its
498                  * IDE controller, and the correct checksum. */
499                 md = (void *) (bh->b_data);
500
501                 if (pcidev->vendor == md->vendor_id &&
502                     pcidev->device == md->product_id) {
503                         u16 checksum = 0;
504                         u16 *p = (void *) (bh->b_data);
505                         int c;
506                         for (c = 0; c < 160; c++) {
507                                 checksum += *p++;
508                         }
509                         dprintk
510                             ("Probing %02x:%02x csum=%d, major_ver=%d\n",
511                              MAJOR(dev), MINOR(dev), checksum,
512                              md->major_ver);
513                         if (((checksum == 0xffff) && (md->major_ver == 1))
514                             || (checksum == 0)) {
515                                 dprintk("Probing %02x:%02x VALID\n",
516                                         MAJOR(dev), MINOR(dev));
517                                 break;
518                         }
519                 }
520                 /* Was not a valid superblock */
521                 if (bh) {
522                         brelse(bh);
523                         bh = NULL;
524                 }
525         }
526         return bh;
527 }
528
529 /*
530  * Determine if this drive belongs to a Medley array.
531  */
532 static void medley_probe_drive(int major, int minor)
533 {
534         struct buffer_head *bh;
535         kdev_t dev = MKDEV(major, minor);
536         struct medley_metadata *md;
537
538         bh = medley_get_metadata(dev);
539         if (!bh)
540                 return;
541
542         md = (void *) (bh->b_data);
543
544         if (md->raid_type != 0x0) {
545                 printk(KERN_INFO "Medley RAID (%02x:%02x): "
546                        "Sorry, this driver currently only supports "
547                        "striped sets (RAID level 0).\n", major, minor);
548         } else if (md->major_ver == 2 && md->total_sectors_high != 0) {
549                 printk(KERN_ERR "Medley RAID (%02x:%02x):"
550                        "Sorry, the driver only supports 32 bit LBA disks "
551                        "(disk too big).\n", major, minor);
552         } else if (md->major_ver > 0 && md->major_ver > 2) {
553                 printk(KERN_INFO "Medley RAID (%02x:%02x): "
554                        "Unsupported version (%d.%d) - this driver supports "
555                        "Medley version 1.x and 2.x\n",
556                        major, minor, md->major_ver, md->minor_ver);
557         } else if (md->drives_per_striped_set > MAX_DRIVES_PER_SET) {
558                 printk(KERN_ERR "Medley RAID (%02x:%02x): "
559                        "Striped set too large (%d drives) - please report "
560                        "this (and change max in driver).\n",
561                        major, minor, md->drives_per_striped_set);
562         } else if ((md->drive_number > md->drives_per_striped_set) ||
563                    (md->drives_per_striped_set < 1) ||
564                    (md->chunk_size < 1)) {
565                 printk(KERN_ERR "Medley RAID (%02x:%02x): "
566                        "Metadata appears to be corrupt.\n", major, minor);
567         } else {
568                 /* We have a good candidate, put it in the correct array */
569                 medley_add_raiddrive(dev, md);
570         }
571
572         if (bh) {
573                 brelse(bh);
574         }
575 }
576
577
578 /*
579  * Taken from hptraid.c, this is called to prevent the device
580  * from disappearing from under us and also nullifies the (incorrect)
581  * partitions of the underlying disk.
582  */
583 struct block_device *get_device_lock(kdev_t member)
584 {
585         struct block_device *bdev = bdget(member);
586         struct gendisk *gd;
587         int minor = MINOR(member);
588         int j;
589
590         if (bdev
591             && blkdev_get(bdev, FMODE_READ | FMODE_WRITE, 0,
592                           BDEV_RAW) == 0) {
593                 /*
594                  * This is supposed to prevent others from
595                  * stealing our underlying disks. Now blank
596                  * the /proc/partitions table for the wrong
597                  * partition table, so that scripts don't
598                  * accidentally mount it and crash the kernel
599                  */
600                 /* XXX: the 0 is an utter hack  --hch */
601                 gd = get_gendisk(MKDEV(MAJOR(member), 0));
602                 if (gd != NULL) {
603                         if (gd->major == MAJOR(member)) {
604                                 for (j = 1 + (minor << gd->minor_shift);
605                                      j < ((minor + 1) << gd->minor_shift);
606                                      j++)
607                                         gd->part[j].nr_sects = 0;
608                         }
609                 }
610         }
611         return bdev;
612 }
613
614 /*
615  * Initialise the driver.
616  */
617 static __init int medley_init(void)
618 {
619         int c, d;
620
621         memset(raid, 0, MAX_MEDLEY_ARRAYS * sizeof(struct medley_array));
622
623         /* Probe each of the drives on our list */
624         for (c = 0; probelist[c] != MKDEV(0, 0); c++) {
625                 medley_probe_drive(MAJOR(probelist[c]),
626                                    MINOR(probelist[c]));
627         }
628
629         /* Check if the detected sets are complete */
630         for (c = 0; c < medley_arrays; c++) {
631                 if (raid[c].present != (1 << raid[c].drives) - 1) {
632                         printk(KERN_ERR "Medley RAID: "
633                                "Incomplete RAID set deleted - disks:");
634                         for (d = 0; c < raid[c].drives; c++) {
635                                 if (raid[c].present & (1 << d)) {
636                                         printk(" %02x:%02x",
637                                                MAJOR(raid[c].members[d]),
638                                                MINOR(raid[c].members[d]));
639                                 }
640                         }
641                         printk("\n");
642                         if (c + 1 < medley_arrays) {
643                                 memmove(raid + c + 1, raid + c,
644                                         (medley_arrays - c -
645                                          1) * sizeof(struct medley_array));
646                         }
647                         medley_arrays--;
648                 }
649         }
650
651         /* Register any remaining array(s) */
652         for (c = 0; c < medley_arrays; c++) {
653                 int device = ataraid_get_device(&medley_ops);
654                 if (device < 0) {
655                         printk(KERN_ERR "Medley RAID: "
656                                "Could not get ATARAID device.\n");
657                         break;
658                 }
659                 if (c == 0) {
660                         /* First array, compute offset to our device ID's */
661                         medley_devid_offset = device;
662                         dprintk("Medley_devid_offset: %d\n",
663                                 medley_devid_offset);
664                 } else if (device - medley_devid_offset != c) {
665                         printk(KERN_ERR "Medley RAID: "
666                                "ATARAID gave us an illegal device ID.\n");
667                         ataraid_release_device(device);
668                         break;
669                 }
670
671                 printk(KERN_INFO "Medley RAID: "
672                        "Striped set %d consists of %d disks, total %dMiB "
673                        "- disks:",
674                        c, raid[c].drives,
675                        raid[c].sectors / 1024 / 1024 / 2);
676                 for (d = 0; d < raid[c].drives; d++) {
677                         printk(" %02x:%02x", MAJOR(raid[c].members[d]),
678                                MINOR(raid[c].members[d]));
679                         raid[c].bdev[d] = get_device_lock(raid[c].members[d]);
680                 }
681                 printk("\n");
682                 raid[c].registered = 1;
683                 atomic_set(&(raid[c].valid), 1);
684                 ataraid_register_disk(c, raid[c].sectors);
685         }
686
687         if (medley_arrays > 0) {
688                 printk(KERN_INFO "Medley RAID: %d active RAID set%s\n",
689                        medley_arrays, medley_arrays == 1 ? "" : "s");
690                 return 0;
691         }
692
693         printk(KERN_INFO "Medley RAID: No usable RAID sets found\n");
694         return -ENODEV;
695 }
696
697 /*
698  * Remove the arrays and clean up.
699  */
700 static void __exit medley_exit(void)
701 {
702         int device, d;
703         for (device = 0; device < medley_arrays; device++) {
704                 for (d = 0; d < raid[device].drives; d++) {
705                         if (raid[device].bdev[d]) {
706                                 blkdev_put(raid[device].bdev[d], BDEV_RAW);
707                                 raid[device].bdev[d] = NULL;
708                         }
709                 }
710                 if (raid[device].registered) {
711                         ataraid_release_device(device +
712                                                medley_devid_offset);
713                         raid[device].registered = 0;
714                 }
715         }
716 }
717
718 /*
719  * Called to open the virtual device
720  */
721 static int medley_open(struct inode *inode, struct file *filp)
722 {
723         int device = ((inode->i_rdev >> SHIFT) & MAJOR_MASK) -
724             medley_devid_offset;
725         dprintk("medley_open\n");
726
727         if (device < medley_arrays) {
728                 while (!atomic_read(&(raid[device].valid)))
729                         sleep_on(&medley_wait_open);
730                 raid[device].access++;
731                 MOD_INC_USE_COUNT;
732                 return (0);
733         }
734         return -ENODEV;
735 }
736
737 /*
738  * Called to release the handle on the virtual device
739  */
740 static int medley_release(struct inode *inode, struct file *filp)
741 {
742         int device = ((inode->i_rdev >> SHIFT) & MAJOR_MASK) -
743             medley_devid_offset;
744         dprintk("medley_release\n");
745         raid[device].access--;
746         MOD_DEC_USE_COUNT;
747         return 0;
748 }
749
750 module_init(medley_init);
751 module_exit(medley_exit);
752 MODULE_LICENSE("GPL");