Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / blkfront / vbd.c
1 /******************************************************************************
2  * vbd.c
3  * 
4  * XenLinux virtual block-device driver (xvd).
5  * 
6  * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
7  * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
8  * Copyright (c) 2004-2005, Christian Limpach
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation; or, when distributed
13  * separately from the Linux kernel or incorporated into other
14  * software packages, subject to the following license:
15  * 
16  * Permission is hereby granted, free of charge, to any person obtaining a copy
17  * of this source file (the "Software"), to deal in the Software without
18  * restriction, including without limitation the rights to use, copy, modify,
19  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
20  * and to permit persons to whom the Software is furnished to do so, subject to
21  * the following conditions:
22  * 
23  * The above copyright notice and this permission notice shall be included in
24  * all copies or substantial portions of the Software.
25  * 
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32  * IN THE SOFTWARE.
33  */
34
35 #include "block.h"
36 #include <linux/bitmap.h>
37 #include <linux/blkdev.h>
38 #include <linux/list.h>
39
40 #ifdef HAVE_XEN_PLATFORM_COMPAT_H
41 #include <xen/platform-compat.h>
42 #endif
43
44 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
45 #define XENVBD_MAJOR 202
46 #endif
47
48 #define BLKIF_MAJOR(dev) ((dev)>>8)
49 #define BLKIF_MINOR(dev) ((dev) & 0xff)
50
51 #define EXT_SHIFT 28
52 #define EXTENDED (1<<EXT_SHIFT)
53 #define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
54 #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
55
56 struct xlbd_minor_state {
57         unsigned int nr;
58         unsigned long *bitmap;
59         spinlock_t lock;
60 };
61
62 /*
63  * For convenience we distinguish between ide, scsi and 'other' (i.e.,
64  * potentially combinations of the two) in the naming scheme and in a few other
65  * places.
66  */
67
68 #define NUM_IDE_MAJORS 10
69 #define NUM_SD_MAJORS 16
70 #define NUM_VBD_MAJORS 2
71
72 struct xlbd_type_info
73 {
74         int partn_shift;
75         int disks_per_major;
76         char *devname;
77         char *diskname;
78 };
79
80 static const struct xlbd_type_info xlbd_ide_type = {
81         .partn_shift = 6,
82         .disks_per_major = 2,
83         .devname = "ide",
84         .diskname = "hd",
85 };
86
87 static const struct xlbd_type_info xlbd_sd_type = {
88         .partn_shift = 4,
89         .disks_per_major = 16,
90         .devname = "sd",
91         .diskname = "sd",
92 };
93
94 static const struct xlbd_type_info xlbd_sr_type = {
95         .partn_shift = 0,
96         .disks_per_major = 256,
97         .devname = "sr",
98         .diskname = "sr",
99 };
100
101 static const struct xlbd_type_info xlbd_vbd_type = {
102         .partn_shift = 4,
103         .disks_per_major = 16,
104         .devname = "xvd",
105         .diskname = "xvd",
106 };
107
108 static const struct xlbd_type_info xlbd_vbd_type_ext = {
109         .partn_shift = 8,
110         .disks_per_major = 256,
111         .devname = "xvd",
112         .diskname = "xvd",
113 };
114
115 static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SD_MAJORS + 1 +
116                                          NUM_VBD_MAJORS];
117
118 #define XLBD_MAJOR_IDE_START    0
119 #define XLBD_MAJOR_SD_START     (NUM_IDE_MAJORS)
120 #define XLBD_MAJOR_SR_START     (NUM_IDE_MAJORS + NUM_SD_MAJORS)
121 #define XLBD_MAJOR_VBD_START    (NUM_IDE_MAJORS + NUM_SD_MAJORS + 1)
122
123 #define XLBD_MAJOR_IDE_RANGE    XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SD_START - 1
124 #define XLBD_MAJOR_SD_RANGE     XLBD_MAJOR_SD_START ... XLBD_MAJOR_SR_START - 1
125 #define XLBD_MAJOR_SR_RANGE     XLBD_MAJOR_SR_START
126 #define XLBD_MAJOR_VBD_RANGE    XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
127
128 #define XLBD_MAJOR_VBD_ALT(idx) ((idx) ^ XLBD_MAJOR_VBD_START ^ (XLBD_MAJOR_VBD_START + 1))
129
130 static const struct block_device_operations xlvbd_block_fops =
131 {
132         .owner = THIS_MODULE,
133         .open = blkif_open,
134         .release = blkif_release,
135         .ioctl  = blkif_ioctl,
136 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
137         .getgeo = blkif_getgeo
138 #endif
139 };
140
141 static struct xlbd_major_info *
142 xlbd_alloc_major_info(int major, int minor, int index)
143 {
144         struct xlbd_major_info *ptr;
145         struct xlbd_minor_state *minors;
146         int do_register;
147
148         ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
149         if (ptr == NULL)
150                 return NULL;
151
152         ptr->major = major;
153         minors = kmalloc(sizeof(*minors), GFP_KERNEL);
154         if (minors == NULL) {
155                 kfree(ptr);
156                 return NULL;
157         }
158
159         minors->bitmap = kzalloc(BITS_TO_LONGS(256) * sizeof(*minors->bitmap),
160                                  GFP_KERNEL);
161         if (minors->bitmap == NULL) {
162                 kfree(minors);
163                 kfree(ptr);
164                 return NULL;
165         }
166
167         spin_lock_init(&minors->lock);
168         minors->nr = 256;
169         do_register = 1;
170
171         switch (index) {
172         case XLBD_MAJOR_IDE_RANGE:
173                 ptr->type = &xlbd_ide_type;
174                 ptr->index = index - XLBD_MAJOR_IDE_START;
175                 break;
176         case XLBD_MAJOR_SD_RANGE:
177                 ptr->type = &xlbd_sd_type;
178                 ptr->index = index - XLBD_MAJOR_SD_START;
179                 break;
180         case XLBD_MAJOR_SR_RANGE:
181                 ptr->type = &xlbd_sr_type;
182                 ptr->index = index - XLBD_MAJOR_SR_START;
183                 break;
184         case XLBD_MAJOR_VBD_RANGE:
185                 ptr->index = 0;
186                 if ((index - XLBD_MAJOR_VBD_START) == 0)
187                         ptr->type = &xlbd_vbd_type;
188                 else
189                         ptr->type = &xlbd_vbd_type_ext;
190
191                 /* 
192                  * if someone already registered block major XENVBD_MAJOR,
193                  * don't try to register it again
194                  */
195                 if (major_info[XLBD_MAJOR_VBD_ALT(index)] != NULL) {
196                         kfree(minors->bitmap);
197                         kfree(minors);
198                         minors = major_info[XLBD_MAJOR_VBD_ALT(index)]->minors;
199                         do_register = 0;
200                 }
201                 break;
202         }
203
204         if (do_register) {
205                 if (register_blkdev(ptr->major, ptr->type->devname)) {
206                         kfree(minors->bitmap);
207                         kfree(minors);
208                         kfree(ptr);
209                         return NULL;
210                 }
211
212                 pr_info("xen-vbd: registered block device major %i\n",
213                         ptr->major);
214         }
215
216         ptr->minors = minors;
217         major_info[index] = ptr;
218         return ptr;
219 }
220
221 static struct xlbd_major_info *
222 xlbd_get_major_info(int major, int minor, int vdevice)
223 {
224         struct xlbd_major_info *mi;
225         int index;
226
227         switch (major) {
228         case IDE0_MAJOR: index = 0; break;
229         case IDE1_MAJOR: index = 1; break;
230         case IDE2_MAJOR: index = 2; break;
231         case IDE3_MAJOR: index = 3; break;
232         case IDE4_MAJOR: index = 4; break;
233         case IDE5_MAJOR: index = 5; break;
234         case IDE6_MAJOR: index = 6; break;
235         case IDE7_MAJOR: index = 7; break;
236         case IDE8_MAJOR: index = 8; break;
237         case IDE9_MAJOR: index = 9; break;
238         case SCSI_DISK0_MAJOR: index = XLBD_MAJOR_SD_START; break;
239         case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
240                 index = XLBD_MAJOR_SD_START + 1 + major - SCSI_DISK1_MAJOR;
241                 break;
242         case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
243                 index = XLBD_MAJOR_SD_START + 8 + major - SCSI_DISK8_MAJOR;
244                 break;
245         case SCSI_CDROM_MAJOR:
246                 index = XLBD_MAJOR_SR_START;
247                 break;
248         case XENVBD_MAJOR:
249                 index = XLBD_MAJOR_VBD_START + !!VDEV_IS_EXTENDED(vdevice);
250                 break;
251         default:
252                 return NULL;
253         }
254
255         mi = ((major_info[index] != NULL) ? major_info[index] :
256               xlbd_alloc_major_info(major, minor, index));
257         if (mi)
258                 mi->usage++;
259         return mi;
260 }
261
262 static void
263 xlbd_put_major_info(struct xlbd_major_info *mi)
264 {
265         mi->usage--;
266         /* XXX: release major if 0 */
267 }
268
269 void __exit
270 xlbd_release_major_info(void)
271 {
272         unsigned int i;
273         int vbd_done = 0;
274
275         for (i = 0; i < ARRAY_SIZE(major_info); ++i) {
276                 struct xlbd_major_info *mi = major_info[i];
277
278                 if (!mi)
279                         continue;
280                 if (mi->usage)
281                         pr_warning("vbd: major %u still in use (%u times)\n",
282                                    mi->major, mi->usage);
283                 if (mi->major != XENVBD_MAJOR || !vbd_done) {
284                         unregister_blkdev(mi->major, mi->type->devname);
285                         kfree(mi->minors->bitmap);
286                         kfree(mi->minors);
287                 }
288                 if (mi->major == XENVBD_MAJOR)
289                         vbd_done = 1;
290                 kfree(mi);
291         }
292 }
293
294 static int
295 xlbd_reserve_minors(struct xlbd_major_info *mi, unsigned int minor,
296                     unsigned int nr_minors)
297 {
298         struct xlbd_minor_state *ms = mi->minors;
299         unsigned int end = minor + nr_minors;
300         int rc;
301
302         if (end > ms->nr) {
303                 unsigned long *bitmap, *old;
304
305                 bitmap = kcalloc(BITS_TO_LONGS(end), sizeof(*bitmap),
306                                  GFP_KERNEL);
307                 if (bitmap == NULL)
308                         return -ENOMEM;
309
310                 spin_lock(&ms->lock);
311                 if (end > ms->nr) {
312                         old = ms->bitmap;
313                         memcpy(bitmap, ms->bitmap,
314                                BITS_TO_LONGS(ms->nr) * sizeof(*bitmap));
315                         ms->bitmap = bitmap;
316                         ms->nr = BITS_TO_LONGS(end) * BITS_PER_LONG;
317                 } else
318                         old = bitmap;
319                 spin_unlock(&ms->lock);
320                 kfree(old);
321         }
322
323         spin_lock(&ms->lock);
324         if (find_next_bit(ms->bitmap, end, minor) >= end) {
325                 bitmap_set(ms->bitmap, minor, nr_minors);
326                 rc = 0;
327         } else
328                 rc = -EBUSY;
329         spin_unlock(&ms->lock);
330
331         return rc;
332 }
333
334 static void
335 xlbd_release_minors(struct xlbd_major_info *mi, unsigned int minor,
336                     unsigned int nr_minors)
337 {
338         struct xlbd_minor_state *ms = mi->minors;
339
340         BUG_ON(minor + nr_minors > ms->nr);
341         spin_lock(&ms->lock);
342         bitmap_clear(ms->bitmap, minor, nr_minors);
343         spin_unlock(&ms->lock);
344 }
345
346 static char *encode_disk_name(char *ptr, unsigned int n)
347 {
348         if (n >= 26)
349                 ptr = encode_disk_name(ptr, n / 26 - 1);
350         *ptr = 'a' + n % 26;
351         return ptr + 1;
352 }
353
354 static int
355 xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
356                      struct blkfront_info *info)
357 {
358         struct request_queue *rq;
359
360         rq = blk_init_queue(do_blkif_request, &info->io_lock);
361         if (rq == NULL)
362                 return -1;
363
364 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
365         queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
366 #endif
367
368         if (info->feature_discard) {
369                 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq);
370                 blk_queue_max_discard_sectors(rq, get_capacity(gd));
371                 rq->limits.discard_granularity = info->discard_granularity;
372                 rq->limits.discard_alignment = info->discard_alignment;
373                 if (info->feature_secdiscard)
374                         queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, rq);
375         }
376
377         /* Hard sector size and max sectors impersonate the equiv. hardware. */
378         blk_queue_logical_block_size(rq, sector_size);
379         blk_queue_max_hw_sectors(rq, 512);
380
381         /* Each segment in a request is up to an aligned page in size. */
382         blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
383         blk_queue_max_segment_size(rq, PAGE_SIZE);
384
385         /* Ensure a merged request will fit in a single I/O ring slot. */
386         blk_queue_max_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
387
388         /* Make sure buffer addresses are sector-aligned. */
389         blk_queue_dma_alignment(rq, 511);
390
391         /* Make sure we don't use bounce buffers. */
392         blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY);
393
394         gd->queue = rq;
395         info->rq = rq;
396
397         return 0;
398 }
399
400 int
401 xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info,
402           u16 sector_size, struct blkfront_info *info)
403 {
404         int major, minor;
405         struct gendisk *gd;
406         struct xlbd_major_info *mi;
407         int nr_minors = 1;
408         int err = -ENODEV;
409         char *ptr;
410         unsigned int offset;
411
412         if ((vdevice>>EXT_SHIFT) > 1) {
413                 /* this is above the extended range; something is wrong */
414                 pr_warning("blkfront: vdevice %#x is above the extended range;"
415                            " ignoring\n", vdevice);
416                 return -ENODEV;
417         }
418
419         if (!VDEV_IS_EXTENDED(vdevice)) {
420                 major = BLKIF_MAJOR(vdevice);
421                 minor = BLKIF_MINOR(vdevice);
422         }
423         else {
424                 major = XENVBD_MAJOR;
425                 minor = BLKIF_MINOR_EXT(vdevice);
426                 if (minor >> MINORBITS) {
427                         pr_warning("blkfront: %#x's minor (%#x) out of range;"
428                                    " ignoring\n", vdevice, minor);
429                         return -ENODEV;
430                 }
431         }
432
433         BUG_ON(info->gd != NULL);
434         BUG_ON(info->mi != NULL);
435         BUG_ON(info->rq != NULL);
436
437         mi = xlbd_get_major_info(major, minor, vdevice);
438         if (mi == NULL)
439                 goto out;
440         info->mi = mi;
441
442         if ((vdisk_info & VDISK_CDROM) ||
443             !(minor & ((1 << mi->type->partn_shift) - 1)))
444                 nr_minors = 1 << mi->type->partn_shift;
445
446         err = xlbd_reserve_minors(mi, minor & ~(nr_minors - 1), nr_minors);
447         if (err)
448                 goto out;
449         err = -ENODEV;
450
451         gd = alloc_disk(vdisk_info & VDISK_CDROM ? 1 : nr_minors);
452         if (gd == NULL)
453                 goto release;
454
455         strcpy(gd->disk_name, mi->type->diskname);
456         ptr = gd->disk_name + strlen(mi->type->diskname);
457         offset = mi->index * mi->type->disks_per_major +
458                  (minor >> mi->type->partn_shift);
459         if (mi->type->partn_shift) {
460                 ptr = encode_disk_name(ptr, offset);
461                 offset = minor & ((1 << mi->type->partn_shift) - 1);
462         } else
463                 gd->flags |= GENHD_FL_CD;
464         BUG_ON(ptr >= gd->disk_name + ARRAY_SIZE(gd->disk_name));
465         if (nr_minors > 1)
466                 *ptr = 0;
467         else
468                 snprintf(ptr, gd->disk_name + ARRAY_SIZE(gd->disk_name) - ptr,
469                          "%u", offset);
470
471         gd->major = mi->major;
472         gd->first_minor = minor;
473         gd->fops = &xlvbd_block_fops;
474         gd->private_data = info;
475         gd->driverfs_dev = &(info->xbdev->dev);
476         set_capacity(gd, capacity);
477
478         if (xlvbd_init_blk_queue(gd, sector_size, info)) {
479                 del_gendisk(gd);
480                 goto release;
481         }
482
483         info->gd = gd;
484
485         xlvbd_flush(info);
486
487         if (vdisk_info & VDISK_READONLY)
488                 set_disk_ro(gd, 1);
489
490         if (vdisk_info & VDISK_REMOVABLE)
491                 gd->flags |= GENHD_FL_REMOVABLE;
492
493         if (vdisk_info & VDISK_CDROM)
494                 gd->flags |= GENHD_FL_CD;
495
496         return 0;
497
498  release:
499         xlbd_release_minors(mi, minor, nr_minors);
500  out:
501         if (mi)
502                 xlbd_put_major_info(mi);
503         info->mi = NULL;
504         return err;
505 }
506
507 void
508 xlvbd_del(struct blkfront_info *info)
509 {
510         unsigned int minor, nr_minors;
511
512         if (info->mi == NULL)
513                 return;
514
515         BUG_ON(info->gd == NULL);
516         minor = info->gd->first_minor;
517         nr_minors = (info->gd->flags & GENHD_FL_CD)
518                     || !(minor & ((1 << info->mi->type->partn_shift) - 1))
519                     ? 1 << info->mi->type->partn_shift : 1;
520         del_gendisk(info->gd);
521         put_disk(info->gd);
522         info->gd = NULL;
523
524         xlbd_release_minors(info->mi, minor & ~(nr_minors - 1), nr_minors);
525         xlbd_put_major_info(info->mi);
526         info->mi = NULL;
527
528         BUG_ON(info->rq == NULL);
529         blk_cleanup_queue(info->rq);
530         info->rq = NULL;
531 }
532
533 void
534 xlvbd_flush(struct blkfront_info *info)
535 {
536 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
537         blk_queue_flush(info->rq, info->feature_flush);
538         pr_info("blkfront: %s: %s: %s\n",
539                 info->gd->disk_name,
540                 info->flush_op == BLKIF_OP_WRITE_BARRIER ?
541                 "barrier" : (info->flush_op == BLKIF_OP_FLUSH_DISKCACHE ?
542                              "flush diskcache" : "barrier or flush"),
543                 info->feature_flush ? "enabled" : "disabled");
544 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
545         int err;
546         const char *barrier;
547
548         switch (info->feature_flush) {
549         case QUEUE_ORDERED_DRAIN:       barrier = "enabled (drain)"; break;
550         case QUEUE_ORDERED_TAG:         barrier = "enabled (tag)"; break;
551         case QUEUE_ORDERED_NONE:        barrier = "disabled"; break;
552         default:                        return -EINVAL;
553         }
554
555         err = blk_queue_ordered(info->rq, info->feature_flush);
556         if (err)
557                 return err;
558         pr_info("blkfront: %s: barriers %s\n",
559                 info->gd->disk_name, barrier);
560 #else
561         if (info->feature_flush)
562                 pr_info("blkfront: %s: barriers disabled\n", info->gd->disk_name);
563 #endif
564 }
565
566 #ifdef CONFIG_SYSFS
567 static ssize_t show_media(struct device *dev,
568                                   struct device_attribute *attr, char *buf)
569 {
570         struct xenbus_device *xendev = to_xenbus_device(dev);
571         struct blkfront_info *info = dev_get_drvdata(&xendev->dev);
572
573         if (info->gd->flags & GENHD_FL_CD)
574                 return sprintf(buf, "cdrom\n");
575         return sprintf(buf, "disk\n");
576 }
577
578 static struct device_attribute xlvbd_attrs[] = {
579         __ATTR(media, S_IRUGO, show_media, NULL),
580 };
581
582 int xlvbd_sysfs_addif(struct blkfront_info *info)
583 {
584         int i;
585         int error = 0;
586
587         for (i = 0; i < ARRAY_SIZE(xlvbd_attrs); i++) {
588                 error = device_create_file(info->gd->driverfs_dev,
589                                 &xlvbd_attrs[i]);
590                 if (error)
591                         goto fail;
592         }
593         return 0;
594
595 fail:
596         while (--i >= 0)
597                 device_remove_file(info->gd->driverfs_dev, &xlvbd_attrs[i]);
598         return error;
599 }
600
601 void xlvbd_sysfs_delif(struct blkfront_info *info)
602 {
603         int i;
604
605         for (i = 0; i < ARRAY_SIZE(xlvbd_attrs); i++)
606                 device_remove_file(info->gd->driverfs_dev, &xlvbd_attrs[i]);
607 }
608
609 #endif /* CONFIG_SYSFS */