b5f2b14b4299e45d085ac89b99afa82f7fdd1a77
[linux-2.6.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 file may be distributed separately from the Linux kernel, or
11  * incorporated into other software packages, subject to the following license:
12  * 
13  * Permission is hereby granted, free of charge, to any person obtaining a copy
14  * of this source file (the "Software"), to deal in the Software without
15  * restriction, including without limitation the rights to use, copy, modify,
16  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
17  * and to permit persons to whom the Software is furnished to do so, subject to
18  * the following conditions:
19  * 
20  * The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22  * 
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  * IN THE SOFTWARE.
30  */
31
32 #include "block.h"
33 #include <linux/blkdev.h>
34 #include <linux/list.h>
35
36 /*
37  * For convenience we distinguish between ide, scsi and 'other' (i.e.,
38  * potentially combinations of the two) in the naming scheme and in a few other
39  * places.
40  */
41
42 #define NUM_IDE_MAJORS 10
43 #define NUM_SCSI_MAJORS 9
44 #define NUM_VBD_MAJORS 1
45
46 struct lvdisk
47 {
48     blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
49     blkif_vdev_t   device;   /*  8: Device number (opaque 16 bit value). */
50     u16            info; 
51     struct list_head list;
52 };
53
54 static struct xlbd_type_info xlbd_ide_type = {
55     .partn_shift = 6,
56     .partn_per_major = 2,
57     .devname = "ide",
58     .diskname = "hd",
59 };
60
61 static struct xlbd_type_info xlbd_scsi_type = {
62     .partn_shift = 4,
63     .partn_per_major = 16,
64     .devname = "sd",
65     .diskname = "sd",
66 };
67
68 static struct xlbd_type_info xlbd_vbd_type = {
69     .partn_shift = 4,
70     .partn_per_major = 16,
71     .devname = "xvd",
72     .diskname = "xvd",
73 };
74
75 static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
76                                          NUM_VBD_MAJORS];
77
78 #define XLBD_MAJOR_IDE_START    0
79 #define XLBD_MAJOR_SCSI_START   (NUM_IDE_MAJORS)
80 #define XLBD_MAJOR_VBD_START    (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
81
82 #define XLBD_MAJOR_IDE_RANGE    XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
83 #define XLBD_MAJOR_SCSI_RANGE   XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
84 #define XLBD_MAJOR_VBD_RANGE    XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
85
86 /* Information about our VBDs. */
87 #define MAX_VBDS 64
88 struct list_head vbds_list;
89
90 struct request_queue *xlbd_blk_queue = NULL;
91
92 #define MAJOR_XEN(dev) ((dev)>>8)
93 #define MINOR_XEN(dev) ((dev) & 0xff)
94
95 static struct block_device_operations xlvbd_block_fops = 
96 {
97     .owner  = THIS_MODULE,
98     .open  = blkif_open,
99     .release = blkif_release,
100     .ioctl  = blkif_ioctl,
101 };
102
103 spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
104
105 static struct lvdisk * xlvbd_device_alloc(void)
106 {
107     struct lvdisk *ret;
108
109     ret = kmalloc(sizeof(struct lvdisk), GFP_KERNEL);
110     if ( ret ) {
111         memset(ret, '\0', sizeof(struct lvdisk));
112         INIT_LIST_HEAD(&ret->list);
113     }
114     return ret;
115 }
116
117 static void xlvbd_device_free(struct lvdisk *disk)
118 {
119     list_del(&disk->list);
120     kfree(disk);
121 }
122
123 static vdisk_t * xlvbd_probe(int *ret)
124 {
125     blkif_response_t rsp;
126     blkif_request_t req;
127     vdisk_t *disk_info = NULL;
128     unsigned long buf;
129     int nr;
130
131     buf = __get_free_page(GFP_KERNEL);
132     if ( !buf )
133         goto out;
134
135     memset(&req, 0, sizeof(req));
136     req.operation = BLKIF_OP_PROBE;
137     req.nr_segments = 1;
138 #ifdef CONFIG_XEN_BLKDEV_GRANT
139     blkif_control_probe_send(&req, &rsp,
140                              (unsigned long)(virt_to_machine(buf)));
141 #else
142     req.frame_and_sects[0] = virt_to_machine(buf) | 7;
143
144     blkif_control_send(&req, &rsp);
145 #endif
146     if ( rsp.status <= 0 ) {
147         printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
148         goto out;
149     }
150     nr = rsp.status;
151     if ( nr > MAX_VBDS )
152         nr = MAX_VBDS;
153
154     disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
155     if ( disk_info )
156         memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
157     if ( ret )
158         *ret = nr;
159 out:
160     free_page(buf);
161     return disk_info;
162 }
163
164 static struct xlbd_major_info *xlbd_alloc_major_info(int major, int minor, int index)
165 {
166     struct xlbd_major_info *ptr;
167
168     ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
169     if ( !ptr )
170         return NULL;
171
172     memset(ptr, 0, sizeof(struct xlbd_major_info));
173
174     ptr->major = major;
175
176     switch (index) {
177     case XLBD_MAJOR_IDE_RANGE:
178         ptr->type = &xlbd_ide_type;
179         ptr->index = index - XLBD_MAJOR_IDE_START;
180         break;
181     case XLBD_MAJOR_SCSI_RANGE:
182         ptr->type = &xlbd_scsi_type;
183         ptr->index = index - XLBD_MAJOR_SCSI_START;
184         break;
185     case XLBD_MAJOR_VBD_RANGE:
186         ptr->type = &xlbd_vbd_type;
187         ptr->index = index - XLBD_MAJOR_VBD_START;
188         break;
189     }
190     
191     if ( register_blkdev(ptr->major, ptr->type->devname) ) {
192         printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
193                     ptr->major, ptr->type->devname);
194         kfree(ptr);
195         return NULL;
196     }
197
198     devfs_mk_dir(ptr->type->devname);
199     major_info[index] = ptr;
200     return ptr;
201 }
202
203 static struct xlbd_major_info *xlbd_get_major_info(int device)
204 {
205     int major, minor, index;
206
207     major = MAJOR_XEN(device);
208     minor = MINOR_XEN(device);
209
210     switch (major) {
211     case IDE0_MAJOR: index = 0; break;
212     case IDE1_MAJOR: index = 1; break;
213     case IDE2_MAJOR: index = 2; break;
214     case IDE3_MAJOR: index = 3; break;
215     case IDE4_MAJOR: index = 4; break;
216     case IDE5_MAJOR: index = 5; break;
217     case IDE6_MAJOR: index = 6; break;
218     case IDE7_MAJOR: index = 7; break;
219     case IDE8_MAJOR: index = 8; break;
220     case IDE9_MAJOR: index = 9; break;
221     case SCSI_DISK0_MAJOR: index = 10; break;
222     case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
223         index = 11 + major - SCSI_DISK1_MAJOR;
224         break;
225     case SCSI_CDROM_MAJOR: index = 18; break;
226     default: index = 19; break;
227     }
228
229     return major_info[index]
230         ? major_info[index]
231         : xlbd_alloc_major_info(major, minor, index);
232 }
233
234 static int xlvbd_blk_queue_alloc(struct xlbd_type_info *type)
235 {
236     xlbd_blk_queue = blk_init_queue(do_blkif_request, &blkif_io_lock);
237     if ( !xlbd_blk_queue )
238         return -1;
239
240     elevator_init(xlbd_blk_queue, "noop");
241
242     /*
243     * Turn off barking 'headactive' mode. We dequeue
244     * buffer heads as soon as we pass them to back-end
245     * driver.
246     */
247     blk_queue_headactive(xlbd_blk_queue, 0);
248
249     /* Hard sector size and max sectors impersonate the equiv. hardware. */
250     blk_queue_hardsect_size(xlbd_blk_queue, 512);
251     blk_queue_max_sectors(xlbd_blk_queue, 512);
252
253     /* Each segment in a request is up to an aligned page in size. */
254     blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1);
255     blk_queue_max_segment_size(xlbd_blk_queue, PAGE_SIZE);
256
257     /* Ensure a merged request will fit in a single I/O ring slot. */
258     blk_queue_max_phys_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
259     blk_queue_max_hw_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
260
261     /* Make sure buffer addresses are sector-aligned. */
262     blk_queue_dma_alignment(xlbd_blk_queue, 511);
263     return 0;
264 }
265
266 struct gendisk *xlvbd_alloc_gendisk(struct xlbd_major_info *mi, int minor,
267                     vdisk_t *disk)
268 {
269     struct gendisk *gd;
270     struct xlbd_disk_info *di;
271     int nb_minors;
272
273     di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
274     if ( !di )
275         goto out;
276     di->mi = mi;
277     di->xd_device = disk->device;
278
279     nb_minors = ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
280             ? mi->type->partn_per_major
281             : 1;
282
283     gd = alloc_disk(nb_minors);
284     if ( !gd )
285         goto out;
286
287     if ( nb_minors > 1 )
288         sprintf(gd->disk_name, "%s%c", mi->type->diskname,
289                 'a' + mi->index * mi->type->partn_per_major +
290                     (minor >> mi->type->partn_shift));
291     else
292         sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
293                 'a' + mi->index * mi->type->partn_per_major +
294                     (minor >> mi->type->partn_shift),
295                 minor & ((1 << mi->type->partn_shift) - 1));
296
297     gd->major = mi->major;
298     gd->first_minor = minor;
299     gd->fops = &xlvbd_block_fops;
300     gd->private_data = di;
301     set_capacity(gd, disk->capacity);
302
303     if ( !xlbd_blk_queue )
304         if ( xlvbd_blk_queue_alloc(mi->type) )
305             goto out_gendisk;
306
307     gd->queue = xlbd_blk_queue;
308     add_disk(gd);
309     return gd;
310 out_gendisk:
311     printk(KERN_ALERT "error gendisk\n");
312     del_gendisk(gd);
313 out:
314     printk(KERN_ALERT "error out\n");
315     kfree(di);
316     return NULL;
317 }
318
319 static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
320 {
321     struct lvdisk *new;
322     int minor;
323     dev_t device;
324     struct block_device *bd;
325     struct gendisk *gd;
326     struct xlbd_major_info *mi;
327
328     mi = xlbd_get_major_info(disk->device);
329     if ( !mi )
330         return -EPERM;
331
332     new = xlvbd_device_alloc();
333     if ( !new )
334         return -1;
335     new->capacity = disk->capacity;
336     new->device = disk->device;
337     new->info = disk->info;
338     
339     minor = MINOR_XEN(disk->device);
340     device = MKDEV(mi->major, minor);
341     
342     bd = bdget(device);
343     if ( !bd )
344         goto out;
345     
346     gd = xlvbd_alloc_gendisk(mi, minor, disk);
347     if ( !gd )
348         goto out_bd;
349
350     if ( VDISK_READONLY(disk->info) )
351         set_disk_ro(gd, 1);
352
353     switch (VDISK_TYPE(disk->info)) {
354     case VDISK_TYPE_CDROM:
355         gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD;
356         break;
357     case VDISK_TYPE_FLOPPY: 
358     case VDISK_TYPE_TAPE:
359         gd->flags |= GENHD_FL_REMOVABLE;
360         break;
361     case VDISK_TYPE_DISK:
362         break;
363     default:
364         printk(KERN_ALERT "XenLinux: unknown device type %d\n",
365                         VDISK_TYPE(disk->info));
366         break;
367     }    
368
369     list_add(&new->list, list);
370 out_bd:
371     bdput(bd);
372 out:
373     return 0;
374 }
375
376 static int xlvbd_device_del(struct lvdisk *disk)
377 {
378     dev_t device;
379     struct block_device *bd;
380     struct gendisk *gd;
381     struct xlbd_disk_info *di;
382     int ret = 0, unused;
383
384     device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
385
386     bd = bdget(device);
387     if ( !bd )
388         return -1;
389
390     gd = get_gendisk(device, &unused);
391     di = gd->private_data;
392
393     if ( di->mi->usage != 0 ) {
394         printk(KERN_ALERT "VBD removal failed: used [dev=%x]\n", device);
395         ret = -1;
396         goto out;
397     }
398
399     del_gendisk(gd);
400
401     xlvbd_device_free(disk);
402 out:
403     bdput(bd);
404     return ret;
405 }
406
407 static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
408 {
409     dev_t device;
410     struct block_device *bd;
411     struct gendisk *gd;
412     int unused;
413
414     if ( ldisk->capacity == disk->capacity && ldisk->info == disk->info )
415         return 0;    
416
417     device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
418
419     bd = bdget(device);
420     if ( !bd )
421         return -1;
422
423     gd = get_gendisk(device, &unused);
424     set_capacity(gd, disk->capacity);    
425     ldisk->capacity = disk->capacity;
426
427     bdput(bd);
428
429     return 0;
430 }
431
432 void xlvbd_refresh(void)
433 {
434     vdisk_t *newdisks;
435     struct list_head *tmp, *tmp2;
436     struct lvdisk *disk;
437     int i, nr;
438
439     newdisks = xlvbd_probe(&nr);
440     if ( !newdisks ) {
441         printk(KERN_ALERT "failed to probe\n");
442         return;
443     }
444     
445     i = 0;
446     list_for_each_safe(tmp, tmp2, &vbds_list) {
447         disk = list_entry(tmp, struct lvdisk, list);
448         
449         for (i = 0; i < nr; i++) {
450             if ( !newdisks[i].device )
451                 continue;
452             if ( disk->device == newdisks[i].device ) {
453                 xlvbd_device_update(disk, &newdisks[i]);
454                 newdisks[i].device = 0;
455                 break;
456             }
457         }
458         if ( i == nr ) {
459             xlvbd_device_del(disk);
460             newdisks[i].device = 0;
461         }
462     }
463     for (i = 0; i < nr; i++)
464         if ( newdisks[i].device )
465             xlvbd_device_add(&vbds_list, &newdisks[i]);
466     kfree(newdisks);
467 }
468
469 /*
470  * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
471  * state. The VBDs need to be updated in this way when the domain is
472  * initialised and also each time we receive an XLBLK_UPDATE event.
473  */
474 void xlvbd_update_vbds(void)
475 {
476     xlvbd_refresh();
477 }
478
479 /*
480  * Set up all the linux device goop for the virtual block devices
481  * (vbd's) that we know about. Note that although from the backend
482  * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
483  * number, the domain creation tools conventionally allocate these
484  * numbers to correspond to those used by 'real' linux -- this is just
485  * for convenience as it means e.g. that the same /etc/fstab can be
486  * used when booting with or without Xen.
487  */
488 int xlvbd_init(void)
489 {
490     int i, nr;
491     vdisk_t *disks;
492
493     INIT_LIST_HEAD(&vbds_list);
494
495     memset(major_info, 0, sizeof(major_info));
496     
497     disks = xlvbd_probe(&nr);
498     if ( !disks ) {
499         printk(KERN_ALERT "failed to probe\n");
500         return -1;
501     }
502
503     for (i = 0; i < nr; i++)
504         xlvbd_device_add(&vbds_list, &disks[i]);
505     kfree(disks);
506     return 0;
507 }