- more 2.6.17 port work (still does not build)
[linux-flexiantxendom0-3.2.10.git] / drivers / dump / dump_blockdev.c
1 /*
2  * Implements the dump driver interface for saving a dump to
3  * a block device through the kernel's generic low level block I/O
4  * routines, or through polling I/O.
5  *
6  * Started: June 2002 - Mohamed Abbas <mohamed.abbas@intel.com>
7  *      Moved original lkcd kiobuf dump i/o code from dump_base.c
8  *      to use generic dump device interfaces
9  *
10  * Sept 2002 - Bharata B. Rao <bharata@in.ibm.com>
11  *      Convert dump i/o to directly use bio instead of kiobuf for 2.5
12  *
13  * Oct 2002  - Suparna Bhattacharya <suparna@in.ibm.com>
14  *      Rework to new dumpdev.h structures, implement open/close/
15  *      silence, misc fixes (blocknr removal, bio_add_page usage)
16  * Oct 2004 - Mar 2005 - Mohamed Abbas <mohamed.abbas@intel.com>
17  *                       Jason Uhlenkott <jasonuhl@sgi.com>
18  *      Implement polling I/O (adapted from lkdump, with thanks
19  *      to Nobuhiro Tachino).
20  *
21  * Copyright (C) 1999 - 2005 Silicon Graphics, Inc. All rights reserved.
22  * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
23  * Copyright (C) 2002 International Business Machines Corp.
24  * Copyright (C) 2004 FUJITSU LIMITED
25  *
26  * This code is released under version 2 of the GNU GPL.
27  */
28
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/blkdev.h>
34 #include <linux/bio.h>
35 #include <linux/diskdump.h>
36 #include <linux/dump.h>
37 #include <linux/delay.h>
38 #include <asm/dump.h>
39 #include <asm/hardirq.h>
40 #include "dump_methods.h"
41
42
43 /* ----- Support functions for interrupt-driven dumps ----- */
44
45
46 extern void *dump_page_buf;
47
48 /* The end_io callback for dump i/o completion */
49 static int
50 dump_bio_end_io(struct bio *bio, unsigned int bytes_done, int error)
51 {
52         struct dump_blockdev *dump_bdev;
53
54         if (bio->bi_size) {
55                 /* some bytes still left to transfer */
56                 return 1; /* not complete */
57         }
58
59         dump_bdev = (struct dump_blockdev *)bio->bi_private;
60         if (error) {
61                 printk("LKCD: IO error while writing the dump, aborting\n");
62         }
63
64         dump_bdev->err = error;
65
66         /* no wakeup needed, since caller polls for completion */
67         return 0;
68 }
69
70 /* Check if the dump bio is already mapped to the specified buffer */
71 static int
72 dump_block_map_valid(struct dump_blockdev *dev, struct page *page,
73         int len)
74 {
75         struct bio *bio = dev->bio;
76         unsigned long bsize = 0;
77
78         if (!bio->bi_vcnt)
79                 return 0; /* first time, not mapped */
80
81
82         if ((bio_page(bio) != page) || (len > bio->bi_vcnt << PAGE_SHIFT))
83                 return 0; /* buffer not mapped */
84
85         bsize = bdev_hardsect_size(bio->bi_bdev);
86         if ((len & (PAGE_SIZE - 1)) || (len & bsize))
87                 return 0; /* alignment checks needed */
88
89         /* quick check to decide if we need to redo bio_add_page */
90         if (bdev_get_queue(bio->bi_bdev)->merge_bvec_fn)
91                 return 0; /* device may have other restrictions */
92
93         return 1; /* already mapped */
94 }
95
96 /*
97  * Set up the dump bio for i/o from the specified buffer
98  * Return value indicates whether the full buffer could be mapped or not
99  */
100 static int
101 dump_block_map(struct dump_blockdev *dev, void *buf, int len)
102 {
103         struct page *page = virt_to_page(buf);
104         struct bio *bio = dev->bio;
105         unsigned long bsize = 0;
106
107         bio->bi_bdev = dev->bdev;
108         bio->bi_sector = (dev->start_offset + dev->ddev.curr_offset) >> 9;
109         bio->bi_idx = 0; /* reset index to the beginning */
110
111         if (dump_block_map_valid(dev, page, len)) {
112                 /* already mapped and usable rightaway */
113                 bio->bi_size = len; /* reset size to the whole bio */
114                 bio->bi_vcnt = (len + PAGE_SIZE - 1) / PAGE_SIZE; /* Set the proper vector cnt */
115         } else {
116                 /* need to map the bio */
117                 bio->bi_size = 0;
118                 bio->bi_vcnt = 0;
119                 bsize = bdev_hardsect_size(bio->bi_bdev);
120
121                 /* first a few sanity checks */
122                 if (len < bsize) {
123                         printk("LKCD: map: len less than hardsect size \n");
124                         return -EINVAL;
125                 }
126
127                 if ((unsigned long)buf & bsize) {
128                         printk("LKCD: map: not aligned\n");
129                         return -EINVAL;
130                 }
131
132                 /* assume contig. page aligned low mem buffer( no vmalloc) */
133                 if ((page_address(page) != buf) || (len & (PAGE_SIZE - 1))) {
134                         printk("LKCD: map: invalid buffer alignment!\n");
135                         return -EINVAL;
136                 }
137                 /* finally we can go ahead and map it */
138                 while (bio->bi_size < len)
139                         if (bio_add_page(bio, page++, PAGE_SIZE, 0) == 0) {
140                                 break;
141                         }
142
143                 bio->bi_end_io = dump_bio_end_io;
144                 bio->bi_private = dev;
145         }
146
147         if (bio->bi_size != len) {
148                 printk("LKCD: map: bio size = %d not enough for len = %d!\n",
149                         bio->bi_size, len);
150                 return -E2BIG;
151         }
152         return 0;
153 }
154
155 static void
156 dump_free_bio(struct bio *bio)
157 {
158         if (bio)
159                 kfree(bio->bi_io_vec);
160         kfree(bio);
161 }
162
163
164 /* ----- Support functions for polling I/O based dumps ----- */
165
166 static DECLARE_MUTEX(disk_dump_mutex);
167 static LIST_HEAD(disk_dump_types);
168 static struct disk_dump_device dump_device;
169 static struct disk_dump_partition dump_part;
170 static unsigned long long timestamp_base;
171 static unsigned long timestamp_hz;
172 static unsigned long flags_global;
173 static int polling_mode;
174 static void dump_blockdev_unconfigure(void);
175
176 void diskdump_setup_timestamp(void)
177 {
178         unsigned long long t=0;
179
180         platform_timestamp(timestamp_base);
181         udelay(1000000/HZ);
182         platform_timestamp(t);
183         timestamp_hz = (unsigned long)(t - timestamp_base);
184         diskdump_update();
185 }
186
187 void diskdump_update(void)
188 {
189         unsigned long long t=0;
190
191         touch_nmi_watchdog();
192
193         /* update jiffies */
194         platform_timestamp(t);
195         while (t > timestamp_base + timestamp_hz) {
196                 timestamp_base += timestamp_hz;
197                 jiffies++;
198                 platform_timestamp(t);
199         }
200
201         dump_run_timers();
202         dump_run_tasklet();
203         dump_run_workqueue();
204 }
205 EXPORT_SYMBOL_GPL(diskdump_update);
206
207 static void *find_real_device(struct device *dev,
208                               struct disk_dump_type **_dump_type)
209 {
210         void *real_device;
211         struct disk_dump_type *dump_type;
212
213         list_for_each_entry(dump_type, &disk_dump_types, list) {
214                 real_device = dump_type->probe(dev);
215                 if (real_device) {
216                         *_dump_type = dump_type;
217                         return real_device;
218                 }
219         }
220         return NULL;
221 }
222
223 static int register_disk_dump_device(struct device *dev, struct block_device *bdev)
224 {
225         struct disk_dump_type *dump_type = NULL;
226         void *real_device;
227         int ret = 0;
228
229         if (!bdev->bd_part)
230                 return -EINVAL;
231
232         down(&disk_dump_mutex);
233
234         real_device = find_real_device(dev, &dump_type);
235         if (!real_device) {
236                 ret = -ENXIO;
237                 goto err;
238         }
239
240         if (dump_device.device == real_device) {
241                 ret = -EEXIST;
242                 goto err;
243         } else if (dump_device.device) {
244                 BUG();
245         }
246
247         dump_device.device = real_device;
248
249         ret = dump_type->add_device(&dump_device);
250         if (ret < 0) {
251                 dump_device.device = NULL;
252                 goto err;
253         }
254
255         dump_device.dump_type = dump_type;
256         dump_part.device = &dump_device;
257         dump_part.bdev = bdev;
258         dump_part.nr_sects   = bdev->bd_part->nr_sects;
259         dump_part.start_sect = bdev->bd_part->start_sect;
260
261 err:
262         up(&disk_dump_mutex);
263         return ret;
264 }
265
266 static void unregister_disk_dump_device(struct block_device *bdev)
267 {
268         struct disk_dump_type *dump_type;
269
270         down(&disk_dump_mutex);
271
272         if(!dump_part.device) {
273                 up(&disk_dump_mutex);
274                 return;
275         }
276
277         BUG_ON(dump_part.device != &dump_device);
278         BUG_ON(dump_part.bdev != bdev);
279
280         dump_part.device = NULL;
281         dump_part.bdev = NULL;
282
283         dump_type = dump_device.dump_type;
284         dump_type->remove_device(&dump_device);
285         dump_device.device = NULL;
286         dump_device.dump_type = NULL;
287
288         up(&disk_dump_mutex);
289 }
290
291 int register_disk_dump_type(struct disk_dump_type *dump_type)
292 {
293         down(&disk_dump_mutex);
294         list_add(&dump_type->list, &disk_dump_types);
295         up(&disk_dump_mutex);
296
297         return 0;
298 }
299 EXPORT_SYMBOL_GPL(register_disk_dump_type);
300
301 int unregister_disk_dump_type(struct disk_dump_type *dump_type)
302 {
303         lock_kernel(); /* guard against the dump ioctl */
304
305         if (dump_device.dump_type == dump_type)
306                 dump_blockdev_unconfigure();
307
308         down(&disk_dump_mutex);
309         list_del(&dump_type->list);
310         up(&disk_dump_mutex);
311
312         unlock_kernel();
313         return 0;
314 }
315 EXPORT_SYMBOL_GPL(unregister_disk_dump_type);
316
317
318 /* --------------------------------------------------- */
319
320
321 static int
322 dump_block_intr_open(struct dump_dev *dev, unsigned long arg)
323 {
324         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
325         struct block_device *bdev;
326         int retval = 0;
327         struct bio_vec *bvec;
328
329         /* make sure this is a valid block device */
330         if (!arg) {
331                 retval = -EINVAL;
332                 goto err;
333         }
334
335         /* Convert it to the new dev_t format */
336         arg = MKDEV((arg >> OLDMINORBITS), (arg & OLDMINORMASK));
337
338         /* get a corresponding block_dev struct for this */
339         bdev = bdget((dev_t)arg);
340         if (!bdev) {
341                 retval = -ENODEV;
342                 goto err;
343         }
344
345         /* get the block device opened */
346         if ((retval = blkdev_get(bdev, O_RDWR | O_LARGEFILE, 0))) {
347                 goto err;
348         }
349
350         if ((dump_bdev->bio = kmalloc(sizeof(struct bio), GFP_KERNEL))
351                 == NULL) {
352                 printk("LKCD: Cannot allocate bio\n");
353                 retval = -ENOMEM;
354                 goto err1;
355         }
356
357         bio_init(dump_bdev->bio);
358
359         if ((bvec = kmalloc(sizeof(struct bio_vec) *
360                 (DUMP_BUFFER_SIZE >> PAGE_SHIFT), GFP_KERNEL)) == NULL) {
361                 retval = -ENOMEM;
362                 goto err2;
363         }
364
365         /* assign the new dump dev structure */
366         dump_bdev->dev_id = (dev_t)arg;
367         dump_bdev->bdev = bdev;
368
369         /* make a note of the limit */
370         dump_bdev->limit = bdev->bd_inode->i_size;
371
372         /* now make sure we can map the dump buffer */
373         dump_bdev->bio->bi_io_vec = bvec;
374         dump_bdev->bio->bi_max_vecs = DUMP_BUFFER_SIZE >> PAGE_SHIFT;
375
376         retval = dump_block_map(dump_bdev, dump_config.dumper->dump_buf,
377                 DUMP_BUFFER_SIZE);
378
379         if (retval) {
380                 printk("LKCD: open: dump_block_map failed, ret %d\n", retval);
381                 goto err2;
382         }
383
384         printk("LKCD: Block device (%d,%d) successfully configured for dumping\n",
385                MAJOR(dump_bdev->dev_id),
386                MINOR(dump_bdev->dev_id));
387
388
389         /* after opening the block device, return */
390         return retval;
391
392 err2:   dump_free_bio(dump_bdev->bio);
393         dump_bdev->bio = NULL;
394 err1:   if (bdev)
395                 blkdev_put(bdev);
396         dump_bdev->bdev = NULL;
397 err:    return retval;
398 }
399
400 static int
401 dump_block_poll_open(struct dump_dev *dev, unsigned long arg)
402 {
403         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
404         struct block_device *bdev;
405         int retval = 0;
406         struct device *target = NULL;
407
408         /* make sure this is a valid block device */
409         if (!arg) {
410                 retval = -EINVAL;
411                 goto err;
412         }
413
414         /* Convert it to the new dev_t format */
415         arg = MKDEV((arg >> OLDMINORBITS), (arg & OLDMINORMASK));
416
417         /* get a corresponding block_dev struct for this */
418         bdev = bdget((dev_t)arg);
419         if (!bdev) {
420                 retval = -ENODEV;
421                 goto err;
422         }
423
424         /* get the block device opened */
425         if ((retval = blkdev_get(bdev, O_RDWR | O_LARGEFILE, 0))) {
426                 goto err;
427         }
428
429         dump_bdev->bio = 0;
430         dump_bdev->dev_id = (dev_t)arg;
431         dump_bdev->bdev = bdev;
432
433         /* make a note of the limit */
434         dump_bdev->limit = bdev->bd_inode->i_size;
435
436         target = get_device(bdev->bd_disk->driverfs_dev);
437         if (!target) {
438                 retval = -EINVAL;
439                 goto err1;
440         }
441         retval = register_disk_dump_device(target,bdev);
442         if (retval == -EEXIST)
443                 retval = 0;
444         else if (retval < 0)
445                 goto err1;
446
447         printk("LKCD: Block device (%d,%d) successfully configured for dumping using polling I/O\n",
448                 MAJOR((dev_t)arg), MINOR((dev_t)arg));
449
450         /* after opening the block device, return */
451         return retval;
452
453 err1:   if (bdev)
454                 blkdev_put(bdev);
455 err:    return retval;
456 }
457
458 /*
459  * Prepares the dump device so we can take a dump later.
460  * The caller is expected to have filled up the dev_id field in the
461  * block dump dev structure.
462  *
463  * At dump time when dump_block_write() is invoked it will be too
464  * late to recover, so as far as possible make sure obvious errors
465  * get caught right here and reported back to the caller.
466  */
467 static int
468 dump_block_open(struct dump_dev *dev, const char *arg)
469 {
470         unsigned long devid;
471
472         if ((sscanf(arg, "%lx", &devid)) != 1)
473                 return -EINVAL;
474
475         if (devid < 0)
476                 return -EINVAL;
477
478         if (dump_config.polling){
479                 polling_mode = 1;
480                 if (!dump_block_poll_open(dev, devid)) {
481                         return 0;
482                 } else {
483                         /*
484                          * If polling I/O isn't supported by this
485                          * device, fall back to interrupt-driven mode.
486                          */
487                         dump_config.polling = 0;
488                 }
489         }
490
491         polling_mode = 0;
492         return dump_block_intr_open(dev, devid);
493 }
494
495 /*
496  * Close the dump device and release associated resources.
497  * Invoked when unconfiguring the dump device.
498  */
499 static int
500 dump_block_release(struct dump_dev *dev)
501 {
502         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
503
504         /* release earlier bdev if present */
505         if (dump_bdev->bdev) {
506                 unregister_disk_dump_device(dump_bdev->bdev);
507                 blkdev_put(dump_bdev->bdev);
508                 dump_bdev->bdev = NULL;
509         }
510
511         if (dump_bdev->bio) {
512                 dump_free_bio(dump_bdev->bio);
513                 dump_bdev->bio = NULL;
514         }
515
516         return 0;
517 }
518
519 static int
520 dump_block_intr_silence(struct dump_dev *dev)
521 {
522         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
523         struct request_queue *q = bdev_get_queue(dump_bdev->bdev);
524         int ret;
525
526         /* If we can't get request queue lock, refuse to take the dump */
527         if (!spin_trylock(q->queue_lock))
528                 return -EBUSY;
529
530         ret = elv_queue_empty(q);
531         spin_unlock(q->queue_lock);
532
533         /* For now we assume we have the device to ourselves */
534         /* Just a quick sanity check */
535         if (!ret) {
536                 /* Warn the user and move on */
537                 printk("LKCD: Warning: Non-empty request queue\n");
538                 printk("LKCD: I/O requests in flight at dump time\n");
539         }
540
541         /*
542          * Move to a softer level of silencing where no spin_lock_irqs
543          * are held on other cpus
544          */
545         dump_silence_level = DUMP_SOFT_SPIN_CPUS;
546
547         ret = __dump_irq_enable();
548         if (ret) {
549                 return ret;
550         }
551
552         printk("LKCD: Dumping to block device (%d,%d) on CPU %d ...\n",
553                MAJOR(dump_bdev->dev_id), MINOR(dump_bdev->dev_id),
554                smp_processor_id());
555
556         return 0;
557 }
558
559 static int
560 dump_block_poll_silence(struct dump_dev *dev)
561 {
562         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
563         int ret;
564
565         local_irq_save(flags_global);
566         preempt_disable();
567
568         touch_nmi_watchdog();
569
570         if (down_trylock(&disk_dump_mutex))
571                 return -EBUSY;
572
573         dump_polling_oncpu = smp_processor_id() + 1;
574
575         /*
576          * Setup timer/tasklet
577          */
578         dump_clear_timers();
579         dump_clear_tasklet();
580         dump_clear_workqueue();
581
582         diskdump_setup_timestamp();
583
584         BUG_ON(dump_part.bdev != dump_bdev->bdev);
585
586         /*
587          * Move to a softer level of silencing where no spin_lock_irqs
588          * are held on other cpus
589          */
590         dump_silence_level = DUMP_SOFT_SPIN_CPUS;
591
592         touch_nmi_watchdog();
593
594         if (dump_device.ops.quiesce)
595                 if ((ret = dump_device.ops.quiesce(&dump_device)) < 0) {
596                         printk("LKCD: Quiesce failed. error %d\n", ret);
597                         return ret;
598                 }
599         touch_nmi_watchdog();
600         printk("LKCD: Dumping to block device (%d,%d) on CPU %d using polling I/O ...\n",
601                MAJOR(dump_bdev->dev_id), MINOR(dump_bdev->dev_id),
602                smp_processor_id());
603
604         return 0;
605 }
606
607 /*
608  * Prepare the dump device for use (silence any ongoing activity
609  * and quiesce state) when the system crashes.
610  */
611 static int
612 dump_block_silence(struct dump_dev *dev)
613 {
614         if (polling_mode)
615                 return dump_block_poll_silence(dev);
616         else
617                 return dump_block_intr_silence(dev);
618 }
619
620
621 static int
622 dump_block_intr_resume(struct dump_dev *dev)
623 {
624         __dump_irq_restore();
625         return 0;
626 }
627
628 static int
629 dump_block_poll_resume(struct dump_dev *dev)
630 {
631         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
632
633         BUG_ON(dump_part.bdev != dump_bdev->bdev);
634
635         if (dump_device.device && dump_device.ops.shutdown)
636                 if (dump_device.ops.shutdown(&dump_device))
637                         printk("LKCD: polling dev: adapter shutdown failed.\n");
638
639         dump_polling_oncpu = 0;
640         preempt_enable_no_resched();
641         local_irq_restore(flags_global);
642         up(&disk_dump_mutex);
643         return 0;
644 }
645
646 /*
647  * Invoked when dumping is done. This is the time to put things back
648  * (i.e. undo the effects of dump_block_silence) so the device is
649  * available for normal use.
650  */
651 static int
652 dump_block_resume(struct dump_dev *dev)
653 {
654         if (polling_mode)
655                 return dump_block_poll_resume(dev);
656         else
657                 return dump_block_intr_resume(dev);
658 }
659
660
661 /*
662  * Seek to the specified offset in the dump device.
663  * Makes sure this is a valid offset, otherwise returns an error.
664  */
665 static int
666 dump_block_seek(struct dump_dev *dev, loff_t off)
667 {
668         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
669         loff_t offset = off + dump_bdev->start_offset;
670
671         if (offset & ( PAGE_SIZE - 1)) {
672                 printk("LKCD: seek: non-page aligned\n");
673                 return -EINVAL;
674         }
675
676         if (offset & (bdev_hardsect_size(dump_bdev->bdev) - 1)) {
677                 printk("LKCD: seek: not sector aligned \n");
678                 return -EINVAL;
679         }
680
681         if (offset > dump_bdev->limit) {
682                 printk("LKCD: seek: not enough space left on device!\n");
683                 return -ENOSPC;
684         }
685         dev->curr_offset = off;
686         return 0;
687 }
688
689
690 static int
691 dump_block_intr_write(struct dump_dev *dev, void *buf,
692         unsigned long len)
693 {
694         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
695         loff_t offset = dev->curr_offset + dump_bdev->start_offset;
696         int retval = -ENOSPC;
697
698         if (offset >= dump_bdev->limit) {
699                 printk("LKCD: write: not enough space left on device!\n");
700                 goto out;
701         }
702
703         /* don't write more blocks than our max limit */
704         if (offset + len > dump_bdev->limit)
705                 len = dump_bdev->limit - offset;
706
707
708         retval = dump_block_map(dump_bdev, buf, len);
709         if (retval){
710                 printk("LKCD: write: dump_block_map failed! err %d\n", retval);
711                 goto out;
712         }
713
714         /*
715          * Write out the data to disk.
716          * Assumes the entire buffer mapped to a single bio, which we can
717          * submit and wait for io completion. In the future, may consider
718          * increasing the dump buffer size and submitting multiple bio s
719          * for better throughput.
720          */
721         dump_bdev->err = -EAGAIN;
722         submit_bio(WRITE, dump_bdev->bio);
723
724         dump_bdev->ddev.curr_offset += len;
725         retval = len;
726  out:
727         return retval;
728 }
729
730 static int
731 dump_block_poll_write(struct dump_dev *dev, void *buf,
732         unsigned long len)
733 {
734         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
735         loff_t offset = dev->curr_offset + dump_bdev->start_offset;
736         int retval = -ENOSPC;
737         int ret;
738
739         if (offset >= dump_bdev->limit) {
740                 printk("LKCD: write: not enough space left on device!\n");
741                 goto out;
742         }
743
744         /* don't write more blocks than our max limit */
745         if (offset + len > dump_bdev->limit)
746                 len = dump_bdev->limit - offset;
747
748         if (dump_part.bdev != dump_bdev->bdev) {
749                 return -EBUSY;
750                 goto out;
751         }
752
753         local_irq_disable();
754         touch_nmi_watchdog();
755         ret = dump_device.ops.rw_block(&dump_part, WRITE, offset >> DUMP_PAGE_SHIFT,
756                 buf, len >> DUMP_PAGE_SHIFT);
757         if (ret < 0) {
758                 printk("LKCD: write error\n");
759                 goto out;
760         }
761
762         retval = len;
763 out:
764         return retval;
765 }
766
767 /*
768  * Write out a buffer after checking the device limitations,
769  * sector sizes, etc. Assumes the buffer is in directly mapped
770  * kernel address space (not vmalloc'ed).
771  *
772  * Returns: number of bytes written or -ERRNO.
773  */
774 static int
775 dump_block_write(struct dump_dev *dev, void *buf,
776         unsigned long len)
777 {
778         if (polling_mode)
779                 return dump_block_poll_write(dev, buf, len);
780         else
781                 return dump_block_intr_write(dev, buf, len);
782 }
783
784
785 /*
786  * Name: dump_block_ready()
787  * Func: check if the last dump i/o is over and ready for next request
788  */
789 static int
790 dump_block_ready(struct dump_dev *dev, void *buf)
791 {
792         struct dump_blockdev *dump_bdev;
793         request_queue_t *q;
794
795         if (polling_mode)
796                 return 0;
797
798         dump_bdev = DUMP_BDEV(dev);
799         q = bdev_get_queue(dump_bdev->bio->bi_bdev);
800
801         /* check for io completion */
802         if (dump_bdev->err == -EAGAIN) {
803                 q->unplug_fn(q);
804                 return -EAGAIN;
805         }
806
807         if (dump_bdev->err) {
808                 printk("LKCD: dump i/o err\n");
809                 return dump_bdev->err;
810         }
811
812         return 0;
813 }
814
815
816 struct dump_dev_ops dump_blockdev_ops = {
817         .open           = dump_block_open,
818         .release        = dump_block_release,
819         .silence        = dump_block_silence,
820         .resume         = dump_block_resume,
821         .seek           = dump_block_seek,
822         .write          = dump_block_write,
823         /* .read not implemented */
824         .ready          = dump_block_ready
825 };
826
827 static struct dump_blockdev default_dump_blockdev = {
828         .ddev = {.type = 1, .ops = &dump_blockdev_ops,
829                         .curr_offset = 0},
830         /*
831          * leave enough room for the longest swap header possibly written
832          * written by mkswap (likely the largest page size supported by
833          * the arch
834          */
835         .start_offset   = DUMP_HEADER_OFFSET,
836         .err            = 0
837         /* assume the rest of the fields are zeroed by default */
838 };
839
840 struct dump_blockdev *dump_blockdev = &default_dump_blockdev;
841
842 /*
843  * Unregister and reregister ourselves.  This has the side effect
844  * of unconfiguring the current dump device.
845  */
846 static void
847 dump_blockdev_unconfigure(void)
848 {
849         dump_unregister_device(&dump_blockdev->ddev);
850         if (dump_register_device(&dump_blockdev->ddev) < 0)
851                 printk("LKCD: block device driver registration failed\n");
852 }
853
854 static int __init
855 dump_blockdev_init(void)
856 {
857         if (dump_register_device(&dump_blockdev->ddev) < 0) {
858                 printk("LKCD: block device driver registration failed\n");
859                 return -1;
860         }
861
862         printk("LKCD: block device driver registered\n");
863         return 0;
864 }
865
866 static void __exit
867 dump_blockdev_cleanup(void)
868 {
869         dump_unregister_device(&dump_blockdev->ddev);
870         printk("LKCD: block device driver unregistered\n");
871 }
872
873 MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
874 MODULE_DESCRIPTION("Block Dump Driver for Linux Kernel Crash Dump (LKCD)");
875 MODULE_LICENSE("GPL");
876
877 module_init(dump_blockdev_init);
878 module_exit(dump_blockdev_cleanup);