diff options
Diffstat (limited to 'drivers')
49 files changed, 1279 insertions, 325 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 43722af90bdd..c3fac7fd555e 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -270,10 +270,9 @@ int bus_add_device(struct device * dev) | |||
270 | 270 | ||
271 | if (bus) { | 271 | if (bus) { |
272 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 272 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); |
273 | error = device_attach(dev); | 273 | device_attach(dev); |
274 | klist_add_tail(&bus->klist_devices, &dev->knode_bus); | 274 | klist_add_tail(&bus->klist_devices, &dev->knode_bus); |
275 | if (error >= 0) | 275 | error = device_add_attrs(bus, dev); |
276 | error = device_add_attrs(bus, dev); | ||
277 | if (!error) { | 276 | if (!error) { |
278 | sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); | 277 | sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); |
279 | sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); | 278 | sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); |
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c index 638db06de2be..3410b4d294b9 100644 --- a/drivers/block/as-iosched.c +++ b/drivers/block/as-iosched.c | |||
@@ -1871,20 +1871,22 @@ static int as_init_queue(request_queue_t *q, elevator_t *e) | |||
1871 | if (!arq_pool) | 1871 | if (!arq_pool) |
1872 | return -ENOMEM; | 1872 | return -ENOMEM; |
1873 | 1873 | ||
1874 | ad = kmalloc(sizeof(*ad), GFP_KERNEL); | 1874 | ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); |
1875 | if (!ad) | 1875 | if (!ad) |
1876 | return -ENOMEM; | 1876 | return -ENOMEM; |
1877 | memset(ad, 0, sizeof(*ad)); | 1877 | memset(ad, 0, sizeof(*ad)); |
1878 | 1878 | ||
1879 | ad->q = q; /* Identify what queue the data belongs to */ | 1879 | ad->q = q; /* Identify what queue the data belongs to */ |
1880 | 1880 | ||
1881 | ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL); | 1881 | ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES, |
1882 | GFP_KERNEL, q->node); | ||
1882 | if (!ad->hash) { | 1883 | if (!ad->hash) { |
1883 | kfree(ad); | 1884 | kfree(ad); |
1884 | return -ENOMEM; | 1885 | return -ENOMEM; |
1885 | } | 1886 | } |
1886 | 1887 | ||
1887 | ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool); | 1888 | ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, |
1889 | mempool_free_slab, arq_pool, q->node); | ||
1888 | if (!ad->arq_pool) { | 1890 | if (!ad->arq_pool) { |
1889 | kfree(ad->hash); | 1891 | kfree(ad->hash); |
1890 | kfree(ad); | 1892 | kfree(ad); |
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c index 7f79f3dd0165..4bc2fea73273 100644 --- a/drivers/block/deadline-iosched.c +++ b/drivers/block/deadline-iosched.c | |||
@@ -711,18 +711,20 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e) | |||
711 | if (!drq_pool) | 711 | if (!drq_pool) |
712 | return -ENOMEM; | 712 | return -ENOMEM; |
713 | 713 | ||
714 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 714 | dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); |
715 | if (!dd) | 715 | if (!dd) |
716 | return -ENOMEM; | 716 | return -ENOMEM; |
717 | memset(dd, 0, sizeof(*dd)); | 717 | memset(dd, 0, sizeof(*dd)); |
718 | 718 | ||
719 | dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL); | 719 | dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES, |
720 | GFP_KERNEL, q->node); | ||
720 | if (!dd->hash) { | 721 | if (!dd->hash) { |
721 | kfree(dd); | 722 | kfree(dd); |
722 | return -ENOMEM; | 723 | return -ENOMEM; |
723 | } | 724 | } |
724 | 725 | ||
725 | dd->drq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, drq_pool); | 726 | dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, |
727 | mempool_free_slab, drq_pool, q->node); | ||
726 | if (!dd->drq_pool) { | 728 | if (!dd->drq_pool) { |
727 | kfree(dd->hash); | 729 | kfree(dd->hash); |
728 | kfree(dd); | 730 | kfree(dd); |
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 53f7d846b747..47fd3659a061 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c | |||
@@ -40,7 +40,7 @@ static inline int major_to_index(int major) | |||
40 | 40 | ||
41 | #ifdef CONFIG_PROC_FS | 41 | #ifdef CONFIG_PROC_FS |
42 | /* get block device names in somewhat random order */ | 42 | /* get block device names in somewhat random order */ |
43 | int get_blkdev_list(char *p) | 43 | int get_blkdev_list(char *p, int used) |
44 | { | 44 | { |
45 | struct blk_major_name *n; | 45 | struct blk_major_name *n; |
46 | int i, len; | 46 | int i, len; |
@@ -49,10 +49,18 @@ int get_blkdev_list(char *p) | |||
49 | 49 | ||
50 | down(&block_subsys_sem); | 50 | down(&block_subsys_sem); |
51 | for (i = 0; i < ARRAY_SIZE(major_names); i++) { | 51 | for (i = 0; i < ARRAY_SIZE(major_names); i++) { |
52 | for (n = major_names[i]; n; n = n->next) | 52 | for (n = major_names[i]; n; n = n->next) { |
53 | /* | ||
54 | * If the curent string plus the 5 extra characters | ||
55 | * in the line would run us off the page, then we're done | ||
56 | */ | ||
57 | if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE) | ||
58 | goto page_full; | ||
53 | len += sprintf(p+len, "%3d %s\n", | 59 | len += sprintf(p+len, "%3d %s\n", |
54 | n->major, n->name); | 60 | n->major, n->name); |
61 | } | ||
55 | } | 62 | } |
63 | page_full: | ||
56 | up(&block_subsys_sem); | 64 | up(&block_subsys_sem); |
57 | 65 | ||
58 | return len; | 66 | return len; |
@@ -582,10 +590,16 @@ struct seq_operations diskstats_op = { | |||
582 | .show = diskstats_show | 590 | .show = diskstats_show |
583 | }; | 591 | }; |
584 | 592 | ||
585 | |||
586 | struct gendisk *alloc_disk(int minors) | 593 | struct gendisk *alloc_disk(int minors) |
587 | { | 594 | { |
588 | struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); | 595 | return alloc_disk_node(minors, -1); |
596 | } | ||
597 | |||
598 | struct gendisk *alloc_disk_node(int minors, int node_id) | ||
599 | { | ||
600 | struct gendisk *disk; | ||
601 | |||
602 | disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id); | ||
589 | if (disk) { | 603 | if (disk) { |
590 | memset(disk, 0, sizeof(struct gendisk)); | 604 | memset(disk, 0, sizeof(struct gendisk)); |
591 | if (!init_disk_stats(disk)) { | 605 | if (!init_disk_stats(disk)) { |
@@ -594,7 +608,7 @@ struct gendisk *alloc_disk(int minors) | |||
594 | } | 608 | } |
595 | if (minors > 1) { | 609 | if (minors > 1) { |
596 | int size = (minors - 1) * sizeof(struct hd_struct *); | 610 | int size = (minors - 1) * sizeof(struct hd_struct *); |
597 | disk->part = kmalloc(size, GFP_KERNEL); | 611 | disk->part = kmalloc_node(size, GFP_KERNEL, node_id); |
598 | if (!disk->part) { | 612 | if (!disk->part) { |
599 | kfree(disk); | 613 | kfree(disk); |
600 | return NULL; | 614 | return NULL; |
@@ -610,6 +624,7 @@ struct gendisk *alloc_disk(int minors) | |||
610 | } | 624 | } |
611 | 625 | ||
612 | EXPORT_SYMBOL(alloc_disk); | 626 | EXPORT_SYMBOL(alloc_disk); |
627 | EXPORT_SYMBOL(alloc_disk_node); | ||
613 | 628 | ||
614 | struct kobject *get_disk(struct gendisk *disk) | 629 | struct kobject *get_disk(struct gendisk *disk) |
615 | { | 630 | { |
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c index 6d7bcc9da9e7..6e278474f9a8 100644 --- a/drivers/block/ioctl.c +++ b/drivers/block/ioctl.c | |||
@@ -133,11 +133,9 @@ static int put_u64(unsigned long arg, u64 val) | |||
133 | return put_user(val, (u64 __user *)arg); | 133 | return put_user(val, (u64 __user *)arg); |
134 | } | 134 | } |
135 | 135 | ||
136 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, | 136 | static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, |
137 | unsigned long arg) | 137 | unsigned cmd, unsigned long arg) |
138 | { | 138 | { |
139 | struct block_device *bdev = inode->i_bdev; | ||
140 | struct gendisk *disk = bdev->bd_disk; | ||
141 | struct backing_dev_info *bdi; | 139 | struct backing_dev_info *bdi; |
142 | int ret, n; | 140 | int ret, n; |
143 | 141 | ||
@@ -190,36 +188,72 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, | |||
190 | return put_ulong(arg, bdev->bd_inode->i_size >> 9); | 188 | return put_ulong(arg, bdev->bd_inode->i_size >> 9); |
191 | case BLKGETSIZE64: | 189 | case BLKGETSIZE64: |
192 | return put_u64(arg, bdev->bd_inode->i_size); | 190 | return put_u64(arg, bdev->bd_inode->i_size); |
191 | } | ||
192 | return -ENOIOCTLCMD; | ||
193 | } | ||
194 | |||
195 | static int blkdev_driver_ioctl(struct inode *inode, struct file *file, | ||
196 | struct gendisk *disk, unsigned cmd, unsigned long arg) | ||
197 | { | ||
198 | int ret; | ||
199 | if (disk->fops->unlocked_ioctl) | ||
200 | return disk->fops->unlocked_ioctl(file, cmd, arg); | ||
201 | |||
202 | if (disk->fops->ioctl) { | ||
203 | lock_kernel(); | ||
204 | ret = disk->fops->ioctl(inode, file, cmd, arg); | ||
205 | unlock_kernel(); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | return -ENOTTY; | ||
210 | } | ||
211 | |||
212 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, | ||
213 | unsigned long arg) | ||
214 | { | ||
215 | struct block_device *bdev = inode->i_bdev; | ||
216 | struct gendisk *disk = bdev->bd_disk; | ||
217 | int ret, n; | ||
218 | |||
219 | switch(cmd) { | ||
193 | case BLKFLSBUF: | 220 | case BLKFLSBUF: |
194 | if (!capable(CAP_SYS_ADMIN)) | 221 | if (!capable(CAP_SYS_ADMIN)) |
195 | return -EACCES; | 222 | return -EACCES; |
196 | if (disk->fops->ioctl) { | 223 | |
197 | ret = disk->fops->ioctl(inode, file, cmd, arg); | 224 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); |
198 | /* -EINVAL to handle old uncorrected drivers */ | 225 | /* -EINVAL to handle old uncorrected drivers */ |
199 | if (ret != -EINVAL && ret != -ENOTTY) | 226 | if (ret != -EINVAL && ret != -ENOTTY) |
200 | return ret; | 227 | return ret; |
201 | } | 228 | |
229 | lock_kernel(); | ||
202 | fsync_bdev(bdev); | 230 | fsync_bdev(bdev); |
203 | invalidate_bdev(bdev, 0); | 231 | invalidate_bdev(bdev, 0); |
232 | unlock_kernel(); | ||
204 | return 0; | 233 | return 0; |
234 | |||
205 | case BLKROSET: | 235 | case BLKROSET: |
206 | if (disk->fops->ioctl) { | 236 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); |
207 | ret = disk->fops->ioctl(inode, file, cmd, arg); | 237 | /* -EINVAL to handle old uncorrected drivers */ |
208 | /* -EINVAL to handle old uncorrected drivers */ | 238 | if (ret != -EINVAL && ret != -ENOTTY) |
209 | if (ret != -EINVAL && ret != -ENOTTY) | 239 | return ret; |
210 | return ret; | ||
211 | } | ||
212 | if (!capable(CAP_SYS_ADMIN)) | 240 | if (!capable(CAP_SYS_ADMIN)) |
213 | return -EACCES; | 241 | return -EACCES; |
214 | if (get_user(n, (int __user *)(arg))) | 242 | if (get_user(n, (int __user *)(arg))) |
215 | return -EFAULT; | 243 | return -EFAULT; |
244 | lock_kernel(); | ||
216 | set_device_ro(bdev, n); | 245 | set_device_ro(bdev, n); |
246 | unlock_kernel(); | ||
217 | return 0; | 247 | return 0; |
218 | default: | ||
219 | if (disk->fops->ioctl) | ||
220 | return disk->fops->ioctl(inode, file, cmd, arg); | ||
221 | } | 248 | } |
222 | return -ENOTTY; | 249 | |
250 | lock_kernel(); | ||
251 | ret = blkdev_locked_ioctl(file, bdev, cmd, arg); | ||
252 | unlock_kernel(); | ||
253 | if (ret != -ENOIOCTLCMD) | ||
254 | return ret; | ||
255 | |||
256 | return blkdev_driver_ioctl(inode, file, disk, cmd, arg); | ||
223 | } | 257 | } |
224 | 258 | ||
225 | /* Most of the generic ioctls are handled in the normal fallback path. | 259 | /* Most of the generic ioctls are handled in the normal fallback path. |
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 81fe3a0c1fe7..fd94ea27d594 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/swap.h> | 29 | #include <linux/swap.h> |
30 | #include <linux/writeback.h> | 30 | #include <linux/writeback.h> |
31 | #include <linux/blkdev.h> | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * for max sense size | 34 | * for max sense size |
@@ -716,7 +717,7 @@ struct request *blk_queue_find_tag(request_queue_t *q, int tag) | |||
716 | { | 717 | { |
717 | struct blk_queue_tag *bqt = q->queue_tags; | 718 | struct blk_queue_tag *bqt = q->queue_tags; |
718 | 719 | ||
719 | if (unlikely(bqt == NULL || tag >= bqt->real_max_depth)) | 720 | if (unlikely(bqt == NULL || tag >= bqt->max_depth)) |
720 | return NULL; | 721 | return NULL; |
721 | 722 | ||
722 | return bqt->tag_index[tag]; | 723 | return bqt->tag_index[tag]; |
@@ -774,9 +775,9 @@ EXPORT_SYMBOL(blk_queue_free_tags); | |||
774 | static int | 775 | static int |
775 | init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | 776 | init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) |
776 | { | 777 | { |
777 | int bits, i; | ||
778 | struct request **tag_index; | 778 | struct request **tag_index; |
779 | unsigned long *tag_map; | 779 | unsigned long *tag_map; |
780 | int nr_ulongs; | ||
780 | 781 | ||
781 | if (depth > q->nr_requests * 2) { | 782 | if (depth > q->nr_requests * 2) { |
782 | depth = q->nr_requests * 2; | 783 | depth = q->nr_requests * 2; |
@@ -788,24 +789,17 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | |||
788 | if (!tag_index) | 789 | if (!tag_index) |
789 | goto fail; | 790 | goto fail; |
790 | 791 | ||
791 | bits = (depth / BLK_TAGS_PER_LONG) + 1; | 792 | nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG; |
792 | tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC); | 793 | tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC); |
793 | if (!tag_map) | 794 | if (!tag_map) |
794 | goto fail; | 795 | goto fail; |
795 | 796 | ||
796 | memset(tag_index, 0, depth * sizeof(struct request *)); | 797 | memset(tag_index, 0, depth * sizeof(struct request *)); |
797 | memset(tag_map, 0, bits * sizeof(unsigned long)); | 798 | memset(tag_map, 0, nr_ulongs * sizeof(unsigned long)); |
798 | tags->max_depth = depth; | 799 | tags->max_depth = depth; |
799 | tags->real_max_depth = bits * BITS_PER_LONG; | ||
800 | tags->tag_index = tag_index; | 800 | tags->tag_index = tag_index; |
801 | tags->tag_map = tag_map; | 801 | tags->tag_map = tag_map; |
802 | 802 | ||
803 | /* | ||
804 | * set the upper bits if the depth isn't a multiple of the word size | ||
805 | */ | ||
806 | for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++) | ||
807 | __set_bit(i, tag_map); | ||
808 | |||
809 | return 0; | 803 | return 0; |
810 | fail: | 804 | fail: |
811 | kfree(tag_index); | 805 | kfree(tag_index); |
@@ -870,32 +864,24 @@ int blk_queue_resize_tags(request_queue_t *q, int new_depth) | |||
870 | struct blk_queue_tag *bqt = q->queue_tags; | 864 | struct blk_queue_tag *bqt = q->queue_tags; |
871 | struct request **tag_index; | 865 | struct request **tag_index; |
872 | unsigned long *tag_map; | 866 | unsigned long *tag_map; |
873 | int bits, max_depth; | 867 | int max_depth, nr_ulongs; |
874 | 868 | ||
875 | if (!bqt) | 869 | if (!bqt) |
876 | return -ENXIO; | 870 | return -ENXIO; |
877 | 871 | ||
878 | /* | 872 | /* |
879 | * don't bother sizing down | ||
880 | */ | ||
881 | if (new_depth <= bqt->real_max_depth) { | ||
882 | bqt->max_depth = new_depth; | ||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | /* | ||
887 | * save the old state info, so we can copy it back | 873 | * save the old state info, so we can copy it back |
888 | */ | 874 | */ |
889 | tag_index = bqt->tag_index; | 875 | tag_index = bqt->tag_index; |
890 | tag_map = bqt->tag_map; | 876 | tag_map = bqt->tag_map; |
891 | max_depth = bqt->real_max_depth; | 877 | max_depth = bqt->max_depth; |
892 | 878 | ||
893 | if (init_tag_map(q, bqt, new_depth)) | 879 | if (init_tag_map(q, bqt, new_depth)) |
894 | return -ENOMEM; | 880 | return -ENOMEM; |
895 | 881 | ||
896 | memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *)); | 882 | memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *)); |
897 | bits = max_depth / BLK_TAGS_PER_LONG; | 883 | nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG; |
898 | memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long)); | 884 | memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long)); |
899 | 885 | ||
900 | kfree(tag_index); | 886 | kfree(tag_index); |
901 | kfree(tag_map); | 887 | kfree(tag_map); |
@@ -925,11 +911,16 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) | |||
925 | 911 | ||
926 | BUG_ON(tag == -1); | 912 | BUG_ON(tag == -1); |
927 | 913 | ||
928 | if (unlikely(tag >= bqt->real_max_depth)) | 914 | if (unlikely(tag >= bqt->max_depth)) |
915 | /* | ||
916 | * This can happen after tag depth has been reduced. | ||
917 | * FIXME: how about a warning or info message here? | ||
918 | */ | ||
929 | return; | 919 | return; |
930 | 920 | ||
931 | if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) { | 921 | if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) { |
932 | printk("attempt to clear non-busy tag (%d)\n", tag); | 922 | printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n", |
923 | __FUNCTION__, tag); | ||
933 | return; | 924 | return; |
934 | } | 925 | } |
935 | 926 | ||
@@ -938,7 +929,8 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) | |||
938 | rq->tag = -1; | 929 | rq->tag = -1; |
939 | 930 | ||
940 | if (unlikely(bqt->tag_index[tag] == NULL)) | 931 | if (unlikely(bqt->tag_index[tag] == NULL)) |
941 | printk("tag %d is missing\n", tag); | 932 | printk(KERN_ERR "%s: tag %d is missing\n", |
933 | __FUNCTION__, tag); | ||
942 | 934 | ||
943 | bqt->tag_index[tag] = NULL; | 935 | bqt->tag_index[tag] = NULL; |
944 | bqt->busy--; | 936 | bqt->busy--; |
@@ -967,24 +959,20 @@ EXPORT_SYMBOL(blk_queue_end_tag); | |||
967 | int blk_queue_start_tag(request_queue_t *q, struct request *rq) | 959 | int blk_queue_start_tag(request_queue_t *q, struct request *rq) |
968 | { | 960 | { |
969 | struct blk_queue_tag *bqt = q->queue_tags; | 961 | struct blk_queue_tag *bqt = q->queue_tags; |
970 | unsigned long *map = bqt->tag_map; | 962 | int tag; |
971 | int tag = 0; | ||
972 | 963 | ||
973 | if (unlikely((rq->flags & REQ_QUEUED))) { | 964 | if (unlikely((rq->flags & REQ_QUEUED))) { |
974 | printk(KERN_ERR | 965 | printk(KERN_ERR |
975 | "request %p for device [%s] already tagged %d", | 966 | "%s: request %p for device [%s] already tagged %d", |
976 | rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag); | 967 | __FUNCTION__, rq, |
968 | rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag); | ||
977 | BUG(); | 969 | BUG(); |
978 | } | 970 | } |
979 | 971 | ||
980 | for (map = bqt->tag_map; *map == -1UL; map++) { | 972 | tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); |
981 | tag += BLK_TAGS_PER_LONG; | 973 | if (tag >= bqt->max_depth) |
982 | 974 | return 1; | |
983 | if (tag >= bqt->max_depth) | ||
984 | return 1; | ||
985 | } | ||
986 | 975 | ||
987 | tag += ffz(*map); | ||
988 | __set_bit(tag, bqt->tag_map); | 976 | __set_bit(tag, bqt->tag_map); |
989 | 977 | ||
990 | rq->flags |= REQ_QUEUED; | 978 | rq->flags |= REQ_QUEUED; |
@@ -1020,7 +1008,8 @@ void blk_queue_invalidate_tags(request_queue_t *q) | |||
1020 | rq = list_entry_rq(tmp); | 1008 | rq = list_entry_rq(tmp); |
1021 | 1009 | ||
1022 | if (rq->tag == -1) { | 1010 | if (rq->tag == -1) { |
1023 | printk("bad tag found on list\n"); | 1011 | printk(KERN_ERR |
1012 | "%s: bad tag found on list\n", __FUNCTION__); | ||
1024 | list_del_init(&rq->queuelist); | 1013 | list_del_init(&rq->queuelist); |
1025 | rq->flags &= ~REQ_QUEUED; | 1014 | rq->flags &= ~REQ_QUEUED; |
1026 | } else | 1015 | } else |
@@ -1450,7 +1439,7 @@ EXPORT_SYMBOL(blk_remove_plug); | |||
1450 | */ | 1439 | */ |
1451 | void __generic_unplug_device(request_queue_t *q) | 1440 | void __generic_unplug_device(request_queue_t *q) |
1452 | { | 1441 | { |
1453 | if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) | 1442 | if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))) |
1454 | return; | 1443 | return; |
1455 | 1444 | ||
1456 | if (!blk_remove_plug(q)) | 1445 | if (!blk_remove_plug(q)) |
@@ -1645,7 +1634,8 @@ static int blk_init_free_list(request_queue_t *q) | |||
1645 | init_waitqueue_head(&rl->wait[WRITE]); | 1634 | init_waitqueue_head(&rl->wait[WRITE]); |
1646 | init_waitqueue_head(&rl->drain); | 1635 | init_waitqueue_head(&rl->drain); |
1647 | 1636 | ||
1648 | rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep); | 1637 | rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, |
1638 | mempool_free_slab, request_cachep, q->node); | ||
1649 | 1639 | ||
1650 | if (!rl->rq_pool) | 1640 | if (!rl->rq_pool) |
1651 | return -ENOMEM; | 1641 | return -ENOMEM; |
@@ -1657,8 +1647,15 @@ static int __make_request(request_queue_t *, struct bio *); | |||
1657 | 1647 | ||
1658 | request_queue_t *blk_alloc_queue(int gfp_mask) | 1648 | request_queue_t *blk_alloc_queue(int gfp_mask) |
1659 | { | 1649 | { |
1660 | request_queue_t *q = kmem_cache_alloc(requestq_cachep, gfp_mask); | 1650 | return blk_alloc_queue_node(gfp_mask, -1); |
1651 | } | ||
1652 | EXPORT_SYMBOL(blk_alloc_queue); | ||
1653 | |||
1654 | request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id) | ||
1655 | { | ||
1656 | request_queue_t *q; | ||
1661 | 1657 | ||
1658 | q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id); | ||
1662 | if (!q) | 1659 | if (!q) |
1663 | return NULL; | 1660 | return NULL; |
1664 | 1661 | ||
@@ -1671,8 +1668,7 @@ request_queue_t *blk_alloc_queue(int gfp_mask) | |||
1671 | 1668 | ||
1672 | return q; | 1669 | return q; |
1673 | } | 1670 | } |
1674 | 1671 | EXPORT_SYMBOL(blk_alloc_queue_node); | |
1675 | EXPORT_SYMBOL(blk_alloc_queue); | ||
1676 | 1672 | ||
1677 | /** | 1673 | /** |
1678 | * blk_init_queue - prepare a request queue for use with a block device | 1674 | * blk_init_queue - prepare a request queue for use with a block device |
@@ -1705,13 +1701,22 @@ EXPORT_SYMBOL(blk_alloc_queue); | |||
1705 | * blk_init_queue() must be paired with a blk_cleanup_queue() call | 1701 | * blk_init_queue() must be paired with a blk_cleanup_queue() call |
1706 | * when the block device is deactivated (such as at module unload). | 1702 | * when the block device is deactivated (such as at module unload). |
1707 | **/ | 1703 | **/ |
1704 | |||
1708 | request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) | 1705 | request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) |
1709 | { | 1706 | { |
1710 | request_queue_t *q = blk_alloc_queue(GFP_KERNEL); | 1707 | return blk_init_queue_node(rfn, lock, -1); |
1708 | } | ||
1709 | EXPORT_SYMBOL(blk_init_queue); | ||
1710 | |||
1711 | request_queue_t * | ||
1712 | blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) | ||
1713 | { | ||
1714 | request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id); | ||
1711 | 1715 | ||
1712 | if (!q) | 1716 | if (!q) |
1713 | return NULL; | 1717 | return NULL; |
1714 | 1718 | ||
1719 | q->node = node_id; | ||
1715 | if (blk_init_free_list(q)) | 1720 | if (blk_init_free_list(q)) |
1716 | goto out_init; | 1721 | goto out_init; |
1717 | 1722 | ||
@@ -1754,12 +1759,11 @@ out_init: | |||
1754 | kmem_cache_free(requestq_cachep, q); | 1759 | kmem_cache_free(requestq_cachep, q); |
1755 | return NULL; | 1760 | return NULL; |
1756 | } | 1761 | } |
1757 | 1762 | EXPORT_SYMBOL(blk_init_queue_node); | |
1758 | EXPORT_SYMBOL(blk_init_queue); | ||
1759 | 1763 | ||
1760 | int blk_get_queue(request_queue_t *q) | 1764 | int blk_get_queue(request_queue_t *q) |
1761 | { | 1765 | { |
1762 | if (!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { | 1766 | if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { |
1763 | atomic_inc(&q->refcnt); | 1767 | atomic_inc(&q->refcnt); |
1764 | return 0; | 1768 | return 0; |
1765 | } | 1769 | } |
@@ -1838,7 +1842,6 @@ static void __freed_request(request_queue_t *q, int rw) | |||
1838 | clear_queue_congested(q, rw); | 1842 | clear_queue_congested(q, rw); |
1839 | 1843 | ||
1840 | if (rl->count[rw] + 1 <= q->nr_requests) { | 1844 | if (rl->count[rw] + 1 <= q->nr_requests) { |
1841 | smp_mb(); | ||
1842 | if (waitqueue_active(&rl->wait[rw])) | 1845 | if (waitqueue_active(&rl->wait[rw])) |
1843 | wake_up(&rl->wait[rw]); | 1846 | wake_up(&rl->wait[rw]); |
1844 | 1847 | ||
@@ -1966,7 +1969,6 @@ static struct request *get_request_wait(request_queue_t *q, int rw) | |||
1966 | DEFINE_WAIT(wait); | 1969 | DEFINE_WAIT(wait); |
1967 | struct request *rq; | 1970 | struct request *rq; |
1968 | 1971 | ||
1969 | generic_unplug_device(q); | ||
1970 | do { | 1972 | do { |
1971 | struct request_list *rl = &q->rq; | 1973 | struct request_list *rl = &q->rq; |
1972 | 1974 | ||
@@ -1978,6 +1980,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw) | |||
1978 | if (!rq) { | 1980 | if (!rq) { |
1979 | struct io_context *ioc; | 1981 | struct io_context *ioc; |
1980 | 1982 | ||
1983 | generic_unplug_device(q); | ||
1981 | io_schedule(); | 1984 | io_schedule(); |
1982 | 1985 | ||
1983 | /* | 1986 | /* |
@@ -2581,7 +2584,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) | |||
2581 | spin_lock_prefetch(q->queue_lock); | 2584 | spin_lock_prefetch(q->queue_lock); |
2582 | 2585 | ||
2583 | barrier = bio_barrier(bio); | 2586 | barrier = bio_barrier(bio); |
2584 | if (barrier && (q->ordered == QUEUE_ORDERED_NONE)) { | 2587 | if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) { |
2585 | err = -EOPNOTSUPP; | 2588 | err = -EOPNOTSUPP; |
2586 | goto end_io; | 2589 | goto end_io; |
2587 | } | 2590 | } |
@@ -2682,7 +2685,7 @@ get_rq: | |||
2682 | /* | 2685 | /* |
2683 | * REQ_BARRIER implies no merging, but lets make it explicit | 2686 | * REQ_BARRIER implies no merging, but lets make it explicit |
2684 | */ | 2687 | */ |
2685 | if (barrier) | 2688 | if (unlikely(barrier)) |
2686 | req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); | 2689 | req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); |
2687 | 2690 | ||
2688 | req->errors = 0; | 2691 | req->errors = 0; |
@@ -2806,7 +2809,7 @@ static inline void block_wait_queue_running(request_queue_t *q) | |||
2806 | { | 2809 | { |
2807 | DEFINE_WAIT(wait); | 2810 | DEFINE_WAIT(wait); |
2808 | 2811 | ||
2809 | while (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) { | 2812 | while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) { |
2810 | struct request_list *rl = &q->rq; | 2813 | struct request_list *rl = &q->rq; |
2811 | 2814 | ||
2812 | prepare_to_wait_exclusive(&rl->drain, &wait, | 2815 | prepare_to_wait_exclusive(&rl->drain, &wait, |
@@ -2915,7 +2918,7 @@ end_io: | |||
2915 | goto end_io; | 2918 | goto end_io; |
2916 | } | 2919 | } |
2917 | 2920 | ||
2918 | if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) | 2921 | if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) |
2919 | goto end_io; | 2922 | goto end_io; |
2920 | 2923 | ||
2921 | block_wait_queue_running(q); | 2924 | block_wait_queue_running(q); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 6f011d0d8e97..b35e08876dd4 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -472,17 +472,11 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
472 | */ | 472 | */ |
473 | static void loop_add_bio(struct loop_device *lo, struct bio *bio) | 473 | static void loop_add_bio(struct loop_device *lo, struct bio *bio) |
474 | { | 474 | { |
475 | unsigned long flags; | ||
476 | |||
477 | spin_lock_irqsave(&lo->lo_lock, flags); | ||
478 | if (lo->lo_biotail) { | 475 | if (lo->lo_biotail) { |
479 | lo->lo_biotail->bi_next = bio; | 476 | lo->lo_biotail->bi_next = bio; |
480 | lo->lo_biotail = bio; | 477 | lo->lo_biotail = bio; |
481 | } else | 478 | } else |
482 | lo->lo_bio = lo->lo_biotail = bio; | 479 | lo->lo_bio = lo->lo_biotail = bio; |
483 | spin_unlock_irqrestore(&lo->lo_lock, flags); | ||
484 | |||
485 | up(&lo->lo_bh_mutex); | ||
486 | } | 480 | } |
487 | 481 | ||
488 | /* | 482 | /* |
@@ -492,14 +486,12 @@ static struct bio *loop_get_bio(struct loop_device *lo) | |||
492 | { | 486 | { |
493 | struct bio *bio; | 487 | struct bio *bio; |
494 | 488 | ||
495 | spin_lock_irq(&lo->lo_lock); | ||
496 | if ((bio = lo->lo_bio)) { | 489 | if ((bio = lo->lo_bio)) { |
497 | if (bio == lo->lo_biotail) | 490 | if (bio == lo->lo_biotail) |
498 | lo->lo_biotail = NULL; | 491 | lo->lo_biotail = NULL; |
499 | lo->lo_bio = bio->bi_next; | 492 | lo->lo_bio = bio->bi_next; |
500 | bio->bi_next = NULL; | 493 | bio->bi_next = NULL; |
501 | } | 494 | } |
502 | spin_unlock_irq(&lo->lo_lock); | ||
503 | 495 | ||
504 | return bio; | 496 | return bio; |
505 | } | 497 | } |
@@ -509,35 +501,28 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio) | |||
509 | struct loop_device *lo = q->queuedata; | 501 | struct loop_device *lo = q->queuedata; |
510 | int rw = bio_rw(old_bio); | 502 | int rw = bio_rw(old_bio); |
511 | 503 | ||
512 | if (!lo) | 504 | if (rw == READA) |
513 | goto out; | 505 | rw = READ; |
506 | |||
507 | BUG_ON(!lo || (rw != READ && rw != WRITE)); | ||
514 | 508 | ||
515 | spin_lock_irq(&lo->lo_lock); | 509 | spin_lock_irq(&lo->lo_lock); |
516 | if (lo->lo_state != Lo_bound) | 510 | if (lo->lo_state != Lo_bound) |
517 | goto inactive; | 511 | goto out; |
518 | atomic_inc(&lo->lo_pending); | 512 | if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) |
519 | spin_unlock_irq(&lo->lo_lock); | 513 | goto out; |
520 | 514 | lo->lo_pending++; | |
521 | if (rw == WRITE) { | ||
522 | if (lo->lo_flags & LO_FLAGS_READ_ONLY) | ||
523 | goto err; | ||
524 | } else if (rw == READA) { | ||
525 | rw = READ; | ||
526 | } else if (rw != READ) { | ||
527 | printk(KERN_ERR "loop: unknown command (%x)\n", rw); | ||
528 | goto err; | ||
529 | } | ||
530 | loop_add_bio(lo, old_bio); | 515 | loop_add_bio(lo, old_bio); |
516 | spin_unlock_irq(&lo->lo_lock); | ||
517 | up(&lo->lo_bh_mutex); | ||
531 | return 0; | 518 | return 0; |
532 | err: | 519 | |
533 | if (atomic_dec_and_test(&lo->lo_pending)) | ||
534 | up(&lo->lo_bh_mutex); | ||
535 | out: | 520 | out: |
521 | if (lo->lo_pending == 0) | ||
522 | up(&lo->lo_bh_mutex); | ||
523 | spin_unlock_irq(&lo->lo_lock); | ||
536 | bio_io_error(old_bio, old_bio->bi_size); | 524 | bio_io_error(old_bio, old_bio->bi_size); |
537 | return 0; | 525 | return 0; |
538 | inactive: | ||
539 | spin_unlock_irq(&lo->lo_lock); | ||
540 | goto out; | ||
541 | } | 526 | } |
542 | 527 | ||
543 | /* | 528 | /* |
@@ -560,13 +545,11 @@ static void do_loop_switch(struct loop_device *, struct switch_request *); | |||
560 | 545 | ||
561 | static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) | 546 | static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) |
562 | { | 547 | { |
563 | int ret; | ||
564 | |||
565 | if (unlikely(!bio->bi_bdev)) { | 548 | if (unlikely(!bio->bi_bdev)) { |
566 | do_loop_switch(lo, bio->bi_private); | 549 | do_loop_switch(lo, bio->bi_private); |
567 | bio_put(bio); | 550 | bio_put(bio); |
568 | } else { | 551 | } else { |
569 | ret = do_bio_filebacked(lo, bio); | 552 | int ret = do_bio_filebacked(lo, bio); |
570 | bio_endio(bio, bio->bi_size, ret); | 553 | bio_endio(bio, bio->bi_size, ret); |
571 | } | 554 | } |
572 | } | 555 | } |
@@ -594,7 +577,7 @@ static int loop_thread(void *data) | |||
594 | set_user_nice(current, -20); | 577 | set_user_nice(current, -20); |
595 | 578 | ||
596 | lo->lo_state = Lo_bound; | 579 | lo->lo_state = Lo_bound; |
597 | atomic_inc(&lo->lo_pending); | 580 | lo->lo_pending = 1; |
598 | 581 | ||
599 | /* | 582 | /* |
600 | * up sem, we are running | 583 | * up sem, we are running |
@@ -602,26 +585,37 @@ static int loop_thread(void *data) | |||
602 | up(&lo->lo_sem); | 585 | up(&lo->lo_sem); |
603 | 586 | ||
604 | for (;;) { | 587 | for (;;) { |
605 | down_interruptible(&lo->lo_bh_mutex); | 588 | int pending; |
589 | |||
606 | /* | 590 | /* |
607 | * could be upped because of tear-down, not because of | 591 | * interruptible just to not contribute to load avg |
608 | * pending work | ||
609 | */ | 592 | */ |
610 | if (!atomic_read(&lo->lo_pending)) | 593 | if (down_interruptible(&lo->lo_bh_mutex)) |
594 | continue; | ||
595 | |||
596 | spin_lock_irq(&lo->lo_lock); | ||
597 | |||
598 | /* | ||
599 | * could be upped because of tear-down, not pending work | ||
600 | */ | ||
601 | if (unlikely(!lo->lo_pending)) { | ||
602 | spin_unlock_irq(&lo->lo_lock); | ||
611 | break; | 603 | break; |
604 | } | ||
612 | 605 | ||
613 | bio = loop_get_bio(lo); | 606 | bio = loop_get_bio(lo); |
614 | if (!bio) { | 607 | lo->lo_pending--; |
615 | printk("loop: missing bio\n"); | 608 | pending = lo->lo_pending; |
616 | continue; | 609 | spin_unlock_irq(&lo->lo_lock); |
617 | } | 610 | |
611 | BUG_ON(!bio); | ||
618 | loop_handle_bio(lo, bio); | 612 | loop_handle_bio(lo, bio); |
619 | 613 | ||
620 | /* | 614 | /* |
621 | * upped both for pending work and tear-down, lo_pending | 615 | * upped both for pending work and tear-down, lo_pending |
622 | * will hit zero then | 616 | * will hit zero then |
623 | */ | 617 | */ |
624 | if (atomic_dec_and_test(&lo->lo_pending)) | 618 | if (unlikely(!pending)) |
625 | break; | 619 | break; |
626 | } | 620 | } |
627 | 621 | ||
@@ -900,7 +894,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
900 | 894 | ||
901 | spin_lock_irq(&lo->lo_lock); | 895 | spin_lock_irq(&lo->lo_lock); |
902 | lo->lo_state = Lo_rundown; | 896 | lo->lo_state = Lo_rundown; |
903 | if (atomic_dec_and_test(&lo->lo_pending)) | 897 | lo->lo_pending--; |
898 | if (!lo->lo_pending) | ||
904 | up(&lo->lo_bh_mutex); | 899 | up(&lo->lo_bh_mutex); |
905 | spin_unlock_irq(&lo->lo_lock); | 900 | spin_unlock_irq(&lo->lo_lock); |
906 | 901 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index bc56770bcc90..7f3d78de265c 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -467,14 +467,12 @@ static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsign | |||
467 | * Queue a bio for processing by the low-level CD device. Must be called | 467 | * Queue a bio for processing by the low-level CD device. Must be called |
468 | * from process context. | 468 | * from process context. |
469 | */ | 469 | */ |
470 | static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_prio_read) | 470 | static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio) |
471 | { | 471 | { |
472 | spin_lock(&pd->iosched.lock); | 472 | spin_lock(&pd->iosched.lock); |
473 | if (bio_data_dir(bio) == READ) { | 473 | if (bio_data_dir(bio) == READ) { |
474 | pkt_add_list_last(bio, &pd->iosched.read_queue, | 474 | pkt_add_list_last(bio, &pd->iosched.read_queue, |
475 | &pd->iosched.read_queue_tail); | 475 | &pd->iosched.read_queue_tail); |
476 | if (high_prio_read) | ||
477 | pd->iosched.high_prio_read = 1; | ||
478 | } else { | 476 | } else { |
479 | pkt_add_list_last(bio, &pd->iosched.write_queue, | 477 | pkt_add_list_last(bio, &pd->iosched.write_queue, |
480 | &pd->iosched.write_queue_tail); | 478 | &pd->iosched.write_queue_tail); |
@@ -490,15 +488,16 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_p | |||
490 | * requirements for CDRW drives: | 488 | * requirements for CDRW drives: |
491 | * - A cache flush command must be inserted before a read request if the | 489 | * - A cache flush command must be inserted before a read request if the |
492 | * previous request was a write. | 490 | * previous request was a write. |
493 | * - Switching between reading and writing is slow, so don't it more often | 491 | * - Switching between reading and writing is slow, so don't do it more often |
494 | * than necessary. | 492 | * than necessary. |
493 | * - Optimize for throughput at the expense of latency. This means that streaming | ||
494 | * writes will never be interrupted by a read, but if the drive has to seek | ||
495 | * before the next write, switch to reading instead if there are any pending | ||
496 | * read requests. | ||
495 | * - Set the read speed according to current usage pattern. When only reading | 497 | * - Set the read speed according to current usage pattern. When only reading |
496 | * from the device, it's best to use the highest possible read speed, but | 498 | * from the device, it's best to use the highest possible read speed, but |
497 | * when switching often between reading and writing, it's better to have the | 499 | * when switching often between reading and writing, it's better to have the |
498 | * same read and write speeds. | 500 | * same read and write speeds. |
499 | * - Reads originating from user space should have higher priority than reads | ||
500 | * originating from pkt_gather_data, because some process is usually waiting | ||
501 | * on reads of the first kind. | ||
502 | */ | 501 | */ |
503 | static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | 502 | static void pkt_iosched_process_queue(struct pktcdvd_device *pd) |
504 | { | 503 | { |
@@ -512,21 +511,24 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
512 | 511 | ||
513 | for (;;) { | 512 | for (;;) { |
514 | struct bio *bio; | 513 | struct bio *bio; |
515 | int reads_queued, writes_queued, high_prio_read; | 514 | int reads_queued, writes_queued; |
516 | 515 | ||
517 | spin_lock(&pd->iosched.lock); | 516 | spin_lock(&pd->iosched.lock); |
518 | reads_queued = (pd->iosched.read_queue != NULL); | 517 | reads_queued = (pd->iosched.read_queue != NULL); |
519 | writes_queued = (pd->iosched.write_queue != NULL); | 518 | writes_queued = (pd->iosched.write_queue != NULL); |
520 | if (!reads_queued) | ||
521 | pd->iosched.high_prio_read = 0; | ||
522 | high_prio_read = pd->iosched.high_prio_read; | ||
523 | spin_unlock(&pd->iosched.lock); | 519 | spin_unlock(&pd->iosched.lock); |
524 | 520 | ||
525 | if (!reads_queued && !writes_queued) | 521 | if (!reads_queued && !writes_queued) |
526 | break; | 522 | break; |
527 | 523 | ||
528 | if (pd->iosched.writing) { | 524 | if (pd->iosched.writing) { |
529 | if (high_prio_read || (!writes_queued && reads_queued)) { | 525 | int need_write_seek = 1; |
526 | spin_lock(&pd->iosched.lock); | ||
527 | bio = pd->iosched.write_queue; | ||
528 | spin_unlock(&pd->iosched.lock); | ||
529 | if (bio && (bio->bi_sector == pd->iosched.last_write)) | ||
530 | need_write_seek = 0; | ||
531 | if (need_write_seek && reads_queued) { | ||
530 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { | 532 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { |
531 | VPRINTK("pktcdvd: write, waiting\n"); | 533 | VPRINTK("pktcdvd: write, waiting\n"); |
532 | break; | 534 | break; |
@@ -559,8 +561,10 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
559 | 561 | ||
560 | if (bio_data_dir(bio) == READ) | 562 | if (bio_data_dir(bio) == READ) |
561 | pd->iosched.successive_reads += bio->bi_size >> 10; | 563 | pd->iosched.successive_reads += bio->bi_size >> 10; |
562 | else | 564 | else { |
563 | pd->iosched.successive_reads = 0; | 565 | pd->iosched.successive_reads = 0; |
566 | pd->iosched.last_write = bio->bi_sector + bio_sectors(bio); | ||
567 | } | ||
564 | if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) { | 568 | if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) { |
565 | if (pd->read_speed == pd->write_speed) { | 569 | if (pd->read_speed == pd->write_speed) { |
566 | pd->read_speed = MAX_SPEED; | 570 | pd->read_speed = MAX_SPEED; |
@@ -765,7 +769,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
765 | 769 | ||
766 | atomic_inc(&pkt->io_wait); | 770 | atomic_inc(&pkt->io_wait); |
767 | bio->bi_rw = READ; | 771 | bio->bi_rw = READ; |
768 | pkt_queue_bio(pd, bio, 0); | 772 | pkt_queue_bio(pd, bio); |
769 | frames_read++; | 773 | frames_read++; |
770 | } | 774 | } |
771 | 775 | ||
@@ -1062,7 +1066,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1062 | 1066 | ||
1063 | atomic_set(&pkt->io_wait, 1); | 1067 | atomic_set(&pkt->io_wait, 1); |
1064 | pkt->w_bio->bi_rw = WRITE; | 1068 | pkt->w_bio->bi_rw = WRITE; |
1065 | pkt_queue_bio(pd, pkt->w_bio, 0); | 1069 | pkt_queue_bio(pd, pkt->w_bio); |
1066 | } | 1070 | } |
1067 | 1071 | ||
1068 | static void pkt_finish_packet(struct packet_data *pkt, int uptodate) | 1072 | static void pkt_finish_packet(struct packet_data *pkt, int uptodate) |
@@ -2120,7 +2124,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio) | |||
2120 | cloned_bio->bi_private = psd; | 2124 | cloned_bio->bi_private = psd; |
2121 | cloned_bio->bi_end_io = pkt_end_io_read_cloned; | 2125 | cloned_bio->bi_end_io = pkt_end_io_read_cloned; |
2122 | pd->stats.secs_r += bio->bi_size >> 9; | 2126 | pd->stats.secs_r += bio->bi_size >> 9; |
2123 | pkt_queue_bio(pd, cloned_bio, 1); | 2127 | pkt_queue_bio(pd, cloned_bio); |
2124 | return 0; | 2128 | return 0; |
2125 | } | 2129 | } |
2126 | 2130 | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 9075bbb56ad4..f766bc22c6bb 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -576,7 +576,7 @@ static void __exit hci_uart_exit(void) | |||
576 | #endif | 576 | #endif |
577 | 577 | ||
578 | /* Release tty registration of line discipline */ | 578 | /* Release tty registration of line discipline */ |
579 | if ((err = tty_register_ldisc(N_HCI, NULL))) | 579 | if ((err = tty_unregister_ldisc(N_HCI))) |
580 | BT_ERR("Can't unregister HCI line discipline (%d)", err); | 580 | BT_ERR("Can't unregister HCI line discipline (%d)", err); |
581 | } | 581 | } |
582 | 582 | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 1dc4259213a6..777bc499bbbd 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -861,13 +861,18 @@ static void change_speed(struct async_struct *info, | |||
861 | 861 | ||
862 | static void rs_put_char(struct tty_struct *tty, unsigned char ch) | 862 | static void rs_put_char(struct tty_struct *tty, unsigned char ch) |
863 | { | 863 | { |
864 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 864 | struct async_struct *info; |
865 | unsigned long flags; | 865 | unsigned long flags; |
866 | 866 | ||
867 | if (!tty) | ||
868 | return; | ||
869 | |||
870 | info = tty->driver_data; | ||
871 | |||
867 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | 872 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
868 | return; | 873 | return; |
869 | 874 | ||
870 | if (!tty || !info->xmit.buf) | 875 | if (!info->xmit.buf) |
871 | return; | 876 | return; |
872 | 877 | ||
873 | local_irq_save(flags); | 878 | local_irq_save(flags); |
@@ -910,13 +915,18 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
910 | static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) | 915 | static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) |
911 | { | 916 | { |
912 | int c, ret = 0; | 917 | int c, ret = 0; |
913 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 918 | struct async_struct *info; |
914 | unsigned long flags; | 919 | unsigned long flags; |
915 | 920 | ||
921 | if (!tty) | ||
922 | return 0; | ||
923 | |||
924 | info = tty->driver_data; | ||
925 | |||
916 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 926 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
917 | return 0; | 927 | return 0; |
918 | 928 | ||
919 | if (!tty || !info->xmit.buf || !tmp_buf) | 929 | if (!info->xmit.buf || !tmp_buf) |
920 | return 0; | 930 | return 0; |
921 | 931 | ||
922 | local_save_flags(flags); | 932 | local_save_flags(flags); |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index b3dbff1cf967..5079beda69b5 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -960,7 +960,7 @@ static char hdlc_unregister_fail[] __exitdata = | |||
960 | static void __exit n_hdlc_exit(void) | 960 | static void __exit n_hdlc_exit(void) |
961 | { | 961 | { |
962 | /* Release tty registration of line discipline */ | 962 | /* Release tty registration of line discipline */ |
963 | int status = tty_register_ldisc(N_HDLC, NULL); | 963 | int status = tty_unregister_ldisc(N_HDLC); |
964 | 964 | ||
965 | if (status) | 965 | if (status) |
966 | printk(hdlc_unregister_fail, status); | 966 | printk(hdlc_unregister_fail, status); |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 3883073ab48f..2291a87e8ada 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -200,7 +200,7 @@ static void __exit r3964_exit(void) | |||
200 | 200 | ||
201 | TRACE_M ("cleanup_module()"); | 201 | TRACE_M ("cleanup_module()"); |
202 | 202 | ||
203 | status=tty_register_ldisc(N_R3964, NULL); | 203 | status=tty_unregister_ldisc(N_R3964); |
204 | 204 | ||
205 | if(status!=0) | 205 | if(status!=0) |
206 | { | 206 | { |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 31831030f73f..cc4b43bad703 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -251,7 +251,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | |||
251 | 251 | ||
252 | static DEFINE_SPINLOCK(tty_ldisc_lock); | 252 | static DEFINE_SPINLOCK(tty_ldisc_lock); |
253 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 253 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
254 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ | 254 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ |
255 | 255 | ||
256 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | 256 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) |
257 | { | 257 | { |
@@ -262,24 +262,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | |||
262 | return -EINVAL; | 262 | return -EINVAL; |
263 | 263 | ||
264 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 264 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
265 | if (new_ldisc) { | 265 | tty_ldiscs[disc] = *new_ldisc; |
266 | tty_ldiscs[disc] = *new_ldisc; | 266 | tty_ldiscs[disc].num = disc; |
267 | tty_ldiscs[disc].num = disc; | 267 | tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; |
268 | tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; | 268 | tty_ldiscs[disc].refcount = 0; |
269 | tty_ldiscs[disc].refcount = 0; | ||
270 | } else { | ||
271 | if(tty_ldiscs[disc].refcount) | ||
272 | ret = -EBUSY; | ||
273 | else | ||
274 | tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; | ||
275 | } | ||
276 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 269 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
277 | 270 | ||
278 | return ret; | 271 | return ret; |
279 | } | 272 | } |
280 | |||
281 | EXPORT_SYMBOL(tty_register_ldisc); | 273 | EXPORT_SYMBOL(tty_register_ldisc); |
282 | 274 | ||
275 | int tty_unregister_ldisc(int disc) | ||
276 | { | ||
277 | unsigned long flags; | ||
278 | int ret = 0; | ||
279 | |||
280 | if (disc < N_TTY || disc >= NR_LDISCS) | ||
281 | return -EINVAL; | ||
282 | |||
283 | spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
284 | if (tty_ldiscs[disc].refcount) | ||
285 | ret = -EBUSY; | ||
286 | else | ||
287 | tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; | ||
288 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
289 | |||
290 | return ret; | ||
291 | } | ||
292 | EXPORT_SYMBOL(tty_unregister_ldisc); | ||
293 | |||
283 | struct tty_ldisc *tty_ldisc_get(int disc) | 294 | struct tty_ldisc *tty_ldisc_get(int disc) |
284 | { | 295 | { |
285 | unsigned long flags; | 296 | unsigned long flags; |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 06a31da2381c..b53e2e2b5aee 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -414,6 +414,16 @@ config WATCHDOG_RIO | |||
414 | machines. The watchdog timeout period is normally one minute but | 414 | machines. The watchdog timeout period is normally one minute but |
415 | can be changed with a boot-time parameter. | 415 | can be changed with a boot-time parameter. |
416 | 416 | ||
417 | # ppc64 RTAS watchdog | ||
418 | config WATCHDOG_RTAS | ||
419 | tristate "RTAS watchdog" | ||
420 | depends on WATCHDOG && PPC_RTAS | ||
421 | help | ||
422 | This driver adds watchdog support for the RTAS watchdog. | ||
423 | |||
424 | To compile this driver as a module, choose M here. The module | ||
425 | will be called wdrtas. | ||
426 | |||
417 | # | 427 | # |
418 | # ISA-based Watchdog Cards | 428 | # ISA-based Watchdog Cards |
419 | # | 429 | # |
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 1cd27efa35c1..c1838834ea7f 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile | |||
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o | |||
33 | obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o | 33 | obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o |
34 | obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o | 34 | obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o |
35 | obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o | 35 | obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o |
36 | obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o | ||
36 | 37 | ||
37 | # Only one watchdog can succeed. We probe the hardware watchdog | 38 | # Only one watchdog can succeed. We probe the hardware watchdog |
38 | # drivers first, then the softdog driver. This means if your hardware | 39 | # drivers first, then the softdog driver. This means if your hardware |
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c new file mode 100644 index 000000000000..619e2ffca33f --- /dev/null +++ b/drivers/char/watchdog/wdrtas.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /* | ||
2 | * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as | ||
3 | * RTAS calls are available | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | * RTAS watchdog driver | ||
8 | * | ||
9 | * (C) Copyright IBM Corp. 2005 | ||
10 | * device driver to exploit watchdog RTAS functions | ||
11 | * | ||
12 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2, or (at your option) | ||
17 | * any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/config.h> | ||
30 | #include <linux/fs.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/miscdevice.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/notifier.h> | ||
36 | #include <linux/reboot.h> | ||
37 | #include <linux/types.h> | ||
38 | #include <linux/watchdog.h> | ||
39 | |||
40 | #include <asm/rtas.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | |||
43 | #define WDRTAS_MAGIC_CHAR 42 | ||
44 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ | ||
45 | WDIOF_MAGICCLOSE) | ||
46 | |||
47 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); | ||
48 | MODULE_DESCRIPTION("RTAS watchdog driver"); | ||
49 | MODULE_LICENSE("GPL"); | ||
50 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
51 | MODULE_ALIAS_MISCDEV(TEMP_MINOR); | ||
52 | |||
53 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | ||
54 | static int wdrtas_nowayout = 1; | ||
55 | #else | ||
56 | static int wdrtas_nowayout = 0; | ||
57 | #endif | ||
58 | |||
59 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); | ||
60 | static char wdrtas_expect_close = 0; | ||
61 | |||
62 | static int wdrtas_interval; | ||
63 | |||
64 | #define WDRTAS_THERMAL_SENSOR 3 | ||
65 | static int wdrtas_token_get_sensor_state; | ||
66 | #define WDRTAS_SURVEILLANCE_IND 9000 | ||
67 | static int wdrtas_token_set_indicator; | ||
68 | #define WDRTAS_SP_SPI 28 | ||
69 | static int wdrtas_token_get_sp; | ||
70 | static int wdrtas_token_event_scan; | ||
71 | |||
72 | #define WDRTAS_DEFAULT_INTERVAL 300 | ||
73 | |||
74 | #define WDRTAS_LOGBUFFER_LEN 128 | ||
75 | static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN]; | ||
76 | |||
77 | |||
78 | /*** watchdog access functions */ | ||
79 | |||
80 | /** | ||
81 | * wdrtas_set_interval - sets the watchdog interval | ||
82 | * @interval: new interval | ||
83 | * | ||
84 | * returns 0 on success, <0 on failures | ||
85 | * | ||
86 | * wdrtas_set_interval sets the watchdog keepalive interval by calling the | ||
87 | * RTAS function set-indicator (surveillance). The unit of interval is | ||
88 | * seconds. | ||
89 | */ | ||
90 | static int | ||
91 | wdrtas_set_interval(int interval) | ||
92 | { | ||
93 | long result; | ||
94 | static int print_msg = 10; | ||
95 | |||
96 | /* rtas uses minutes */ | ||
97 | interval = (interval + 59) / 60; | ||
98 | |||
99 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, | ||
100 | WDRTAS_SURVEILLANCE_IND, 0, interval); | ||
101 | if ( (result < 0) && (print_msg) ) { | ||
102 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " | ||
103 | "timeout failed: %li\n", interval, result); | ||
104 | print_msg--; | ||
105 | } | ||
106 | |||
107 | return result; | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * wdrtas_get_interval - returns the current watchdog interval | ||
112 | * @fallback_value: value (in seconds) to use, if the RTAS call fails | ||
113 | * | ||
114 | * returns the interval | ||
115 | * | ||
116 | * wdrtas_get_interval returns the current watchdog keepalive interval | ||
117 | * as reported by the RTAS function ibm,get-system-parameter. The unit | ||
118 | * of the return value is seconds. | ||
119 | */ | ||
120 | static int | ||
121 | wdrtas_get_interval(int fallback_value) | ||
122 | { | ||
123 | long result; | ||
124 | char value[4]; | ||
125 | |||
126 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, | ||
127 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); | ||
128 | if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || | ||
129 | (result < 0) ) { | ||
130 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " | ||
131 | "timeout (%li). Continuing\n", result); | ||
132 | return fallback_value; | ||
133 | } | ||
134 | |||
135 | /* rtas uses minutes */ | ||
136 | return ((int)value[2]) * 60; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * wdrtas_timer_start - starts watchdog | ||
141 | * | ||
142 | * wdrtas_timer_start starts the watchdog by calling the RTAS function | ||
143 | * set-interval (surveillance) | ||
144 | */ | ||
145 | static void | ||
146 | wdrtas_timer_start(void) | ||
147 | { | ||
148 | wdrtas_set_interval(wdrtas_interval); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * wdrtas_timer_stop - stops watchdog | ||
153 | * | ||
154 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function | ||
155 | * set-interval (surveillance) | ||
156 | */ | ||
157 | static void | ||
158 | wdrtas_timer_stop(void) | ||
159 | { | ||
160 | wdrtas_set_interval(0); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * wdrtas_log_scanned_event - logs an event we received during keepalive | ||
165 | * | ||
166 | * wdrtas_log_scanned_event prints a message to the log buffer dumping | ||
167 | * the results of the last event-scan call | ||
168 | */ | ||
169 | static void | ||
170 | wdrtas_log_scanned_event(void) | ||
171 | { | ||
172 | int i; | ||
173 | |||
174 | for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16) | ||
175 | printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = " | ||
176 | "%02x %02x %02x %02x %02x %02x %02x %02x " | ||
177 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
178 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), | ||
179 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], | ||
180 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], | ||
181 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], | ||
182 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], | ||
183 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], | ||
184 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], | ||
185 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], | ||
186 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * wdrtas_timer_keepalive - resets watchdog timer to keep system alive | ||
191 | * | ||
192 | * wdrtas_timer_keepalive restarts the watchdog timer by calling the | ||
193 | * RTAS function event-scan and repeats these calls as long as there are | ||
194 | * events available. All events will be dumped. | ||
195 | */ | ||
196 | static void | ||
197 | wdrtas_timer_keepalive(void) | ||
198 | { | ||
199 | long result; | ||
200 | |||
201 | do { | ||
202 | result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL, | ||
203 | RTAS_EVENT_SCAN_ALL_EVENTS, 0, | ||
204 | (void *)__pa(wdrtas_logbuffer), | ||
205 | WDRTAS_LOGBUFFER_LEN); | ||
206 | if (result < 0) | ||
207 | printk(KERN_ERR "wdrtas: event-scan failed: %li\n", | ||
208 | result); | ||
209 | if (result == 0) | ||
210 | wdrtas_log_scanned_event(); | ||
211 | } while (result == 0); | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * wdrtas_get_temperature - returns current temperature | ||
216 | * | ||
217 | * returns temperature or <0 on failures | ||
218 | * | ||
219 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It | ||
220 | * uses the RTAS call get-sensor-state, token 3 to do so | ||
221 | */ | ||
222 | static int | ||
223 | wdrtas_get_temperature(void) | ||
224 | { | ||
225 | long result; | ||
226 | int temperature = 0; | ||
227 | |||
228 | result = rtas_call(wdrtas_token_get_sensor_state, 2, 2, | ||
229 | (void *)__pa(&temperature), | ||
230 | WDRTAS_THERMAL_SENSOR, 0); | ||
231 | |||
232 | if (result < 0) | ||
233 | printk(KERN_WARNING "wdrtas: reading the thermal sensor " | ||
234 | "faild: %li\n", result); | ||
235 | else | ||
236 | temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */ | ||
237 | |||
238 | return temperature; | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * wdrtas_get_status - returns the status of the watchdog | ||
243 | * | ||
244 | * returns a bitmask of defines WDIOF_... as defined in | ||
245 | * include/linux/watchdog.h | ||
246 | */ | ||
247 | static int | ||
248 | wdrtas_get_status(void) | ||
249 | { | ||
250 | return 0; /* TODO */ | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * wdrtas_get_boot_status - returns the reason for the last boot | ||
255 | * | ||
256 | * returns a bitmask of defines WDIOF_... as defined in | ||
257 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system | ||
258 | */ | ||
259 | static int | ||
260 | wdrtas_get_boot_status(void) | ||
261 | { | ||
262 | return 0; /* TODO */ | ||
263 | } | ||
264 | |||
265 | /*** watchdog API and operations stuff */ | ||
266 | |||
267 | /* wdrtas_write - called when watchdog device is written to | ||
268 | * @file: file structure | ||
269 | * @buf: user buffer with data | ||
270 | * @len: amount to data written | ||
271 | * @ppos: position in file | ||
272 | * | ||
273 | * returns the number of successfully processed characters, which is always | ||
274 | * the number of bytes passed to this function | ||
275 | * | ||
276 | * wdrtas_write processes all the data given to it and looks for the magic | ||
277 | * character 'V'. This character allows the watchdog device to be closed | ||
278 | * properly. | ||
279 | */ | ||
280 | static ssize_t | ||
281 | wdrtas_write(struct file *file, const char __user *buf, | ||
282 | size_t len, loff_t *ppos) | ||
283 | { | ||
284 | int i; | ||
285 | char c; | ||
286 | |||
287 | if (!len) | ||
288 | goto out; | ||
289 | |||
290 | if (!wdrtas_nowayout) { | ||
291 | wdrtas_expect_close = 0; | ||
292 | /* look for 'V' */ | ||
293 | for (i = 0; i < len; i++) { | ||
294 | if (get_user(c, buf + i)) | ||
295 | return -EFAULT; | ||
296 | /* allow to close device */ | ||
297 | if (c == 'V') | ||
298 | wdrtas_expect_close = WDRTAS_MAGIC_CHAR; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | wdrtas_timer_keepalive(); | ||
303 | |||
304 | out: | ||
305 | return len; | ||
306 | } | ||
307 | |||
308 | /** | ||
309 | * wdrtas_ioctl - ioctl function for the watchdog device | ||
310 | * @inode: inode structure | ||
311 | * @file: file structure | ||
312 | * @cmd: command for ioctl | ||
313 | * @arg: argument pointer | ||
314 | * | ||
315 | * returns 0 on success, <0 on failure | ||
316 | * | ||
317 | * wdrtas_ioctl implements the watchdog API ioctls | ||
318 | */ | ||
319 | static int | ||
320 | wdrtas_ioctl(struct inode *inode, struct file *file, | ||
321 | unsigned int cmd, unsigned long arg) | ||
322 | { | ||
323 | int __user *argp = (void *)arg; | ||
324 | int i; | ||
325 | static struct watchdog_info wdinfo = { | ||
326 | .options = WDRTAS_SUPPORTED_MASK, | ||
327 | .firmware_version = 0, | ||
328 | .identity = "wdrtas" | ||
329 | }; | ||
330 | |||
331 | switch (cmd) { | ||
332 | case WDIOC_GETSUPPORT: | ||
333 | if (copy_to_user(argp, &wdinfo, sizeof(wdinfo))) | ||
334 | return -EFAULT; | ||
335 | return 0; | ||
336 | |||
337 | case WDIOC_GETSTATUS: | ||
338 | i = wdrtas_get_status(); | ||
339 | return put_user(i, argp); | ||
340 | |||
341 | case WDIOC_GETBOOTSTATUS: | ||
342 | i = wdrtas_get_boot_status(); | ||
343 | return put_user(i, argp); | ||
344 | |||
345 | case WDIOC_GETTEMP: | ||
346 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) | ||
347 | return -EOPNOTSUPP; | ||
348 | |||
349 | i = wdrtas_get_temperature(); | ||
350 | return put_user(i, argp); | ||
351 | |||
352 | case WDIOC_SETOPTIONS: | ||
353 | if (get_user(i, argp)) | ||
354 | return -EFAULT; | ||
355 | if (i & WDIOS_DISABLECARD) | ||
356 | wdrtas_timer_stop(); | ||
357 | if (i & WDIOS_ENABLECARD) { | ||
358 | wdrtas_timer_keepalive(); | ||
359 | wdrtas_timer_start(); | ||
360 | } | ||
361 | if (i & WDIOS_TEMPPANIC) { | ||
362 | /* not implemented. Done by H8 */ | ||
363 | } | ||
364 | return 0; | ||
365 | |||
366 | case WDIOC_KEEPALIVE: | ||
367 | wdrtas_timer_keepalive(); | ||
368 | return 0; | ||
369 | |||
370 | case WDIOC_SETTIMEOUT: | ||
371 | if (get_user(i, argp)) | ||
372 | return -EFAULT; | ||
373 | |||
374 | if (wdrtas_set_interval(i)) | ||
375 | return -EINVAL; | ||
376 | |||
377 | wdrtas_timer_keepalive(); | ||
378 | |||
379 | if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) | ||
380 | wdrtas_interval = i; | ||
381 | else | ||
382 | wdrtas_interval = wdrtas_get_interval(i); | ||
383 | /* fallthrough */ | ||
384 | |||
385 | case WDIOC_GETTIMEOUT: | ||
386 | return put_user(wdrtas_interval, argp); | ||
387 | |||
388 | default: | ||
389 | return -ENOIOCTLCMD; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * wdrtas_open - open function of watchdog device | ||
395 | * @inode: inode structure | ||
396 | * @file: file structure | ||
397 | * | ||
398 | * returns 0 on success, -EBUSY if the file has been opened already, <0 on | ||
399 | * other failures | ||
400 | * | ||
401 | * function called when watchdog device is opened | ||
402 | */ | ||
403 | static int | ||
404 | wdrtas_open(struct inode *inode, struct file *file) | ||
405 | { | ||
406 | /* only open once */ | ||
407 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { | ||
408 | atomic_dec(&wdrtas_miscdev_open); | ||
409 | return -EBUSY; | ||
410 | } | ||
411 | |||
412 | wdrtas_timer_start(); | ||
413 | wdrtas_timer_keepalive(); | ||
414 | |||
415 | return nonseekable_open(inode, file); | ||
416 | } | ||
417 | |||
418 | /** | ||
419 | * wdrtas_close - close function of watchdog device | ||
420 | * @inode: inode structure | ||
421 | * @file: file structure | ||
422 | * | ||
423 | * returns 0 on success | ||
424 | * | ||
425 | * close function. Always succeeds | ||
426 | */ | ||
427 | static int | ||
428 | wdrtas_close(struct inode *inode, struct file *file) | ||
429 | { | ||
430 | /* only stop watchdog, if this was announced using 'V' before */ | ||
431 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) | ||
432 | wdrtas_timer_stop(); | ||
433 | else { | ||
434 | printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog " | ||
435 | "not stopped.\n"); | ||
436 | wdrtas_timer_keepalive(); | ||
437 | } | ||
438 | |||
439 | wdrtas_expect_close = 0; | ||
440 | atomic_dec(&wdrtas_miscdev_open); | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | * wdrtas_temp_read - gives back the temperature in fahrenheit | ||
446 | * @file: file structure | ||
447 | * @buf: user buffer | ||
448 | * @count: number of bytes to be read | ||
449 | * @ppos: position in file | ||
450 | * | ||
451 | * returns always 1 or -EFAULT in case of user space copy failures, <0 on | ||
452 | * other failures | ||
453 | * | ||
454 | * wdrtas_temp_read gives the temperature to the users by copying this | ||
455 | * value as one byte into the user space buffer. The unit is Fahrenheit... | ||
456 | */ | ||
457 | static ssize_t | ||
458 | wdrtas_temp_read(struct file *file, char __user *buf, | ||
459 | size_t count, loff_t *ppos) | ||
460 | { | ||
461 | int temperature = 0; | ||
462 | |||
463 | temperature = wdrtas_get_temperature(); | ||
464 | if (temperature < 0) | ||
465 | return temperature; | ||
466 | |||
467 | if (copy_to_user(buf, &temperature, 1)) | ||
468 | return -EFAULT; | ||
469 | |||
470 | return 1; | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * wdrtas_temp_open - open function of temperature device | ||
475 | * @inode: inode structure | ||
476 | * @file: file structure | ||
477 | * | ||
478 | * returns 0 on success, <0 on failure | ||
479 | * | ||
480 | * function called when temperature device is opened | ||
481 | */ | ||
482 | static int | ||
483 | wdrtas_temp_open(struct inode *inode, struct file *file) | ||
484 | { | ||
485 | return nonseekable_open(inode, file); | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * wdrtas_temp_close - close function of temperature device | ||
490 | * @inode: inode structure | ||
491 | * @file: file structure | ||
492 | * | ||
493 | * returns 0 on success | ||
494 | * | ||
495 | * close function. Always succeeds | ||
496 | */ | ||
497 | static int | ||
498 | wdrtas_temp_close(struct inode *inode, struct file *file) | ||
499 | { | ||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * wdrtas_reboot - reboot notifier function | ||
505 | * @nb: notifier block structure | ||
506 | * @code: reboot code | ||
507 | * @ptr: unused | ||
508 | * | ||
509 | * returns NOTIFY_DONE | ||
510 | * | ||
511 | * wdrtas_reboot stops the watchdog in case of a reboot | ||
512 | */ | ||
513 | static int | ||
514 | wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | ||
515 | { | ||
516 | if ( (code==SYS_DOWN) || (code==SYS_HALT) ) | ||
517 | wdrtas_timer_stop(); | ||
518 | |||
519 | return NOTIFY_DONE; | ||
520 | } | ||
521 | |||
522 | /*** initialization stuff */ | ||
523 | |||
524 | static struct file_operations wdrtas_fops = { | ||
525 | .owner = THIS_MODULE, | ||
526 | .llseek = no_llseek, | ||
527 | .write = wdrtas_write, | ||
528 | .ioctl = wdrtas_ioctl, | ||
529 | .open = wdrtas_open, | ||
530 | .release = wdrtas_close, | ||
531 | }; | ||
532 | |||
533 | static struct miscdevice wdrtas_miscdev = { | ||
534 | .minor = WATCHDOG_MINOR, | ||
535 | .name = "watchdog", | ||
536 | .fops = &wdrtas_fops, | ||
537 | }; | ||
538 | |||
539 | static struct file_operations wdrtas_temp_fops = { | ||
540 | .owner = THIS_MODULE, | ||
541 | .llseek = no_llseek, | ||
542 | .read = wdrtas_temp_read, | ||
543 | .open = wdrtas_temp_open, | ||
544 | .release = wdrtas_temp_close, | ||
545 | }; | ||
546 | |||
547 | static struct miscdevice wdrtas_tempdev = { | ||
548 | .minor = TEMP_MINOR, | ||
549 | .name = "temperature", | ||
550 | .fops = &wdrtas_temp_fops, | ||
551 | }; | ||
552 | |||
553 | static struct notifier_block wdrtas_notifier = { | ||
554 | .notifier_call = wdrtas_reboot, | ||
555 | }; | ||
556 | |||
557 | /** | ||
558 | * wdrtas_get_tokens - reads in RTAS tokens | ||
559 | * | ||
560 | * returns 0 on succes, <0 on failure | ||
561 | * | ||
562 | * wdrtas_get_tokens reads in the tokens for the RTAS calls used in | ||
563 | * this watchdog driver. It tolerates, if "get-sensor-state" and | ||
564 | * "ibm,get-system-parameter" are not available. | ||
565 | */ | ||
566 | static int | ||
567 | wdrtas_get_tokens(void) | ||
568 | { | ||
569 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); | ||
570 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { | ||
571 | printk(KERN_WARNING "wdrtas: couldn't get token for " | ||
572 | "get-sensor-state. Trying to continue without " | ||
573 | "temperature support.\n"); | ||
574 | } | ||
575 | |||
576 | wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter"); | ||
577 | if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) { | ||
578 | printk(KERN_WARNING "wdrtas: couldn't get token for " | ||
579 | "ibm,get-system-parameter. Trying to continue with " | ||
580 | "a default timeout value of %i seconds.\n", | ||
581 | WDRTAS_DEFAULT_INTERVAL); | ||
582 | } | ||
583 | |||
584 | wdrtas_token_set_indicator = rtas_token("set-indicator"); | ||
585 | if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) { | ||
586 | printk(KERN_ERR "wdrtas: couldn't get token for " | ||
587 | "set-indicator. Terminating watchdog code.\n"); | ||
588 | return -EIO; | ||
589 | } | ||
590 | |||
591 | wdrtas_token_event_scan = rtas_token("event-scan"); | ||
592 | if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) { | ||
593 | printk(KERN_ERR "wdrtas: couldn't get token for event-scan. " | ||
594 | "Terminating watchdog code.\n"); | ||
595 | return -EIO; | ||
596 | } | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * wdrtas_unregister_devs - unregisters the misc dev handlers | ||
603 | * | ||
604 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog | ||
605 | * misc devs | ||
606 | */ | ||
607 | static void | ||
608 | wdrtas_unregister_devs(void) | ||
609 | { | ||
610 | misc_deregister(&wdrtas_miscdev); | ||
611 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) | ||
612 | misc_deregister(&wdrtas_tempdev); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * wdrtas_register_devs - registers the misc dev handlers | ||
617 | * | ||
618 | * returns 0 on succes, <0 on failure | ||
619 | * | ||
620 | * wdrtas_register_devs registers the watchdog and temperature watchdog | ||
621 | * misc devs | ||
622 | */ | ||
623 | static int | ||
624 | wdrtas_register_devs(void) | ||
625 | { | ||
626 | int result; | ||
627 | |||
628 | result = misc_register(&wdrtas_miscdev); | ||
629 | if (result) { | ||
630 | printk(KERN_ERR "wdrtas: couldn't register watchdog misc " | ||
631 | "device. Terminating watchdog code.\n"); | ||
632 | return result; | ||
633 | } | ||
634 | |||
635 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) { | ||
636 | result = misc_register(&wdrtas_tempdev); | ||
637 | if (result) { | ||
638 | printk(KERN_WARNING "wdrtas: couldn't register " | ||
639 | "watchdog temperature misc device. Continuing " | ||
640 | "without temperature support.\n"); | ||
641 | wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | /** | ||
649 | * wdrtas_init - init function of the watchdog driver | ||
650 | * | ||
651 | * returns 0 on succes, <0 on failure | ||
652 | * | ||
653 | * registers the file handlers and the reboot notifier | ||
654 | */ | ||
655 | static int __init | ||
656 | wdrtas_init(void) | ||
657 | { | ||
658 | if (wdrtas_get_tokens()) | ||
659 | return -ENODEV; | ||
660 | |||
661 | if (wdrtas_register_devs()) | ||
662 | return -ENODEV; | ||
663 | |||
664 | if (register_reboot_notifier(&wdrtas_notifier)) { | ||
665 | printk(KERN_ERR "wdrtas: could not register reboot notifier. " | ||
666 | "Terminating watchdog code.\n"); | ||
667 | wdrtas_unregister_devs(); | ||
668 | return -ENODEV; | ||
669 | } | ||
670 | |||
671 | if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) | ||
672 | wdrtas_interval = WDRTAS_DEFAULT_INTERVAL; | ||
673 | else | ||
674 | wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * wdrtas_exit - exit function of the watchdog driver | ||
681 | * | ||
682 | * unregisters the file handlers and the reboot notifier | ||
683 | */ | ||
684 | static void __exit | ||
685 | wdrtas_exit(void) | ||
686 | { | ||
687 | if (!wdrtas_nowayout) | ||
688 | wdrtas_timer_stop(); | ||
689 | |||
690 | wdrtas_unregister_devs(); | ||
691 | |||
692 | unregister_reboot_notifier(&wdrtas_notifier); | ||
693 | } | ||
694 | |||
695 | module_init(wdrtas_init); | ||
696 | module_exit(wdrtas_exit); | ||
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index df1b721154d2..839b44a7e08b 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c | |||
@@ -23,12 +23,15 @@ setup_serial_console(struct pcdp_uart *uart) | |||
23 | { | 23 | { |
24 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 24 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
25 | int mmio; | 25 | int mmio; |
26 | static char options[64]; | 26 | static char options[64], *p = options; |
27 | 27 | ||
28 | mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); | 28 | mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); |
29 | snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d", | 29 | p += sprintf(p, "console=uart,%s,0x%lx", |
30 | mmio ? "mmio" : "io", uart->addr.address, uart->baud, | 30 | mmio ? "mmio" : "io", uart->addr.address); |
31 | uart->bits ? uart->bits : 8); | 31 | if (uart->baud) |
32 | p += sprintf(p, ",%lu", uart->baud); | ||
33 | if (uart->bits) | ||
34 | p += sprintf(p, "n%d", uart->bits); | ||
32 | 35 | ||
33 | return early_serial_console_init(options); | 36 | return early_serial_console_init(options); |
34 | #else | 37 | #else |
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h index 863bb6f768c3..1dc7c88b7b4d 100644 --- a/drivers/firmware/pcdp.h +++ b/drivers/firmware/pcdp.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * Definitions for PCDP-defined console devices | 2 | * Definitions for PCDP-defined console devices |
3 | * | 3 | * |
4 | * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf | 4 | * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf |
5 | * v2.0: http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf | 5 | * v2.0: http://www.dig64.org/specifications/DIG64_PCDPv20.pdf |
6 | * | 6 | * |
7 | * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P. | 7 | * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P. |
8 | * Khalid Aziz <khalid.aziz@hp.com> | 8 | * Khalid Aziz <khalid.aziz@hp.com> |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 39f3e9101ed4..0a31cfda08a0 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -2657,16 +2657,63 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock) | |||
2657 | } | 2657 | } |
2658 | 2658 | ||
2659 | static | 2659 | static |
2660 | int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap) | ||
2661 | { | ||
2662 | struct cdrom_info *info = drive->driver_data; | ||
2663 | struct cdrom_device_info *cdi = &info->devinfo; | ||
2664 | struct packet_command cgc; | ||
2665 | int stat, attempts = 3, size = sizeof(*cap); | ||
2666 | |||
2667 | /* | ||
2668 | * ACER50 (and others?) require the full spec length mode sense | ||
2669 | * page capabilities size, but older drives break. | ||
2670 | */ | ||
2671 | if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || | ||
2672 | !strcmp(drive->id->model, "WPI CDS-32X"))) | ||
2673 | size -= sizeof(cap->pad); | ||
2674 | |||
2675 | init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN); | ||
2676 | do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ | ||
2677 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); | ||
2678 | if (!stat) | ||
2679 | break; | ||
2680 | } while (--attempts); | ||
2681 | return stat; | ||
2682 | } | ||
2683 | |||
2684 | static | ||
2685 | void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap) | ||
2686 | { | ||
2687 | /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ | ||
2688 | if (!drive->id->model[0] && | ||
2689 | !strncmp(drive->id->fw_rev, "241N", 4)) { | ||
2690 | CDROM_STATE_FLAGS(drive)->current_speed = | ||
2691 | (((unsigned int)cap->curspeed) + (176/2)) / 176; | ||
2692 | CDROM_CONFIG_FLAGS(drive)->max_speed = | ||
2693 | (((unsigned int)cap->maxspeed) + (176/2)) / 176; | ||
2694 | } else { | ||
2695 | CDROM_STATE_FLAGS(drive)->current_speed = | ||
2696 | (ntohs(cap->curspeed) + (176/2)) / 176; | ||
2697 | CDROM_CONFIG_FLAGS(drive)->max_speed = | ||
2698 | (ntohs(cap->maxspeed) + (176/2)) / 176; | ||
2699 | } | ||
2700 | } | ||
2701 | |||
2702 | static | ||
2660 | int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) | 2703 | int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) |
2661 | { | 2704 | { |
2662 | ide_drive_t *drive = (ide_drive_t*) cdi->handle; | 2705 | ide_drive_t *drive = (ide_drive_t*) cdi->handle; |
2663 | struct request_sense sense; | 2706 | struct request_sense sense; |
2707 | struct atapi_capabilities_page cap; | ||
2664 | int stat; | 2708 | int stat; |
2665 | 2709 | ||
2666 | if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0) | 2710 | if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0) |
2667 | return stat; | 2711 | return stat; |
2668 | 2712 | ||
2669 | cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; | 2713 | if (!ide_cdrom_get_capabilities(drive, &cap)) { |
2714 | ide_cdrom_update_speed(drive, &cap); | ||
2715 | cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; | ||
2716 | } | ||
2670 | return 0; | 2717 | return 0; |
2671 | } | 2718 | } |
2672 | 2719 | ||
@@ -2869,31 +2916,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) | |||
2869 | } | 2916 | } |
2870 | 2917 | ||
2871 | static | 2918 | static |
2872 | int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap) | ||
2873 | { | ||
2874 | struct cdrom_info *info = drive->driver_data; | ||
2875 | struct cdrom_device_info *cdi = &info->devinfo; | ||
2876 | struct packet_command cgc; | ||
2877 | int stat, attempts = 3, size = sizeof(*cap); | ||
2878 | |||
2879 | /* | ||
2880 | * ACER50 (and others?) require the full spec length mode sense | ||
2881 | * page capabilities size, but older drives break. | ||
2882 | */ | ||
2883 | if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || | ||
2884 | !strcmp(drive->id->model, "WPI CDS-32X"))) | ||
2885 | size -= sizeof(cap->pad); | ||
2886 | |||
2887 | init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN); | ||
2888 | do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ | ||
2889 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); | ||
2890 | if (!stat) | ||
2891 | break; | ||
2892 | } while (--attempts); | ||
2893 | return stat; | ||
2894 | } | ||
2895 | |||
2896 | static | ||
2897 | int ide_cdrom_probe_capabilities (ide_drive_t *drive) | 2919 | int ide_cdrom_probe_capabilities (ide_drive_t *drive) |
2898 | { | 2920 | { |
2899 | struct cdrom_info *info = drive->driver_data; | 2921 | struct cdrom_info *info = drive->driver_data; |
@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) | |||
2978 | } | 3000 | } |
2979 | } | 3001 | } |
2980 | 3002 | ||
2981 | /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ | 3003 | ide_cdrom_update_speed(drive, &cap); |
2982 | if (!drive->id->model[0] && | ||
2983 | !strncmp(drive->id->fw_rev, "241N", 4)) { | ||
2984 | CDROM_STATE_FLAGS(drive)->current_speed = | ||
2985 | (((unsigned int)cap.curspeed) + (176/2)) / 176; | ||
2986 | CDROM_CONFIG_FLAGS(drive)->max_speed = | ||
2987 | (((unsigned int)cap.maxspeed) + (176/2)) / 176; | ||
2988 | } else { | ||
2989 | CDROM_STATE_FLAGS(drive)->current_speed = | ||
2990 | (ntohs(cap.curspeed) + (176/2)) / 176; | ||
2991 | CDROM_CONFIG_FLAGS(drive)->max_speed = | ||
2992 | (ntohs(cap.maxspeed) + (176/2)) / 176; | ||
2993 | } | ||
2994 | |||
2995 | /* don't print speed if the drive reported 0. | 3004 | /* don't print speed if the drive reported 0. |
2996 | */ | 3005 | */ |
2997 | printk(KERN_INFO "%s: ATAPI", drive->name); | 3006 | printk(KERN_INFO "%s: ATAPI", drive->name); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 3302cd8eab4c..d6f934886b04 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -1215,7 +1215,8 @@ static int ide_disk_probe(struct device *dev) | |||
1215 | if (!idkp) | 1215 | if (!idkp) |
1216 | goto failed; | 1216 | goto failed; |
1217 | 1217 | ||
1218 | g = alloc_disk(1 << PARTN_BITS); | 1218 | g = alloc_disk_node(1 << PARTN_BITS, |
1219 | pcibus_to_node(drive->hwif->pci_dev->bus)); | ||
1219 | if (!g) | 1220 | if (!g) |
1220 | goto out_free_idkp; | 1221 | goto out_free_idkp; |
1221 | 1222 | ||
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index c949e98df4b6..9eab6426148e 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -661,10 +661,12 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un | |||
661 | 661 | ||
662 | idefloppy_do_end_request(drive, 1, done >> 9); | 662 | idefloppy_do_end_request(drive, 1, done >> 9); |
663 | 663 | ||
664 | #if IDEFLOPPY_DEBUG_BUGS | ||
664 | if (bcount) { | 665 | if (bcount) { |
665 | printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); | 666 | printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); |
666 | idefloppy_write_zeros(drive, bcount); | 667 | idefloppy_write_zeros(drive, bcount); |
667 | } | 668 | } |
669 | #endif | ||
668 | } | 670 | } |
669 | 671 | ||
670 | static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) | 672 | static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) |
@@ -1048,6 +1050,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
1048 | atapi_bcount_t bcount; | 1050 | atapi_bcount_t bcount; |
1049 | ide_handler_t *pkt_xfer_routine; | 1051 | ide_handler_t *pkt_xfer_routine; |
1050 | 1052 | ||
1053 | #if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone | ||
1054 | and have lived on another thread's stack; that stack may have become | ||
1055 | unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */ | ||
1051 | #if IDEFLOPPY_DEBUG_BUGS | 1056 | #if IDEFLOPPY_DEBUG_BUGS |
1052 | if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && | 1057 | if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && |
1053 | pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { | 1058 | pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { |
@@ -1055,6 +1060,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
1055 | "Two request sense in serial were issued\n"); | 1060 | "Two request sense in serial were issued\n"); |
1056 | } | 1061 | } |
1057 | #endif /* IDEFLOPPY_DEBUG_BUGS */ | 1062 | #endif /* IDEFLOPPY_DEBUG_BUGS */ |
1063 | #endif | ||
1058 | 1064 | ||
1059 | if (floppy->failed_pc == NULL && | 1065 | if (floppy->failed_pc == NULL && |
1060 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) | 1066 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 5d876f53c697..7df85af75371 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -977,8 +977,9 @@ static int ide_init_queue(ide_drive_t *drive) | |||
977 | * limits and LBA48 we could raise it but as yet | 977 | * limits and LBA48 we could raise it but as yet |
978 | * do not. | 978 | * do not. |
979 | */ | 979 | */ |
980 | 980 | ||
981 | q = blk_init_queue(do_ide_request, &ide_lock); | 981 | q = blk_init_queue_node(do_ide_request, &ide_lock, |
982 | pcibus_to_node(drive->hwif->pci_dev->bus)); | ||
982 | if (!q) | 983 | if (!q) |
983 | return 1; | 984 | return 1; |
984 | 985 | ||
@@ -1095,7 +1096,8 @@ static int init_irq (ide_hwif_t *hwif) | |||
1095 | hwgroup->hwif->next = hwif; | 1096 | hwgroup->hwif->next = hwif; |
1096 | spin_unlock_irq(&ide_lock); | 1097 | spin_unlock_irq(&ide_lock); |
1097 | } else { | 1098 | } else { |
1098 | hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); | 1099 | hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL, |
1100 | pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus)); | ||
1099 | if (!hwgroup) | 1101 | if (!hwgroup) |
1100 | goto out_up; | 1102 | goto out_up; |
1101 | 1103 | ||
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index f6b85222ba3d..79ca38469159 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -257,7 +257,7 @@ static int __init serport_init(void) | |||
257 | 257 | ||
258 | static void __exit serport_exit(void) | 258 | static void __exit serport_exit(void) |
259 | { | 259 | { |
260 | tty_register_ldisc(N_MOUSE, NULL); | 260 | tty_unregister_ldisc(N_MOUSE); |
261 | } | 261 | } |
262 | 262 | ||
263 | module_init(serport_init); | 263 | module_init(serport_init); |
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index ee3c869d9701..200a0688f717 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -122,14 +122,6 @@ static struct hash_cell *__get_uuid_cell(const char *str) | |||
122 | /*----------------------------------------------------------------- | 122 | /*----------------------------------------------------------------- |
123 | * Inserting, removing and renaming a device. | 123 | * Inserting, removing and renaming a device. |
124 | *---------------------------------------------------------------*/ | 124 | *---------------------------------------------------------------*/ |
125 | static inline char *kstrdup(const char *str) | ||
126 | { | ||
127 | char *r = kmalloc(strlen(str) + 1, GFP_KERNEL); | ||
128 | if (r) | ||
129 | strcpy(r, str); | ||
130 | return r; | ||
131 | } | ||
132 | |||
133 | static struct hash_cell *alloc_cell(const char *name, const char *uuid, | 125 | static struct hash_cell *alloc_cell(const char *name, const char *uuid, |
134 | struct mapped_device *md) | 126 | struct mapped_device *md) |
135 | { | 127 | { |
@@ -139,7 +131,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid, | |||
139 | if (!hc) | 131 | if (!hc) |
140 | return NULL; | 132 | return NULL; |
141 | 133 | ||
142 | hc->name = kstrdup(name); | 134 | hc->name = kstrdup(name, GFP_KERNEL); |
143 | if (!hc->name) { | 135 | if (!hc->name) { |
144 | kfree(hc); | 136 | kfree(hc); |
145 | return NULL; | 137 | return NULL; |
@@ -149,7 +141,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid, | |||
149 | hc->uuid = NULL; | 141 | hc->uuid = NULL; |
150 | 142 | ||
151 | else { | 143 | else { |
152 | hc->uuid = kstrdup(uuid); | 144 | hc->uuid = kstrdup(uuid, GFP_KERNEL); |
153 | if (!hc->uuid) { | 145 | if (!hc->uuid) { |
154 | kfree(hc->name); | 146 | kfree(hc->name); |
155 | kfree(hc); | 147 | kfree(hc); |
@@ -273,7 +265,7 @@ static int dm_hash_rename(const char *old, const char *new) | |||
273 | /* | 265 | /* |
274 | * duplicate new. | 266 | * duplicate new. |
275 | */ | 267 | */ |
276 | new_name = kstrdup(new); | 268 | new_name = kstrdup(new, GFP_KERNEL); |
277 | if (!new_name) | 269 | if (!new_name) |
278 | return -ENOMEM; | 270 | return -ENOMEM; |
279 | 271 | ||
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index db4f369637b6..d5666c37cb0d 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c | |||
@@ -1109,8 +1109,7 @@ struct net_device * __init ltpc_probe(void) | |||
1109 | inb_p(io+1); | 1109 | inb_p(io+1); |
1110 | inb_p(io+3); | 1110 | inb_p(io+3); |
1111 | 1111 | ||
1112 | set_current_state(TASK_UNINTERRUPTIBLE); | 1112 | msleep(20); |
1113 | schedule_timeout(2*HZ/100); | ||
1114 | 1113 | ||
1115 | inb_p(io+0); | 1114 | inb_p(io+0); |
1116 | inb_p(io+2); | 1115 | inb_p(io+2); |
@@ -1120,8 +1119,7 @@ struct net_device * __init ltpc_probe(void) | |||
1120 | inb_p(io+5); /* enable dma */ | 1119 | inb_p(io+5); /* enable dma */ |
1121 | inb_p(io+6); /* tri-state interrupt line */ | 1120 | inb_p(io+6); /* tri-state interrupt line */ |
1122 | 1121 | ||
1123 | set_current_state(TASK_UNINTERRUPTIBLE); | 1122 | ssleep(1); |
1124 | schedule_timeout(HZ); | ||
1125 | 1123 | ||
1126 | /* now, figure out which dma channel we're using, unless it's | 1124 | /* now, figure out which dma channel we're using, unless it's |
1127 | already been specified */ | 1125 | already been specified */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 325495b8b60c..137226d98d47 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2307,6 +2307,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2307 | tso = e1000_tso(adapter, skb); | 2307 | tso = e1000_tso(adapter, skb); |
2308 | if (tso < 0) { | 2308 | if (tso < 0) { |
2309 | dev_kfree_skb_any(skb); | 2309 | dev_kfree_skb_any(skb); |
2310 | spin_unlock_irqrestore(&adapter->tx_lock, flags); | ||
2310 | return NETDEV_TX_OK; | 2311 | return NETDEV_TX_OK; |
2311 | } | 2312 | } |
2312 | 2313 | ||
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 89454915b857..e44f8e9055ef 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -848,7 +848,7 @@ static void __exit sixpack_exit_driver(void) | |||
848 | { | 848 | { |
849 | int ret; | 849 | int ret; |
850 | 850 | ||
851 | if ((ret = tty_register_ldisc(N_6PACK, NULL))) | 851 | if ((ret = tty_unregister_ldisc(N_6PACK))) |
852 | printk(msg_unregfail, ret); | 852 | printk(msg_unregfail, ret); |
853 | } | 853 | } |
854 | 854 | ||
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 62790511098f..3035422f5ad8 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -934,7 +934,7 @@ static void __exit mkiss_exit_driver(void) | |||
934 | kfree(ax25_ctrls); | 934 | kfree(ax25_ctrls); |
935 | ax25_ctrls = NULL; | 935 | ax25_ctrls = NULL; |
936 | 936 | ||
937 | if ((i = tty_register_ldisc(N_AX25, NULL))) | 937 | if ((i = tty_unregister_ldisc(N_AX25))) |
938 | printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); | 938 | printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); |
939 | } | 939 | } |
940 | 940 | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 7d23aa375908..b8d112348ba4 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -626,7 +626,7 @@ static void __exit irtty_sir_cleanup(void) | |||
626 | { | 626 | { |
627 | int err; | 627 | int err; |
628 | 628 | ||
629 | if ((err = tty_register_ldisc(N_IRDA, NULL))) { | 629 | if ((err = tty_unregister_ldisc(N_IRDA))) { |
630 | IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n", | 630 | IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n", |
631 | __FUNCTION__, err); | 631 | __FUNCTION__, err); |
632 | } | 632 | } |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 33b9d79b1aad..5e48b9ab3045 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -1025,7 +1025,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, | |||
1025 | 1025 | ||
1026 | static void __exit ppp_async_cleanup(void) | 1026 | static void __exit ppp_async_cleanup(void) |
1027 | { | 1027 | { |
1028 | if (tty_register_ldisc(N_PPP, NULL) != 0) | 1028 | if (tty_unregister_ldisc(N_PPP) != 0) |
1029 | printk(KERN_ERR "failed to unregister PPP line discipline\n"); | 1029 | printk(KERN_ERR "failed to unregister PPP line discipline\n"); |
1030 | } | 1030 | } |
1031 | 1031 | ||
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 7d0150b4c629..fd9f50180355 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -793,7 +793,7 @@ err: | |||
793 | static void __exit | 793 | static void __exit |
794 | ppp_sync_cleanup(void) | 794 | ppp_sync_cleanup(void) |
795 | { | 795 | { |
796 | if (tty_register_ldisc(N_SYNC_PPP, NULL) != 0) | 796 | if (tty_unregister_ldisc(N_SYNC_PPP) != 0) |
797 | printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); | 797 | printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); |
798 | } | 798 | } |
799 | 799 | ||
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8f7841c0374d..19112712daf0 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -1430,7 +1430,7 @@ static void __exit slip_exit(void) | |||
1430 | kfree(slip_devs); | 1430 | kfree(slip_devs); |
1431 | slip_devs = NULL; | 1431 | slip_devs = NULL; |
1432 | 1432 | ||
1433 | if ((i = tty_register_ldisc(N_SLIP, NULL))) | 1433 | if ((i = tty_unregister_ldisc(N_SLIP))) |
1434 | { | 1434 | { |
1435 | printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); | 1435 | printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); |
1436 | } | 1436 | } |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 1c540d825551..bdf672c48182 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -829,7 +829,7 @@ static void __exit exit_x25_asy(void) | |||
829 | } | 829 | } |
830 | 830 | ||
831 | kfree(x25_asy_devs); | 831 | kfree(x25_asy_devs); |
832 | tty_register_ldisc(N_X25, NULL); | 832 | tty_unregister_ldisc(N_X25); |
833 | } | 833 | } |
834 | 834 | ||
835 | module_init(init_x25_asy); | 835 | module_init(init_x25_asy); |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index ec8cf29ffced..6c42b573a95a 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -2828,7 +2828,7 @@ static void __exit strip_exit_driver(void) | |||
2828 | /* Unregister with the /proc/net file here. */ | 2828 | /* Unregister with the /proc/net file here. */ |
2829 | proc_net_remove("strip"); | 2829 | proc_net_remove("strip"); |
2830 | 2830 | ||
2831 | if ((i = tty_register_ldisc(N_STRIP, NULL))) | 2831 | if ((i = tty_unregister_ldisc(N_STRIP))) |
2832 | printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); | 2832 | printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); |
2833 | 2833 | ||
2834 | printk(signoff); | 2834 | printk(signoff); |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index e7f3bcb79000..80edfa3abd29 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -2751,7 +2751,6 @@ enum parport_pc_pci_cards { | |||
2751 | netmos_9755, | 2751 | netmos_9755, |
2752 | netmos_9805, | 2752 | netmos_9805, |
2753 | netmos_9815, | 2753 | netmos_9815, |
2754 | netmos_9855, | ||
2755 | }; | 2754 | }; |
2756 | 2755 | ||
2757 | 2756 | ||
@@ -2826,7 +2825,6 @@ static struct parport_pc_pci { | |||
2826 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */ | 2825 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */ |
2827 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ | 2826 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ |
2828 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ | 2827 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ |
2829 | /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ | ||
2830 | }; | 2828 | }; |
2831 | 2829 | ||
2832 | static struct pci_device_id parport_pc_pci_tbl[] = { | 2830 | static struct pci_device_id parport_pc_pci_tbl[] = { |
@@ -2907,8 +2905,6 @@ static struct pci_device_id parport_pc_pci_tbl[] = { | |||
2907 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, | 2905 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, |
2908 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, | 2906 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, |
2909 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, | 2907 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, |
2910 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, | ||
2911 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, | ||
2912 | { 0, } /* terminate list */ | 2908 | { 0, } /* terminate list */ |
2913 | }; | 2909 | }; |
2914 | MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); | 2910 | MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 6715a17b5d0f..00498e2f1205 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -34,6 +34,7 @@ enum parport_pc_pci_cards { | |||
34 | titan_110l = 0, | 34 | titan_110l = 0, |
35 | titan_210l, | 35 | titan_210l, |
36 | netmos_9xx5_combo, | 36 | netmos_9xx5_combo, |
37 | netmos_9855, | ||
37 | avlab_1s1p, | 38 | avlab_1s1p, |
38 | avlab_1s1p_650, | 39 | avlab_1s1p_650, |
39 | avlab_1s1p_850, | 40 | avlab_1s1p_850, |
@@ -87,6 +88,7 @@ static struct parport_pc_pci cards[] __devinitdata = { | |||
87 | /* titan_110l */ { 1, { { 3, -1 }, } }, | 88 | /* titan_110l */ { 1, { { 3, -1 }, } }, |
88 | /* titan_210l */ { 1, { { 3, -1 }, } }, | 89 | /* titan_210l */ { 1, { { 3, -1 }, } }, |
89 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, | 90 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, |
91 | /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, | ||
90 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, | 92 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, |
91 | /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, | 93 | /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, |
92 | /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, | 94 | /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, |
@@ -120,7 +122,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
120 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, | 122 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, |
121 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 123 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
122 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, | 124 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, |
123 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 125 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, |
124 | /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ | 126 | /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ |
125 | { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, | 127 | { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, |
126 | { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, | 128 | { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, |
@@ -207,6 +209,7 @@ static struct pci_board_no_ids pci_boards[] __devinitdata = { | |||
207 | /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, | 209 | /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, |
208 | /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, | 210 | /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, |
209 | /* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, | 211 | /* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, |
212 | /* netmos_9855 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, | ||
210 | /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 213 | /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, |
211 | /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 214 | /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, |
212 | /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 215 | /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, |
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c index c94963145e17..6e6f42d01e64 100644 --- a/drivers/parport/probe.c +++ b/drivers/parport/probe.c | |||
@@ -48,14 +48,6 @@ static void pretty_print(struct parport *port, int device) | |||
48 | printk("\n"); | 48 | printk("\n"); |
49 | } | 49 | } |
50 | 50 | ||
51 | static char *strdup(char *str) | ||
52 | { | ||
53 | int n = strlen(str)+1; | ||
54 | char *s = kmalloc(n, GFP_KERNEL); | ||
55 | if (!s) return NULL; | ||
56 | return strcpy(s, str); | ||
57 | } | ||
58 | |||
59 | static void parse_data(struct parport *port, int device, char *str) | 51 | static void parse_data(struct parport *port, int device, char *str) |
60 | { | 52 | { |
61 | char *txt = kmalloc(strlen(str)+1, GFP_KERNEL); | 53 | char *txt = kmalloc(strlen(str)+1, GFP_KERNEL); |
@@ -88,16 +80,16 @@ static void parse_data(struct parport *port, int device, char *str) | |||
88 | if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { | 80 | if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { |
89 | if (info->mfr) | 81 | if (info->mfr) |
90 | kfree (info->mfr); | 82 | kfree (info->mfr); |
91 | info->mfr = strdup(sep); | 83 | info->mfr = kstrdup(sep, GFP_KERNEL); |
92 | } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) { | 84 | } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) { |
93 | if (info->model) | 85 | if (info->model) |
94 | kfree (info->model); | 86 | kfree (info->model); |
95 | info->model = strdup(sep); | 87 | info->model = kstrdup(sep, GFP_KERNEL); |
96 | } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) { | 88 | } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) { |
97 | int i; | 89 | int i; |
98 | if (info->class_name) | 90 | if (info->class_name) |
99 | kfree (info->class_name); | 91 | kfree (info->class_name); |
100 | info->class_name = strdup(sep); | 92 | info->class_name = kstrdup(sep, GFP_KERNEL); |
101 | for (u = sep; *u; u++) | 93 | for (u = sep; *u; u++) |
102 | *u = toupper(*u); | 94 | *u = toupper(*u); |
103 | for (i = 0; classes[i].token; i++) { | 95 | for (i = 0; classes[i].token; i++) { |
@@ -112,7 +104,7 @@ static void parse_data(struct parport *port, int device, char *str) | |||
112 | !strcmp(p, "COMMAND SET")) { | 104 | !strcmp(p, "COMMAND SET")) { |
113 | if (info->cmdset) | 105 | if (info->cmdset) |
114 | kfree (info->cmdset); | 106 | kfree (info->cmdset); |
115 | info->cmdset = strdup(sep); | 107 | info->cmdset = kstrdup(sep, GFP_KERNEL); |
116 | /* if it speaks printer language, it's | 108 | /* if it speaks printer language, it's |
117 | probably a printer */ | 109 | probably a printer */ |
118 | if (strstr(sep, "PJL") || strstr(sep, "PCL")) | 110 | if (strstr(sep, "PJL") || strstr(sep, "PCL")) |
@@ -120,7 +112,7 @@ static void parse_data(struct parport *port, int device, char *str) | |||
120 | } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) { | 112 | } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) { |
121 | if (info->description) | 113 | if (info->description) |
122 | kfree (info->description); | 114 | kfree (info->description); |
123 | info->description = strdup(sep); | 115 | info->description = kstrdup(sep, GFP_KERNEL); |
124 | } | 116 | } |
125 | } | 117 | } |
126 | rock_on: | 118 | rock_on: |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 03fc885db1c5..d136b3c8fac9 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -508,6 +508,10 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) | |||
508 | cs_err(skt, "unsupported voltage key.\n"); | 508 | cs_err(skt, "unsupported voltage key.\n"); |
509 | return CS_BAD_TYPE; | 509 | return CS_BAD_TYPE; |
510 | } | 510 | } |
511 | |||
512 | if (skt->power_hook) | ||
513 | skt->power_hook(skt, HOOK_POWER_PRE); | ||
514 | |||
511 | skt->socket.flags = 0; | 515 | skt->socket.flags = 0; |
512 | skt->ops->set_socket(skt, &skt->socket); | 516 | skt->ops->set_socket(skt, &skt->socket); |
513 | 517 | ||
@@ -522,7 +526,12 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) | |||
522 | return CS_BAD_TYPE; | 526 | return CS_BAD_TYPE; |
523 | } | 527 | } |
524 | 528 | ||
525 | return socket_reset(skt); | 529 | status = socket_reset(skt); |
530 | |||
531 | if (skt->power_hook) | ||
532 | skt->power_hook(skt, HOOK_POWER_POST); | ||
533 | |||
534 | return status; | ||
526 | } | 535 | } |
527 | 536 | ||
528 | /* | 537 | /* |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index a8a1d104524a..c7ba99871aca 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -611,6 +611,170 @@ out: | |||
611 | } | 611 | } |
612 | } | 612 | } |
613 | 613 | ||
614 | |||
615 | /* Returns true value if the second slot of a two-slot controller is empty */ | ||
616 | static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | ||
617 | { | ||
618 | struct pci_dev *func; | ||
619 | struct yenta_socket *slot2; | ||
620 | int devfn; | ||
621 | unsigned int state; | ||
622 | int ret = 1; | ||
623 | |||
624 | /* catch the two-slot controllers */ | ||
625 | switch (socket->dev->device) { | ||
626 | case PCI_DEVICE_ID_TI_1220: | ||
627 | case PCI_DEVICE_ID_TI_1221: | ||
628 | case PCI_DEVICE_ID_TI_1225: | ||
629 | case PCI_DEVICE_ID_TI_1251A: | ||
630 | case PCI_DEVICE_ID_TI_1251B: | ||
631 | case PCI_DEVICE_ID_TI_1420: | ||
632 | case PCI_DEVICE_ID_TI_1450: | ||
633 | case PCI_DEVICE_ID_TI_1451A: | ||
634 | case PCI_DEVICE_ID_TI_1520: | ||
635 | case PCI_DEVICE_ID_TI_1620: | ||
636 | case PCI_DEVICE_ID_TI_4520: | ||
637 | case PCI_DEVICE_ID_TI_4450: | ||
638 | case PCI_DEVICE_ID_TI_4451: | ||
639 | /* | ||
640 | * there are way more, but they need to be added in yenta_socket.c | ||
641 | * and pci_ids.h first anyway. | ||
642 | */ | ||
643 | break; | ||
644 | |||
645 | /* single-slot controllers have the 2nd slot empty always :) */ | ||
646 | default: | ||
647 | return 1; | ||
648 | } | ||
649 | |||
650 | /* get other slot */ | ||
651 | devfn = socket->dev->devfn & ~0x07; | ||
652 | func = pci_get_slot(socket->dev->bus, | ||
653 | (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01); | ||
654 | if (!func) | ||
655 | return 1; | ||
656 | |||
657 | slot2 = pci_get_drvdata(func); | ||
658 | if (!slot2) | ||
659 | goto out; | ||
660 | |||
661 | /* check state */ | ||
662 | yenta_get_status(&socket->socket, &state); | ||
663 | if (state & SS_DETECT) { | ||
664 | ret = 0; | ||
665 | goto out; | ||
666 | } | ||
667 | |||
668 | out: | ||
669 | pci_dev_put(func); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | /* | ||
674 | * TI specifiy parts for the power hook. | ||
675 | * | ||
676 | * some TI's with some CB's produces interrupt storm on power on. it has been | ||
677 | * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to | ||
678 | * disable any CB interrupts during this time. | ||
679 | */ | ||
680 | static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation) | ||
681 | { | ||
682 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | ||
683 | u32 mfunc, devctl, sysctl; | ||
684 | u8 gpio3; | ||
685 | |||
686 | /* only POWER_PRE and POWER_POST are interesting */ | ||
687 | if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST)) | ||
688 | return 0; | ||
689 | |||
690 | devctl = config_readb(socket, TI113X_DEVICE_CONTROL); | ||
691 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | ||
692 | mfunc = config_readl(socket, TI122X_MFUNC); | ||
693 | |||
694 | /* | ||
695 | * all serial/tied: only disable when modparm set. always doing it | ||
696 | * would mean a regression for working setups 'cos it disables the | ||
697 | * interrupts for both both slots on 2-slot controllers | ||
698 | * (and users of single slot controllers where it's save have to | ||
699 | * live with setting the modparm, most don't have to anyway) | ||
700 | */ | ||
701 | if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) && | ||
702 | (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) { | ||
703 | switch (socket->dev->device) { | ||
704 | case PCI_DEVICE_ID_TI_1250: | ||
705 | case PCI_DEVICE_ID_TI_1251A: | ||
706 | case PCI_DEVICE_ID_TI_1251B: | ||
707 | case PCI_DEVICE_ID_TI_1450: | ||
708 | case PCI_DEVICE_ID_TI_1451A: | ||
709 | case PCI_DEVICE_ID_TI_4450: | ||
710 | case PCI_DEVICE_ID_TI_4451: | ||
711 | /* these chips have no IRQSER setting in MFUNC3 */ | ||
712 | break; | ||
713 | |||
714 | default: | ||
715 | if (operation == HOOK_POWER_PRE) | ||
716 | mfunc = (mfunc & ~TI122X_MFUNC3_MASK); | ||
717 | else | ||
718 | mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER; | ||
719 | } | ||
720 | |||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | /* do the job differently for func0/1 */ | ||
725 | if ((PCI_FUNC(socket->dev->devfn) == 0) || | ||
726 | ((sysctl & TI122X_SCR_INTRTIE) && | ||
727 | (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) { | ||
728 | /* some bridges are different */ | ||
729 | switch (socket->dev->device) { | ||
730 | case PCI_DEVICE_ID_TI_1250: | ||
731 | case PCI_DEVICE_ID_TI_1251A: | ||
732 | case PCI_DEVICE_ID_TI_1251B: | ||
733 | case PCI_DEVICE_ID_TI_1450: | ||
734 | /* those oldies use gpio3 for INTA */ | ||
735 | gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL); | ||
736 | if (operation == HOOK_POWER_PRE) | ||
737 | gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40; | ||
738 | else | ||
739 | gpio3 &= ~TI1250_GPIO_MODE_MASK; | ||
740 | config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3); | ||
741 | break; | ||
742 | |||
743 | default: | ||
744 | /* all new bridges are the same */ | ||
745 | if (operation == HOOK_POWER_PRE) | ||
746 | mfunc &= ~TI122X_MFUNC0_MASK; | ||
747 | else | ||
748 | mfunc |= TI122X_MFUNC0_INTA; | ||
749 | config_writel(socket, TI122X_MFUNC, mfunc); | ||
750 | } | ||
751 | } else { | ||
752 | switch (socket->dev->device) { | ||
753 | case PCI_DEVICE_ID_TI_1251A: | ||
754 | case PCI_DEVICE_ID_TI_1251B: | ||
755 | case PCI_DEVICE_ID_TI_1450: | ||
756 | /* those have INTA elsewhere and INTB in MFUNC0 */ | ||
757 | if (operation == HOOK_POWER_PRE) | ||
758 | mfunc &= ~TI122X_MFUNC0_MASK; | ||
759 | else | ||
760 | mfunc |= TI125X_MFUNC0_INTB; | ||
761 | config_writel(socket, TI122X_MFUNC, mfunc); | ||
762 | |||
763 | break; | ||
764 | |||
765 | default: | ||
766 | /* all new bridges are the same */ | ||
767 | if (operation == HOOK_POWER_PRE) | ||
768 | mfunc &= ~TI122X_MFUNC1_MASK; | ||
769 | else | ||
770 | mfunc |= TI122X_MFUNC1_INTB; | ||
771 | config_writel(socket, TI122X_MFUNC, mfunc); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | return 0; | ||
776 | } | ||
777 | |||
614 | static int ti12xx_override(struct yenta_socket *socket) | 778 | static int ti12xx_override(struct yenta_socket *socket) |
615 | { | 779 | { |
616 | u32 val, val_orig; | 780 | u32 val, val_orig; |
@@ -654,6 +818,9 @@ static int ti12xx_override(struct yenta_socket *socket) | |||
654 | else | 818 | else |
655 | ti12xx_irqroute_func1(socket); | 819 | ti12xx_irqroute_func1(socket); |
656 | 820 | ||
821 | /* install power hook */ | ||
822 | socket->socket.power_hook = ti12xx_power_hook; | ||
823 | |||
657 | return ti_override(socket); | 824 | return ti_override(socket); |
658 | } | 825 | } |
659 | 826 | ||
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 6404d97a12eb..bee05362fd24 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -32,6 +32,14 @@ static int disable_clkrun; | |||
32 | module_param(disable_clkrun, bool, 0444); | 32 | module_param(disable_clkrun, bool, 0444); |
33 | MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); | 33 | MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); |
34 | 34 | ||
35 | static int isa_probe = 1; | ||
36 | module_param(isa_probe, bool, 0444); | ||
37 | MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing"); | ||
38 | |||
39 | static int pwr_irqs_off; | ||
40 | module_param(pwr_irqs_off, bool, 0644); | ||
41 | MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!"); | ||
42 | |||
35 | #if 0 | 43 | #if 0 |
36 | #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) | 44 | #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) |
37 | #else | 45 | #else |
@@ -150,15 +158,16 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) | |||
150 | 158 | ||
151 | val = (state & CB_3VCARD) ? SS_3VCARD : 0; | 159 | val = (state & CB_3VCARD) ? SS_3VCARD : 0; |
152 | val |= (state & CB_XVCARD) ? SS_XVCARD : 0; | 160 | val |= (state & CB_XVCARD) ? SS_XVCARD : 0; |
153 | val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD | 161 | val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING; |
154 | | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING; | 162 | val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0; |
163 | |||
155 | 164 | ||
156 | if (state & CB_CBCARD) { | 165 | if (state & CB_CBCARD) { |
157 | val |= SS_CARDBUS; | 166 | val |= SS_CARDBUS; |
158 | val |= (state & CB_CARDSTS) ? SS_STSCHG : 0; | 167 | val |= (state & CB_CARDSTS) ? SS_STSCHG : 0; |
159 | val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT; | 168 | val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT; |
160 | val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0; | 169 | val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0; |
161 | } else { | 170 | } else if (state & CB_16BITCARD) { |
162 | u8 status = exca_readb(socket, I365_STATUS); | 171 | u8 status = exca_readb(socket, I365_STATUS); |
163 | val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0; | 172 | val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0; |
164 | if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { | 173 | if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { |
@@ -405,11 +414,13 @@ static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map * | |||
405 | } | 414 | } |
406 | 415 | ||
407 | 416 | ||
408 | static unsigned int yenta_events(struct yenta_socket *socket) | 417 | |
418 | static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
409 | { | 419 | { |
420 | unsigned int events; | ||
421 | struct yenta_socket *socket = (struct yenta_socket *) dev_id; | ||
410 | u8 csc; | 422 | u8 csc; |
411 | u32 cb_event; | 423 | u32 cb_event; |
412 | unsigned int events; | ||
413 | 424 | ||
414 | /* Clear interrupt status for the event */ | 425 | /* Clear interrupt status for the event */ |
415 | cb_event = cb_readl(socket, CB_SOCKET_EVENT); | 426 | cb_event = cb_readl(socket, CB_SOCKET_EVENT); |
@@ -426,20 +437,13 @@ static unsigned int yenta_events(struct yenta_socket *socket) | |||
426 | events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; | 437 | events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; |
427 | events |= (csc & I365_CSC_READY) ? SS_READY : 0; | 438 | events |= (csc & I365_CSC_READY) ? SS_READY : 0; |
428 | } | 439 | } |
429 | return events; | ||
430 | } | ||
431 | |||
432 | |||
433 | static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
434 | { | ||
435 | unsigned int events; | ||
436 | struct yenta_socket *socket = (struct yenta_socket *) dev_id; | ||
437 | 440 | ||
438 | events = yenta_events(socket); | 441 | if (events) |
439 | if (events) { | ||
440 | pcmcia_parse_events(&socket->socket, events); | 442 | pcmcia_parse_events(&socket->socket, events); |
443 | |||
444 | if (cb_event || csc) | ||
441 | return IRQ_HANDLED; | 445 | return IRQ_HANDLED; |
442 | } | 446 | |
443 | return IRQ_NONE; | 447 | return IRQ_NONE; |
444 | } | 448 | } |
445 | 449 | ||
@@ -470,11 +474,22 @@ static void yenta_clear_maps(struct yenta_socket *socket) | |||
470 | } | 474 | } |
471 | } | 475 | } |
472 | 476 | ||
477 | /* redoes voltage interrogation if required */ | ||
478 | static void yenta_interrogate(struct yenta_socket *socket) | ||
479 | { | ||
480 | u32 state; | ||
481 | |||
482 | state = cb_readl(socket, CB_SOCKET_STATE); | ||
483 | if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) || | ||
484 | (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) || | ||
485 | ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD))) | ||
486 | cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); | ||
487 | } | ||
488 | |||
473 | /* Called at resume and initialization events */ | 489 | /* Called at resume and initialization events */ |
474 | static int yenta_sock_init(struct pcmcia_socket *sock) | 490 | static int yenta_sock_init(struct pcmcia_socket *sock) |
475 | { | 491 | { |
476 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | 492 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); |
477 | u32 state; | ||
478 | u16 bridge; | 493 | u16 bridge; |
479 | 494 | ||
480 | bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR; | 495 | bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR; |
@@ -486,10 +501,7 @@ static int yenta_sock_init(struct pcmcia_socket *sock) | |||
486 | exca_writeb(socket, I365_GENCTL, 0x00); | 501 | exca_writeb(socket, I365_GENCTL, 0x00); |
487 | 502 | ||
488 | /* Redo card voltage interrogation */ | 503 | /* Redo card voltage interrogation */ |
489 | state = cb_readl(socket, CB_SOCKET_STATE); | 504 | yenta_interrogate(socket); |
490 | if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | | ||
491 | CB_3VCARD | CB_XVCARD | CB_YVCARD))) | ||
492 | cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); | ||
493 | 505 | ||
494 | yenta_clear_maps(socket); | 506 | yenta_clear_maps(socket); |
495 | 507 | ||
@@ -856,7 +868,10 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i | |||
856 | socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; | 868 | socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; |
857 | socket->socket.map_size = 0x1000; | 869 | socket->socket.map_size = 0x1000; |
858 | socket->socket.pci_irq = socket->cb_irq; | 870 | socket->socket.pci_irq = socket->cb_irq; |
859 | socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); | 871 | if (isa_probe) |
872 | socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); | ||
873 | else | ||
874 | socket->socket.irq_mask = 0; | ||
860 | socket->socket.cb_dev = socket->dev; | 875 | socket->socket.cb_dev = socket->dev; |
861 | 876 | ||
862 | printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", | 877 | printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", |
@@ -996,6 +1011,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
996 | } | 1011 | } |
997 | 1012 | ||
998 | /* Figure out what the dang thing can do for the PCMCIA layer... */ | 1013 | /* Figure out what the dang thing can do for the PCMCIA layer... */ |
1014 | yenta_interrogate(socket); | ||
999 | yenta_get_socket_capabilities(socket, isa_interrupts); | 1015 | yenta_get_socket_capabilities(socket, isa_interrupts); |
1000 | printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); | 1016 | printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); |
1001 | 1017 | ||
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 9cc0015b717d..a699c30b2662 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -1126,11 +1126,11 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout) | |||
1126 | struct adpt_i2o_post_wait_data *p1, *p2; | 1126 | struct adpt_i2o_post_wait_data *p1, *p2; |
1127 | struct adpt_i2o_post_wait_data *wait_data = | 1127 | struct adpt_i2o_post_wait_data *wait_data = |
1128 | kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL); | 1128 | kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL); |
1129 | adpt_wait_queue_t wait; | 1129 | DECLARE_WAITQUEUE(wait, current); |
1130 | 1130 | ||
1131 | if(!wait_data){ | 1131 | if (!wait_data) |
1132 | return -ENOMEM; | 1132 | return -ENOMEM; |
1133 | } | 1133 | |
1134 | /* | 1134 | /* |
1135 | * The spin locking is needed to keep anyone from playing | 1135 | * The spin locking is needed to keep anyone from playing |
1136 | * with the queue pointers and id while we do the same | 1136 | * with the queue pointers and id while we do the same |
@@ -1148,12 +1148,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout) | |||
1148 | wait_data->wq = &adpt_wq_i2o_post; | 1148 | wait_data->wq = &adpt_wq_i2o_post; |
1149 | wait_data->status = -ETIMEDOUT; | 1149 | wait_data->status = -ETIMEDOUT; |
1150 | 1150 | ||
1151 | // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout | 1151 | add_wait_queue(&adpt_wq_i2o_post, &wait); |
1152 | wait.task = current; | ||
1153 | init_waitqueue_entry(&wait, current); | ||
1154 | spin_lock_irqsave(&adpt_wq_i2o_post.lock, flags); | ||
1155 | __add_wait_queue(&adpt_wq_i2o_post, &wait); | ||
1156 | spin_unlock(&adpt_wq_i2o_post.lock); | ||
1157 | 1152 | ||
1158 | msg[2] |= 0x80000000 | ((u32)wait_data->id); | 1153 | msg[2] |= 0x80000000 | ((u32)wait_data->id); |
1159 | timeout *= HZ; | 1154 | timeout *= HZ; |
@@ -1175,9 +1170,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout) | |||
1175 | if(pHba->host) | 1170 | if(pHba->host) |
1176 | spin_lock_irq(pHba->host->host_lock); | 1171 | spin_lock_irq(pHba->host->host_lock); |
1177 | } | 1172 | } |
1178 | spin_lock_irq(&adpt_wq_i2o_post.lock); | 1173 | remove_wait_queue(&adpt_wq_i2o_post, &wait); |
1179 | __remove_wait_queue(&adpt_wq_i2o_post, &wait); | ||
1180 | spin_unlock_irqrestore(&adpt_wq_i2o_post.lock, flags); | ||
1181 | 1174 | ||
1182 | if(status == -ETIMEDOUT){ | 1175 | if(status == -ETIMEDOUT){ |
1183 | printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit); | 1176 | printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit); |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index fee6418e84c4..840815fde49b 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -572,6 +572,7 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw) | |||
572 | 572 | ||
573 | if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) { | 573 | if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) { |
574 | /* Nothing to do. */ | 574 | /* Nothing to do. */ |
575 | ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT); | ||
575 | return; | 576 | return; |
576 | } | 577 | } |
577 | 578 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d041782e0c8b..0da23732e807 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1794,7 +1794,7 @@ EXPORT_SYMBOL (usb_remove_hcd); | |||
1794 | 1794 | ||
1795 | /*-------------------------------------------------------------------------*/ | 1795 | /*-------------------------------------------------------------------------*/ |
1796 | 1796 | ||
1797 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) | 1797 | #if defined(CONFIG_USB_MON) |
1798 | 1798 | ||
1799 | struct usb_mon_operations *mon_ops; | 1799 | struct usb_mon_operations *mon_ops; |
1800 | 1800 | ||
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index f67cf1e634fc..325a51656c3f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -399,7 +399,7 @@ static inline void usbfs_cleanup(void) { } | |||
399 | 399 | ||
400 | /*-------------------------------------------------------------------------*/ | 400 | /*-------------------------------------------------------------------------*/ |
401 | 401 | ||
402 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) | 402 | #if defined(CONFIG_USB_MON) |
403 | 403 | ||
404 | struct usb_mon_operations { | 404 | struct usb_mon_operations { |
405 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); | 405 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index f9f9561c6bad..c3e3a95d3804 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -453,17 +453,6 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent) | |||
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
455 | 455 | ||
456 | static struct dentry * get_dentry(struct dentry *parent, const char *name) | ||
457 | { | ||
458 | struct qstr qstr; | ||
459 | |||
460 | qstr.name = name; | ||
461 | qstr.len = strlen(name); | ||
462 | qstr.hash = full_name_hash(name,qstr.len); | ||
463 | return lookup_hash(&qstr,parent); | ||
464 | } | ||
465 | |||
466 | |||
467 | /* | 456 | /* |
468 | * fs_create_by_name - create a file, given a name | 457 | * fs_create_by_name - create a file, given a name |
469 | * @name: name of file | 458 | * @name: name of file |
@@ -496,7 +485,7 @@ static int fs_create_by_name (const char *name, mode_t mode, | |||
496 | 485 | ||
497 | *dentry = NULL; | 486 | *dentry = NULL; |
498 | down(&parent->d_inode->i_sem); | 487 | down(&parent->d_inode->i_sem); |
499 | *dentry = get_dentry (parent, name); | 488 | *dentry = lookup_one_len(name, parent, strlen(name)); |
500 | if (!IS_ERR(dentry)) { | 489 | if (!IS_ERR(dentry)) { |
501 | if ((mode & S_IFMT) == S_IFDIR) | 490 | if ((mode & S_IFMT) == S_IFDIR) |
502 | error = usbfs_mkdir (parent->d_inode, *dentry, mode); | 491 | error = usbfs_mkdir (parent->d_inode, *dentry, mode); |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 2d8bd9dcc6ed..740dec1f521d 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1762,7 +1762,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1762 | intf->altsetting->desc.bInterfaceNumber); | 1762 | intf->altsetting->desc.bInterfaceNumber); |
1763 | 1763 | ||
1764 | if (!(hid = usb_hid_configure(intf))) | 1764 | if (!(hid = usb_hid_configure(intf))) |
1765 | return -EIO; | 1765 | return -ENODEV; |
1766 | 1766 | ||
1767 | hid_init_reports(hid); | 1767 | hid_init_reports(hid); |
1768 | hid_dump_device(hid); | 1768 | hid_dump_device(hid); |
@@ -1777,7 +1777,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1777 | if (!hid->claimed) { | 1777 | if (!hid->claimed) { |
1778 | printk ("HID device not claimed by input or hiddev\n"); | 1778 | printk ("HID device not claimed by input or hiddev\n"); |
1779 | hid_disconnect(intf); | 1779 | hid_disconnect(intf); |
1780 | return -EIO; | 1780 | return -ENODEV; |
1781 | } | 1781 | } |
1782 | 1782 | ||
1783 | printk(KERN_INFO); | 1783 | printk(KERN_INFO); |
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index bc3b1635eab0..ef4204eab6c4 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c | |||
@@ -118,9 +118,9 @@ int pwc_decompress(struct pwc_device *pdev) | |||
118 | return -ENXIO; /* No such device or address: missing decompressor */ | 118 | return -ENXIO; /* No such device or address: missing decompressor */ |
119 | } | 119 | } |
120 | 120 | ||
121 | #if 0 | ||
121 | switch (pdev->type) | 122 | switch (pdev->type) |
122 | { | 123 | { |
123 | #if 0 | ||
124 | case 675: | 124 | case 675: |
125 | case 680: | 125 | case 680: |
126 | case 690: | 126 | case 690: |
@@ -128,18 +128,17 @@ int pwc_decompress(struct pwc_device *pdev) | |||
128 | case 730: | 128 | case 730: |
129 | case 740: | 129 | case 740: |
130 | case 750: | 130 | case 750: |
131 | pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset, | 131 | pwc_dec23_decompress(&pdev->image, &pdev->view, |
132 | yuv, image, | 132 | &pdev->offset, yuv, image, flags, |
133 | flags, | ||
134 | pdev->decompress_data, pdev->vbandlength); | 133 | pdev->decompress_data, pdev->vbandlength); |
135 | break; | 134 | break; |
136 | case 645: | 135 | case 645: |
137 | case 646: | 136 | case 646: |
138 | /* TODO & FIXME */ | 137 | /* TODO & FIXME */ |
139 | #endif | 138 | return -ENXIO; /* Missing decompressor */ |
140 | return -ENXIO; /* No such device or address: missing decompressor */ | ||
141 | break; | 139 | break; |
142 | } | 140 | } |
141 | #endif | ||
143 | } | 142 | } |
144 | return 0; | 143 | return 0; |
145 | } | 144 | } |
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 4e6152aa5f19..777642e26b9a 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig | |||
@@ -2,13 +2,9 @@ | |||
2 | # USB Monitor configuration | 2 | # USB Monitor configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | # In normal life, it makes little sense to have usbmon as a module, and in fact | ||
6 | # it is harmful, because there is no way to autoload the module. | ||
7 | # The 'm' option is allowed for hackers who debug the usbmon itself, | ||
8 | # and for those who have usbcore as a module. | ||
9 | config USB_MON | 5 | config USB_MON |
10 | tristate "USB Monitor" | 6 | bool "USB Monitor" |
11 | depends on USB | 7 | depends on USB!=n |
12 | default y | 8 | default y |
13 | help | 9 | help |
14 | If you say Y here, a component which captures the USB traffic | 10 | If you say Y here, a component which captures the USB traffic |
@@ -17,6 +13,5 @@ config USB_MON | |||
17 | Harding's USBMon. | 13 | Harding's USBMon. |
18 | 14 | ||
19 | This is somewhat experimental at this time, but it should be safe, | 15 | This is somewhat experimental at this time, but it should be safe, |
20 | as long as you aren't building this as a module and then removing it. | 16 | as long as you aren't using modular USB and try to remove this |
21 | 17 | module. | |
22 | If unsure, say Y. Do not say M. | ||
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 3cff8d444bb1..f18d10ce91f9 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o | 5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o |
6 | 6 | ||
7 | obj-$(CONFIG_USB_MON) += usbmon.o | 7 | obj-$(CONFIG_USB) += usbmon.o |