diff options
Diffstat (limited to 'drivers')
81 files changed, 1349 insertions, 1470 deletions
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 31dcd9142d54..dc8d1a90971f 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void) | |||
417 | module_init(agp_ali_init); | 417 | module_init(agp_ali_init); |
418 | module_exit(agp_ali_cleanup); | 418 | module_exit(agp_ali_cleanup); |
419 | 419 | ||
420 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 420 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
421 | MODULE_LICENSE("GPL and additional rights"); | 421 | MODULE_LICENSE("GPL and additional rights"); |
422 | 422 | ||
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2812ee2b165a..52f4361eb6e4 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -772,6 +772,6 @@ module_init(agp_amd64_init); | |||
772 | module_exit(agp_amd64_cleanup); | 772 | module_exit(agp_amd64_cleanup); |
773 | #endif | 773 | #endif |
774 | 774 | ||
775 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen"); | 775 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); |
776 | module_param(agp_try_unsupported, bool, 0); | 776 | module_param(agp_try_unsupported, bool, 0); |
777 | MODULE_LICENSE("GPL"); | 777 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index ae2791b926b9..f1537eece07f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -561,6 +561,6 @@ static void __exit agp_ati_cleanup(void) | |||
561 | module_init(agp_ati_init); | 561 | module_init(agp_ati_init); |
562 | module_exit(agp_ati_cleanup); | 562 | module_exit(agp_ati_cleanup); |
563 | 563 | ||
564 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 564 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
565 | MODULE_LICENSE("GPL and additional rights"); | 565 | MODULE_LICENSE("GPL and additional rights"); |
566 | 566 | ||
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 3a3cc03d401c..8c617ad7497f 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -349,7 +349,7 @@ static __init int agp_setup(char *s) | |||
349 | __setup("agp=", agp_setup); | 349 | __setup("agp=", agp_setup); |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 352 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
353 | MODULE_DESCRIPTION("AGP GART driver"); | 353 | MODULE_DESCRIPTION("AGP GART driver"); |
354 | MODULE_LICENSE("GPL and additional rights"); | 354 | MODULE_LICENSE("GPL and additional rights"); |
355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); | 355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 1108665913e2..9cf6e9bb017e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -2390,5 +2390,5 @@ static void __exit agp_intel_cleanup(void) | |||
2390 | module_init(agp_intel_init); | 2390 | module_init(agp_intel_init); |
2391 | module_exit(agp_intel_cleanup); | 2391 | module_exit(agp_intel_cleanup); |
2392 | 2392 | ||
2393 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 2393 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
2394 | MODULE_LICENSE("GPL and additional rights"); | 2394 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 5bbed3d79db9..16acee2de117 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Nvidia AGPGART routines. | 2 | * Nvidia AGPGART routines. |
3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up | 3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up |
4 | * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk> | 4 | * to work in 2.5 by Dave Jones <davej@redhat.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9f4d49e1b59a..d3bd243867fc 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -595,4 +595,4 @@ module_init(agp_via_init); | |||
595 | module_exit(agp_via_cleanup); | 595 | module_exit(agp_via_cleanup); |
596 | 596 | ||
597 | MODULE_LICENSE("GPL"); | 597 | MODULE_LICENSE("GPL"); |
598 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 598 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index f3cfb4c76125..408f5f92cb4e 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -219,7 +219,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp) | |||
219 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; | 219 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; |
220 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { | 220 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { |
221 | 221 | ||
222 | if (irq >= NR_IRQS) { | 222 | if (irq >= nr_irqs) { |
223 | irq = HPET_MAX_IRQ; | 223 | irq = HPET_MAX_IRQ; |
224 | break; | 224 | break; |
225 | } | 225 | } |
diff --git a/drivers/char/random.c b/drivers/char/random.c index c8752eaad483..705a839f1796 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -558,9 +558,26 @@ struct timer_rand_state { | |||
558 | unsigned dont_count_entropy:1; | 558 | unsigned dont_count_entropy:1; |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static struct timer_rand_state input_timer_state; | ||
562 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; | 561 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; |
563 | 562 | ||
563 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
564 | { | ||
565 | if (irq >= nr_irqs) | ||
566 | return NULL; | ||
567 | |||
568 | return irq_timer_state[irq]; | ||
569 | } | ||
570 | |||
571 | static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) | ||
572 | { | ||
573 | if (irq >= nr_irqs) | ||
574 | return; | ||
575 | |||
576 | irq_timer_state[irq] = state; | ||
577 | } | ||
578 | |||
579 | static struct timer_rand_state input_timer_state; | ||
580 | |||
564 | /* | 581 | /* |
565 | * This function adds entropy to the entropy "pool" by using timing | 582 | * This function adds entropy to the entropy "pool" by using timing |
566 | * delays. It uses the timer_rand_state structure to make an estimate | 583 | * delays. It uses the timer_rand_state structure to make an estimate |
@@ -648,11 +665,15 @@ EXPORT_SYMBOL_GPL(add_input_randomness); | |||
648 | 665 | ||
649 | void add_interrupt_randomness(int irq) | 666 | void add_interrupt_randomness(int irq) |
650 | { | 667 | { |
651 | if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) | 668 | struct timer_rand_state *state; |
669 | |||
670 | state = get_timer_rand_state(irq); | ||
671 | |||
672 | if (state == NULL) | ||
652 | return; | 673 | return; |
653 | 674 | ||
654 | DEBUG_ENT("irq event %d\n", irq); | 675 | DEBUG_ENT("irq event %d\n", irq); |
655 | add_timer_randomness(irq_timer_state[irq], 0x100 + irq); | 676 | add_timer_randomness(state, 0x100 + irq); |
656 | } | 677 | } |
657 | 678 | ||
658 | #ifdef CONFIG_BLOCK | 679 | #ifdef CONFIG_BLOCK |
@@ -912,7 +933,12 @@ void rand_initialize_irq(int irq) | |||
912 | { | 933 | { |
913 | struct timer_rand_state *state; | 934 | struct timer_rand_state *state; |
914 | 935 | ||
915 | if (irq >= NR_IRQS || irq_timer_state[irq]) | 936 | if (irq >= nr_irqs) |
937 | return; | ||
938 | |||
939 | state = get_timer_rand_state(irq); | ||
940 | |||
941 | if (state) | ||
916 | return; | 942 | return; |
917 | 943 | ||
918 | /* | 944 | /* |
@@ -921,7 +947,7 @@ void rand_initialize_irq(int irq) | |||
921 | */ | 947 | */ |
922 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | 948 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); |
923 | if (state) | 949 | if (state) |
924 | irq_timer_state[irq] = state; | 950 | set_timer_rand_state(irq, state); |
925 | } | 951 | } |
926 | 952 | ||
927 | #ifdef CONFIG_BLOCK | 953 | #ifdef CONFIG_BLOCK |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index d0c0d64ed366..ce0d9da52a8a 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -168,7 +168,7 @@ static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | |||
168 | static struct sysrq_key_op sysrq_show_timers_op = { | 168 | static struct sysrq_key_op sysrq_show_timers_op = { |
169 | .handler = sysrq_handle_show_timers, | 169 | .handler = sysrq_handle_show_timers, |
170 | .help_msg = "show-all-timers(Q)", | 170 | .help_msg = "show-all-timers(Q)", |
171 | .action_msg = "Show pending hrtimers (no others)", | 171 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 174 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index ffe9b4e3072e..54c837288d19 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev) | |||
641 | } | 641 | } |
642 | 642 | ||
643 | irq = platform_get_irq(dev, 0); | 643 | irq = platform_get_irq(dev, 0); |
644 | if (irq < 0 || irq >= NR_IRQS) | 644 | if (irq < 0 || irq >= nr_irqs) |
645 | return -EBUSY; | 645 | return -EBUSY; |
646 | 646 | ||
647 | return cascade_irq(irq, giu_get_irq); | 647 | return cascade_irq(irq, giu_get_irq); |
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 71d2ac4e3f46..c20171078d1d 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -237,9 +237,12 @@ static int __init parse_pmtmr(char *arg) | |||
237 | 237 | ||
238 | if (strict_strtoul(arg, 16, &base)) | 238 | if (strict_strtoul(arg, 16, &base)) |
239 | return -EINVAL; | 239 | return -EINVAL; |
240 | 240 | #ifdef CONFIG_X86_64 | |
241 | if (base > UINT_MAX) | ||
242 | return -ERANGE; | ||
243 | #endif | ||
241 | printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", | 244 | printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", |
242 | (unsigned int)pmtmr_ioport, base); | 245 | pmtmr_ioport, base); |
243 | pmtmr_ioport = base; | 246 | pmtmr_ioport = base; |
244 | 247 | ||
245 | return 1; | 248 | return 1; |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cd303901eb5b..904e57558bb5 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -48,13 +48,13 @@ config DW_DMAC | |||
48 | can be integrated in chips such as the Atmel AT32ap7000. | 48 | can be integrated in chips such as the Atmel AT32ap7000. |
49 | 49 | ||
50 | config FSL_DMA | 50 | config FSL_DMA |
51 | bool "Freescale MPC85xx/MPC83xx DMA support" | 51 | tristate "Freescale Elo and Elo Plus DMA support" |
52 | depends on PPC | 52 | depends on FSL_SOC |
53 | select DMA_ENGINE | 53 | select DMA_ENGINE |
54 | ---help--- | 54 | ---help--- |
55 | Enable support for the Freescale DMA engine. Now, it support | 55 | Enable support for the Freescale Elo and Elo Plus DMA controllers. |
56 | MPC8560/40, MPC8555, MPC8548 and MPC8641 processors. | 56 | The Elo is the DMA controller on some 82xx and 83xx parts, and the |
57 | The MPC8349, MPC8360 is also supported. | 57 | Elo Plus is the DMA controller on 85xx and 86xx parts. |
58 | 58 | ||
59 | config MV_XOR | 59 | config MV_XOR |
60 | bool "Marvell XOR engine support" | 60 | bool "Marvell XOR engine support" |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index a08d19704743..d1e381e35a9e 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -325,7 +325,12 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
325 | struct dmatest_thread *thread; | 325 | struct dmatest_thread *thread; |
326 | unsigned int i; | 326 | unsigned int i; |
327 | 327 | ||
328 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_ATOMIC); | 328 | /* Have we already been told about this channel? */ |
329 | list_for_each_entry(dtc, &dmatest_channels, node) | ||
330 | if (dtc->chan == chan) | ||
331 | return DMA_DUP; | ||
332 | |||
333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); | ||
329 | if (!dtc) { | 334 | if (!dtc) { |
330 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); | 335 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); |
331 | return DMA_NAK; | 336 | return DMA_NAK; |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index c0059ca58340..0b95dcce447e 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -370,7 +370,10 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan, | |||
370 | struct dma_client *client) | 370 | struct dma_client *client) |
371 | { | 371 | { |
372 | struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); | 372 | struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); |
373 | LIST_HEAD(tmp_list); | 373 | |
374 | /* Has this channel already been allocated? */ | ||
375 | if (fsl_chan->desc_pool) | ||
376 | return 1; | ||
374 | 377 | ||
375 | /* We need the descriptor to be aligned to 32bytes | 378 | /* We need the descriptor to be aligned to 32bytes |
376 | * for meeting FSL DMA specification requirement. | 379 | * for meeting FSL DMA specification requirement. |
@@ -410,6 +413,8 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan) | |||
410 | } | 413 | } |
411 | spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); | 414 | spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); |
412 | dma_pool_destroy(fsl_chan->desc_pool); | 415 | dma_pool_destroy(fsl_chan->desc_pool); |
416 | |||
417 | fsl_chan->desc_pool = NULL; | ||
413 | } | 418 | } |
414 | 419 | ||
415 | static struct dma_async_tx_descriptor * | 420 | static struct dma_async_tx_descriptor * |
@@ -786,159 +791,29 @@ static void dma_do_tasklet(unsigned long data) | |||
786 | fsl_chan_ld_cleanup(fsl_chan); | 791 | fsl_chan_ld_cleanup(fsl_chan); |
787 | } | 792 | } |
788 | 793 | ||
789 | static void fsl_dma_callback_test(void *param) | 794 | static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev, |
790 | { | 795 | struct device_node *node, u32 feature, const char *compatible) |
791 | struct fsl_dma_chan *fsl_chan = param; | ||
792 | if (fsl_chan) | ||
793 | dev_dbg(fsl_chan->dev, "selftest: callback is ok!\n"); | ||
794 | } | ||
795 | |||
796 | static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan) | ||
797 | { | ||
798 | struct dma_chan *chan; | ||
799 | int err = 0; | ||
800 | dma_addr_t dma_dest, dma_src; | ||
801 | dma_cookie_t cookie; | ||
802 | u8 *src, *dest; | ||
803 | int i; | ||
804 | size_t test_size; | ||
805 | struct dma_async_tx_descriptor *tx1, *tx2, *tx3; | ||
806 | |||
807 | test_size = 4096; | ||
808 | |||
809 | src = kmalloc(test_size * 2, GFP_KERNEL); | ||
810 | if (!src) { | ||
811 | dev_err(fsl_chan->dev, | ||
812 | "selftest: Cannot alloc memory for test!\n"); | ||
813 | return -ENOMEM; | ||
814 | } | ||
815 | |||
816 | dest = src + test_size; | ||
817 | |||
818 | for (i = 0; i < test_size; i++) | ||
819 | src[i] = (u8) i; | ||
820 | |||
821 | chan = &fsl_chan->common; | ||
822 | |||
823 | if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) { | ||
824 | dev_err(fsl_chan->dev, | ||
825 | "selftest: Cannot alloc resources for DMA\n"); | ||
826 | err = -ENODEV; | ||
827 | goto out; | ||
828 | } | ||
829 | |||
830 | /* TX 1 */ | ||
831 | dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2, | ||
832 | DMA_TO_DEVICE); | ||
833 | dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2, | ||
834 | DMA_FROM_DEVICE); | ||
835 | tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0); | ||
836 | async_tx_ack(tx1); | ||
837 | |||
838 | cookie = fsl_dma_tx_submit(tx1); | ||
839 | fsl_dma_memcpy_issue_pending(chan); | ||
840 | msleep(2); | ||
841 | |||
842 | if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { | ||
843 | dev_err(fsl_chan->dev, "selftest: Time out!\n"); | ||
844 | err = -ENODEV; | ||
845 | goto free_resources; | ||
846 | } | ||
847 | |||
848 | /* Test free and re-alloc channel resources */ | ||
849 | fsl_dma_free_chan_resources(chan); | ||
850 | |||
851 | if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) { | ||
852 | dev_err(fsl_chan->dev, | ||
853 | "selftest: Cannot alloc resources for DMA\n"); | ||
854 | err = -ENODEV; | ||
855 | goto free_resources; | ||
856 | } | ||
857 | |||
858 | /* Continue to test | ||
859 | * TX 2 | ||
860 | */ | ||
861 | dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2, | ||
862 | test_size / 4, DMA_TO_DEVICE); | ||
863 | dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2, | ||
864 | test_size / 4, DMA_FROM_DEVICE); | ||
865 | tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); | ||
866 | async_tx_ack(tx2); | ||
867 | |||
868 | /* TX 3 */ | ||
869 | dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4, | ||
870 | test_size / 4, DMA_TO_DEVICE); | ||
871 | dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4, | ||
872 | test_size / 4, DMA_FROM_DEVICE); | ||
873 | tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); | ||
874 | async_tx_ack(tx3); | ||
875 | |||
876 | /* Interrupt tx test */ | ||
877 | tx1 = fsl_dma_prep_interrupt(chan, 0); | ||
878 | async_tx_ack(tx1); | ||
879 | cookie = fsl_dma_tx_submit(tx1); | ||
880 | |||
881 | /* Test exchanging the prepared tx sort */ | ||
882 | cookie = fsl_dma_tx_submit(tx3); | ||
883 | cookie = fsl_dma_tx_submit(tx2); | ||
884 | |||
885 | if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *) | ||
886 | dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) { | ||
887 | tx3->callback = fsl_dma_callback_test; | ||
888 | tx3->callback_param = fsl_chan; | ||
889 | } | ||
890 | fsl_dma_memcpy_issue_pending(chan); | ||
891 | msleep(2); | ||
892 | |||
893 | if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { | ||
894 | dev_err(fsl_chan->dev, "selftest: Time out!\n"); | ||
895 | err = -ENODEV; | ||
896 | goto free_resources; | ||
897 | } | ||
898 | |||
899 | err = memcmp(src, dest, test_size); | ||
900 | if (err) { | ||
901 | for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size); | ||
902 | i++); | ||
903 | dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is " | ||
904 | "error! src 0x%x, dest 0x%x\n", | ||
905 | i, (long)test_size, *(src + i), *(dest + i)); | ||
906 | } | ||
907 | |||
908 | free_resources: | ||
909 | fsl_dma_free_chan_resources(chan); | ||
910 | out: | ||
911 | kfree(src); | ||
912 | return err; | ||
913 | } | ||
914 | |||
915 | static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | ||
916 | const struct of_device_id *match) | ||
917 | { | 796 | { |
918 | struct fsl_dma_device *fdev; | ||
919 | struct fsl_dma_chan *new_fsl_chan; | 797 | struct fsl_dma_chan *new_fsl_chan; |
920 | int err; | 798 | int err; |
921 | 799 | ||
922 | fdev = dev_get_drvdata(dev->dev.parent); | ||
923 | BUG_ON(!fdev); | ||
924 | |||
925 | /* alloc channel */ | 800 | /* alloc channel */ |
926 | new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL); | 801 | new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL); |
927 | if (!new_fsl_chan) { | 802 | if (!new_fsl_chan) { |
928 | dev_err(&dev->dev, "No free memory for allocating " | 803 | dev_err(fdev->dev, "No free memory for allocating " |
929 | "dma channels!\n"); | 804 | "dma channels!\n"); |
930 | return -ENOMEM; | 805 | return -ENOMEM; |
931 | } | 806 | } |
932 | 807 | ||
933 | /* get dma channel register base */ | 808 | /* get dma channel register base */ |
934 | err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg); | 809 | err = of_address_to_resource(node, 0, &new_fsl_chan->reg); |
935 | if (err) { | 810 | if (err) { |
936 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | 811 | dev_err(fdev->dev, "Can't get %s property 'reg'\n", |
937 | dev->node->full_name); | 812 | node->full_name); |
938 | goto err_no_reg; | 813 | goto err_no_reg; |
939 | } | 814 | } |
940 | 815 | ||
941 | new_fsl_chan->feature = *(u32 *)match->data; | 816 | new_fsl_chan->feature = feature; |
942 | 817 | ||
943 | if (!fdev->feature) | 818 | if (!fdev->feature) |
944 | fdev->feature = new_fsl_chan->feature; | 819 | fdev->feature = new_fsl_chan->feature; |
@@ -948,13 +823,13 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | |||
948 | */ | 823 | */ |
949 | WARN_ON(fdev->feature != new_fsl_chan->feature); | 824 | WARN_ON(fdev->feature != new_fsl_chan->feature); |
950 | 825 | ||
951 | new_fsl_chan->dev = &dev->dev; | 826 | new_fsl_chan->dev = &new_fsl_chan->common.dev; |
952 | new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, | 827 | new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, |
953 | new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); | 828 | new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); |
954 | 829 | ||
955 | new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; | 830 | new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; |
956 | if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { | 831 | if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { |
957 | dev_err(&dev->dev, "There is no %d channel!\n", | 832 | dev_err(fdev->dev, "There is no %d channel!\n", |
958 | new_fsl_chan->id); | 833 | new_fsl_chan->id); |
959 | err = -EINVAL; | 834 | err = -EINVAL; |
960 | goto err_no_chan; | 835 | goto err_no_chan; |
@@ -988,29 +863,23 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | |||
988 | &fdev->common.channels); | 863 | &fdev->common.channels); |
989 | fdev->common.chancnt++; | 864 | fdev->common.chancnt++; |
990 | 865 | ||
991 | new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0); | 866 | new_fsl_chan->irq = irq_of_parse_and_map(node, 0); |
992 | if (new_fsl_chan->irq != NO_IRQ) { | 867 | if (new_fsl_chan->irq != NO_IRQ) { |
993 | err = request_irq(new_fsl_chan->irq, | 868 | err = request_irq(new_fsl_chan->irq, |
994 | &fsl_dma_chan_do_interrupt, IRQF_SHARED, | 869 | &fsl_dma_chan_do_interrupt, IRQF_SHARED, |
995 | "fsldma-channel", new_fsl_chan); | 870 | "fsldma-channel", new_fsl_chan); |
996 | if (err) { | 871 | if (err) { |
997 | dev_err(&dev->dev, "DMA channel %s request_irq error " | 872 | dev_err(fdev->dev, "DMA channel %s request_irq error " |
998 | "with return %d\n", dev->node->full_name, err); | 873 | "with return %d\n", node->full_name, err); |
999 | goto err_no_irq; | 874 | goto err_no_irq; |
1000 | } | 875 | } |
1001 | } | 876 | } |
1002 | 877 | ||
1003 | err = fsl_dma_self_test(new_fsl_chan); | 878 | dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, |
1004 | if (err) | 879 | compatible, new_fsl_chan->irq); |
1005 | goto err_self_test; | ||
1006 | |||
1007 | dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, | ||
1008 | match->compatible, new_fsl_chan->irq); | ||
1009 | 880 | ||
1010 | return 0; | 881 | return 0; |
1011 | 882 | ||
1012 | err_self_test: | ||
1013 | free_irq(new_fsl_chan->irq, new_fsl_chan); | ||
1014 | err_no_irq: | 883 | err_no_irq: |
1015 | list_del(&new_fsl_chan->common.device_node); | 884 | list_del(&new_fsl_chan->common.device_node); |
1016 | err_no_chan: | 885 | err_no_chan: |
@@ -1020,38 +889,20 @@ err_no_reg: | |||
1020 | return err; | 889 | return err; |
1021 | } | 890 | } |
1022 | 891 | ||
1023 | const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN; | 892 | static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan) |
1024 | const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN; | ||
1025 | |||
1026 | static struct of_device_id of_fsl_dma_chan_ids[] = { | ||
1027 | { | ||
1028 | .compatible = "fsl,eloplus-dma-channel", | ||
1029 | .data = (void *)&mpc8540_dma_ip_feature, | ||
1030 | }, | ||
1031 | { | ||
1032 | .compatible = "fsl,elo-dma-channel", | ||
1033 | .data = (void *)&mpc8349_dma_ip_feature, | ||
1034 | }, | ||
1035 | {} | ||
1036 | }; | ||
1037 | |||
1038 | static struct of_platform_driver of_fsl_dma_chan_driver = { | ||
1039 | .name = "of-fsl-dma-channel", | ||
1040 | .match_table = of_fsl_dma_chan_ids, | ||
1041 | .probe = of_fsl_dma_chan_probe, | ||
1042 | }; | ||
1043 | |||
1044 | static __init int of_fsl_dma_chan_init(void) | ||
1045 | { | 893 | { |
1046 | return of_register_platform_driver(&of_fsl_dma_chan_driver); | 894 | free_irq(fchan->irq, fchan); |
895 | list_del(&fchan->common.device_node); | ||
896 | iounmap(fchan->reg_base); | ||
897 | kfree(fchan); | ||
1047 | } | 898 | } |
1048 | 899 | ||
1049 | static int __devinit of_fsl_dma_probe(struct of_device *dev, | 900 | static int __devinit of_fsl_dma_probe(struct of_device *dev, |
1050 | const struct of_device_id *match) | 901 | const struct of_device_id *match) |
1051 | { | 902 | { |
1052 | int err; | 903 | int err; |
1053 | unsigned int irq; | ||
1054 | struct fsl_dma_device *fdev; | 904 | struct fsl_dma_device *fdev; |
905 | struct device_node *child; | ||
1055 | 906 | ||
1056 | fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL); | 907 | fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL); |
1057 | if (!fdev) { | 908 | if (!fdev) { |
@@ -1085,9 +936,9 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, | |||
1085 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; | 936 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; |
1086 | fdev->common.dev = &dev->dev; | 937 | fdev->common.dev = &dev->dev; |
1087 | 938 | ||
1088 | irq = irq_of_parse_and_map(dev->node, 0); | 939 | fdev->irq = irq_of_parse_and_map(dev->node, 0); |
1089 | if (irq != NO_IRQ) { | 940 | if (fdev->irq != NO_IRQ) { |
1090 | err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED, | 941 | err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED, |
1091 | "fsldma-device", fdev); | 942 | "fsldma-device", fdev); |
1092 | if (err) { | 943 | if (err) { |
1093 | dev_err(&dev->dev, "DMA device request_irq error " | 944 | dev_err(&dev->dev, "DMA device request_irq error " |
@@ -1097,7 +948,21 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, | |||
1097 | } | 948 | } |
1098 | 949 | ||
1099 | dev_set_drvdata(&(dev->dev), fdev); | 950 | dev_set_drvdata(&(dev->dev), fdev); |
1100 | of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev); | 951 | |
952 | /* We cannot use of_platform_bus_probe() because there is no | ||
953 | * of_platform_bus_remove. Instead, we manually instantiate every DMA | ||
954 | * channel object. | ||
955 | */ | ||
956 | for_each_child_of_node(dev->node, child) { | ||
957 | if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) | ||
958 | fsl_dma_chan_probe(fdev, child, | ||
959 | FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, | ||
960 | "fsl,eloplus-dma-channel"); | ||
961 | if (of_device_is_compatible(child, "fsl,elo-dma-channel")) | ||
962 | fsl_dma_chan_probe(fdev, child, | ||
963 | FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN, | ||
964 | "fsl,elo-dma-channel"); | ||
965 | } | ||
1101 | 966 | ||
1102 | dma_async_device_register(&fdev->common); | 967 | dma_async_device_register(&fdev->common); |
1103 | return 0; | 968 | return 0; |
@@ -1109,6 +974,30 @@ err_no_reg: | |||
1109 | return err; | 974 | return err; |
1110 | } | 975 | } |
1111 | 976 | ||
977 | static int of_fsl_dma_remove(struct of_device *of_dev) | ||
978 | { | ||
979 | struct fsl_dma_device *fdev; | ||
980 | unsigned int i; | ||
981 | |||
982 | fdev = dev_get_drvdata(&of_dev->dev); | ||
983 | |||
984 | dma_async_device_unregister(&fdev->common); | ||
985 | |||
986 | for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) | ||
987 | if (fdev->chan[i]) | ||
988 | fsl_dma_chan_remove(fdev->chan[i]); | ||
989 | |||
990 | if (fdev->irq != NO_IRQ) | ||
991 | free_irq(fdev->irq, fdev); | ||
992 | |||
993 | iounmap(fdev->reg_base); | ||
994 | |||
995 | kfree(fdev); | ||
996 | dev_set_drvdata(&of_dev->dev, NULL); | ||
997 | |||
998 | return 0; | ||
999 | } | ||
1000 | |||
1112 | static struct of_device_id of_fsl_dma_ids[] = { | 1001 | static struct of_device_id of_fsl_dma_ids[] = { |
1113 | { .compatible = "fsl,eloplus-dma", }, | 1002 | { .compatible = "fsl,eloplus-dma", }, |
1114 | { .compatible = "fsl,elo-dma", }, | 1003 | { .compatible = "fsl,elo-dma", }, |
@@ -1116,15 +1005,32 @@ static struct of_device_id of_fsl_dma_ids[] = { | |||
1116 | }; | 1005 | }; |
1117 | 1006 | ||
1118 | static struct of_platform_driver of_fsl_dma_driver = { | 1007 | static struct of_platform_driver of_fsl_dma_driver = { |
1119 | .name = "of-fsl-dma", | 1008 | .name = "fsl-elo-dma", |
1120 | .match_table = of_fsl_dma_ids, | 1009 | .match_table = of_fsl_dma_ids, |
1121 | .probe = of_fsl_dma_probe, | 1010 | .probe = of_fsl_dma_probe, |
1011 | .remove = of_fsl_dma_remove, | ||
1122 | }; | 1012 | }; |
1123 | 1013 | ||
1124 | static __init int of_fsl_dma_init(void) | 1014 | static __init int of_fsl_dma_init(void) |
1125 | { | 1015 | { |
1126 | return of_register_platform_driver(&of_fsl_dma_driver); | 1016 | int ret; |
1017 | |||
1018 | pr_info("Freescale Elo / Elo Plus DMA driver\n"); | ||
1019 | |||
1020 | ret = of_register_platform_driver(&of_fsl_dma_driver); | ||
1021 | if (ret) | ||
1022 | pr_err("fsldma: failed to register platform driver\n"); | ||
1023 | |||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | static void __exit of_fsl_dma_exit(void) | ||
1028 | { | ||
1029 | of_unregister_platform_driver(&of_fsl_dma_driver); | ||
1127 | } | 1030 | } |
1128 | 1031 | ||
1129 | subsys_initcall(of_fsl_dma_chan_init); | ||
1130 | subsys_initcall(of_fsl_dma_init); | 1032 | subsys_initcall(of_fsl_dma_init); |
1033 | module_exit(of_fsl_dma_exit); | ||
1034 | |||
1035 | MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver"); | ||
1036 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index 6faf07ba0d0e..4f21a512d848 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
@@ -114,6 +114,7 @@ struct fsl_dma_device { | |||
114 | struct dma_device common; | 114 | struct dma_device common; |
115 | struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; | 115 | struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; |
116 | u32 feature; /* The same as DMA channels */ | 116 | u32 feature; /* The same as DMA channels */ |
117 | int irq; /* Channel IRQ */ | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /* Define macros for fsl_dma_chan->feature property */ | 120 | /* Define macros for fsl_dma_chan->feature property */ |
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index bc8c6e3470ca..1ef68b315657 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
@@ -971,11 +971,9 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor( | |||
971 | switch (ioat_chan->device->version) { | 971 | switch (ioat_chan->device->version) { |
972 | case IOAT_VER_1_2: | 972 | case IOAT_VER_1_2: |
973 | return ioat1_dma_get_next_descriptor(ioat_chan); | 973 | return ioat1_dma_get_next_descriptor(ioat_chan); |
974 | break; | ||
975 | case IOAT_VER_2_0: | 974 | case IOAT_VER_2_0: |
976 | case IOAT_VER_3_0: | 975 | case IOAT_VER_3_0: |
977 | return ioat2_dma_get_next_descriptor(ioat_chan); | 976 | return ioat2_dma_get_next_descriptor(ioat_chan); |
978 | break; | ||
979 | } | 977 | } |
980 | return NULL; | 978 | return NULL; |
981 | } | 979 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 22edc4273ef6..faa1cc66e9cf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1143,7 +1143,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1143 | 1143 | ||
1144 | if (!is_out) { | 1144 | if (!is_out) { |
1145 | int irq = gpio_to_irq(gpio); | 1145 | int irq = gpio_to_irq(gpio); |
1146 | struct irq_desc *desc = irq_desc + irq; | 1146 | struct irq_desc *desc = irq_to_desc(irq); |
1147 | 1147 | ||
1148 | /* This races with request_irq(), set_irq_type(), | 1148 | /* This races with request_irq(), set_irq_type(), |
1149 | * and set_irq_wake() ... but those are "rare". | 1149 | * and set_irq_wake() ... but those are "rare". |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 74a369a6116f..a820ca6fc327 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA | |||
84 | 84 | ||
85 | If unsure, say N. | 85 | If unsure, say N. |
86 | 86 | ||
87 | config BLK_DEV_IDEDISK | 87 | config IDE_GD |
88 | tristate "Include IDE/ATA-2 DISK support" | 88 | tristate "generic ATA/ATAPI disk support" |
89 | ---help--- | 89 | default y |
90 | This will include enhanced support for MFM/RLL/IDE hard disks. If | 90 | help |
91 | you have a MFM/RLL/IDE disk, and there is no special reason to use | 91 | Support for ATA/ATAPI disks (including ATAPI floppy drives). |
92 | the old hard disk driver instead, say Y. If you have an SCSI-only | ||
93 | system, you can say N here. | ||
94 | 92 | ||
95 | To compile this driver as a module, choose M here: the | 93 | To compile this driver as a module, choose M here. |
96 | module will be called ide-disk. | 94 | The module will be called ide-gd_mod. |
97 | Do not compile this driver as a module if your root file system | 95 | |
98 | (the one containing the directory /) is located on the IDE disk. | 96 | If unsure, say Y. |
97 | |||
98 | config IDE_GD_ATA | ||
99 | bool "ATA disk support" | ||
100 | depends on IDE_GD | ||
101 | default y | ||
102 | help | ||
103 | This will include support for ATA hard disks. | ||
99 | 104 | ||
100 | If unsure, say Y. | 105 | If unsure, say Y. |
101 | 106 | ||
107 | config IDE_GD_ATAPI | ||
108 | bool "ATAPI floppy support" | ||
109 | depends on IDE_GD | ||
110 | select IDE_ATAPI | ||
111 | help | ||
112 | This will include support for ATAPI floppy drives | ||
113 | (i.e. Iomega ZIP or MKE LS-120). | ||
114 | |||
115 | For information about jumper settings and the question | ||
116 | of when a ZIP drive uses a partition table, see | ||
117 | <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | ||
118 | |||
119 | If unsure, say N. | ||
120 | |||
102 | config BLK_DEV_IDECS | 121 | config BLK_DEV_IDECS |
103 | tristate "PCMCIA IDE support" | 122 | tristate "PCMCIA IDE support" |
104 | depends on PCMCIA | 123 | depends on PCMCIA |
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE | |||
163 | To compile this driver as a module, choose M here: the | 182 | To compile this driver as a module, choose M here: the |
164 | module will be called ide-tape. | 183 | module will be called ide-tape. |
165 | 184 | ||
166 | config BLK_DEV_IDEFLOPPY | ||
167 | tristate "Include IDE/ATAPI FLOPPY support" | ||
168 | select IDE_ATAPI | ||
169 | ---help--- | ||
170 | If you have an IDE floppy drive which uses the ATAPI protocol, | ||
171 | answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy | ||
172 | drives, similar to the SCSI protocol. | ||
173 | |||
174 | The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by | ||
175 | this driver. For information about jumper settings and the question | ||
176 | of when a ZIP drive uses a partition table, see | ||
177 | <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | ||
178 | (ATAPI PD-CD/CDR drives are not supported by this driver; support | ||
179 | for PD-CD/CDR drives is available if you answer Y to | ||
180 | "SCSI emulation support", below). | ||
181 | |||
182 | If you say Y here, the FLOPPY drive will be identified along with | ||
183 | other IDE devices, as "hdb" or "hdc", or something similar (check | ||
184 | the boot messages with dmesg). | ||
185 | |||
186 | To compile this driver as a module, choose M here: the | ||
187 | module will be called ide-floppy. | ||
188 | |||
189 | config BLK_DEV_IDESCSI | 185 | config BLK_DEV_IDESCSI |
190 | tristate "SCSI emulation support (DEPRECATED)" | 186 | tristate "SCSI emulation support (DEPRECATED)" |
191 | depends on SCSI | 187 | depends on SCSI |
@@ -332,7 +328,7 @@ config IDEPCI_PCIBUS_ORDER | |||
332 | # TODO: split it on per host driver config options (or module parameters) | 328 | # TODO: split it on per host driver config options (or module parameters) |
333 | config BLK_DEV_OFFBOARD | 329 | config BLK_DEV_OFFBOARD |
334 | bool "Boot off-board chipsets first support (DEPRECATED)" | 330 | bool "Boot off-board chipsets first support (DEPRECATED)" |
335 | depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) | 331 | depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) |
336 | help | 332 | help |
337 | Normally, IDE controllers built into the motherboard (on-board | 333 | Normally, IDE controllers built into the motherboard (on-board |
338 | controllers) are assigned to ide0 and ide1 while those on add-in PCI | 334 | controllers) are assigned to ide0 and ide1 while those on add-in PCI |
@@ -482,28 +478,6 @@ config BLK_DEV_CS5535 | |||
482 | 478 | ||
483 | It is safe to say Y to this question. | 479 | It is safe to say Y to this question. |
484 | 480 | ||
485 | config BLK_DEV_HPT34X | ||
486 | tristate "HPT34X chipset support" | ||
487 | depends on BROKEN | ||
488 | select BLK_DEV_IDEDMA_PCI | ||
489 | help | ||
490 | This driver adds up to 4 more EIDE devices sharing a single | ||
491 | interrupt. The HPT343 chipset in its current form is a non-bootable | ||
492 | controller; the HPT345/HPT363 chipset is a bootable (needs BIOS FIX) | ||
493 | PCI UDMA controllers. This driver requires dynamic tuning of the | ||
494 | chipset during the ide-probe at boot time. It is reported to support | ||
495 | DVD II drives, by the manufacturer. | ||
496 | |||
497 | config HPT34X_AUTODMA | ||
498 | bool "HPT34X AUTODMA support (EXPERIMENTAL)" | ||
499 | depends on BLK_DEV_HPT34X && EXPERIMENTAL | ||
500 | help | ||
501 | This is a dangerous thing to attempt currently! Please read the | ||
502 | comments at the top of <file:drivers/ide/pci/hpt34x.c>. If you say Y | ||
503 | here, then say Y to "Use DMA by default when available" as well. | ||
504 | |||
505 | If unsure, say N. | ||
506 | |||
507 | config BLK_DEV_HPT366 | 481 | config BLK_DEV_HPT366 |
508 | tristate "HPT36X/37X chipset support" | 482 | tristate "HPT36X/37X chipset support" |
509 | select BLK_DEV_IDEDMA_PCI | 483 | select BLK_DEV_IDEDMA_PCI |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index ceaf779054ea..093d3248ca89 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -37,18 +37,25 @@ obj-$(CONFIG_IDE_H8300) += h8300/ | |||
37 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o | 37 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o |
38 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o | 38 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o |
39 | 39 | ||
40 | ide-disk_mod-y += ide-disk.o ide-disk_ioctl.o | 40 | ide-gd_mod-y += ide-gd.o |
41 | ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o | 41 | ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o |
42 | ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o | ||
43 | 42 | ||
43 | ifeq ($(CONFIG_IDE_GD_ATA), y) | ||
44 | ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o | ||
44 | ifeq ($(CONFIG_IDE_PROC_FS), y) | 45 | ifeq ($(CONFIG_IDE_PROC_FS), y) |
45 | ide-disk_mod-y += ide-disk_proc.o | 46 | ide-gd_mod-y += ide-disk_proc.o |
46 | ide-floppy_mod-y += ide-floppy_proc.o | 47 | endif |
48 | endif | ||
49 | |||
50 | ifeq ($(CONFIG_IDE_GD_ATAPI), y) | ||
51 | ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o | ||
52 | ifeq ($(CONFIG_IDE_PROC_FS), y) | ||
53 | ide-gd_mod-y += ide-floppy_proc.o | ||
54 | endif | ||
47 | endif | 55 | endif |
48 | 56 | ||
49 | obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o | 57 | obj-$(CONFIG_IDE_GD) += ide-gd_mod.o |
50 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o | 58 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o |
51 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o | ||
52 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o | 59 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o |
53 | 60 | ||
54 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) | 61 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2e305714c209..4e58b9e7a58a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -191,7 +191,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) | |||
191 | { | 191 | { |
192 | struct ide_atapi_pc pc; | 192 | struct ide_atapi_pc pc; |
193 | 193 | ||
194 | if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) | 194 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) |
195 | return 0; | 195 | return 0; |
196 | 196 | ||
197 | ide_init_pc(&pc); | 197 | ide_init_pc(&pc); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3308b1cd3a33..13265a8827da 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -99,7 +99,7 @@ static void ide_cd_put(struct cdrom_info *cd) | |||
99 | /* Mark that we've seen a media change and invalidate our internal buffers. */ | 99 | /* Mark that we've seen a media change and invalidate our internal buffers. */ |
100 | static void cdrom_saw_media_change(ide_drive_t *drive) | 100 | static void cdrom_saw_media_change(ide_drive_t *drive) |
101 | { | 101 | { |
102 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | 102 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
103 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; | 103 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; |
104 | } | 104 | } |
105 | 105 | ||
@@ -340,8 +340,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " | 342 | ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " |
343 | "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat, | 343 | "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", |
344 | good_stat, rq->cmd_type, err); | 344 | __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); |
345 | 345 | ||
346 | if (blk_sense_request(rq)) { | 346 | if (blk_sense_request(rq)) { |
347 | /* | 347 | /* |
@@ -843,13 +843,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) | |||
843 | rq->q->prep_rq_fn(rq->q, rq); | 843 | rq->q->prep_rq_fn(rq->q, rq); |
844 | } | 844 | } |
845 | 845 | ||
846 | /* | ||
847 | * All other packet commands. | ||
848 | */ | ||
849 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) | 846 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) |
850 | { | 847 | { |
851 | 848 | ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n", | |
852 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | 849 | __func__, rq->cmd[0]); |
853 | 850 | ||
854 | /* | 851 | /* |
855 | * Some of the trailing request sense fields are optional, | 852 | * Some of the trailing request sense fields are optional, |
@@ -876,7 +873,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
876 | if (!sense) | 873 | if (!sense) |
877 | sense = &local_sense; | 874 | sense = &local_sense; |
878 | 875 | ||
879 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " | 876 | ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, " |
880 | "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, | 877 | "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, |
881 | timeout, cmd_flags); | 878 | timeout, cmd_flags); |
882 | 879 | ||
@@ -1177,8 +1174,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
1177 | unsigned short sectors_per_frame = | 1174 | unsigned short sectors_per_frame = |
1178 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | 1175 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; |
1179 | 1176 | ||
1180 | ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n", | 1177 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " |
1181 | __func__, write, sectors_per_frame); | 1178 | "secs_per_frame: %u\n", |
1179 | __func__, rq->cmd[0], write, sectors_per_frame); | ||
1182 | 1180 | ||
1183 | if (write) { | 1181 | if (write) { |
1184 | /* disk has become write protected */ | 1182 | /* disk has become write protected */ |
@@ -1221,7 +1219,8 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) | |||
1221 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | 1219 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) |
1222 | { | 1220 | { |
1223 | 1221 | ||
1224 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__, | 1222 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " |
1223 | "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], | ||
1225 | rq->cmd_type); | 1224 | rq->cmd_type); |
1226 | 1225 | ||
1227 | if (blk_pc_request(rq)) | 1226 | if (blk_pc_request(rq)) |
@@ -1257,9 +1256,6 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
1257 | } | 1256 | } |
1258 | } | 1257 | } |
1259 | 1258 | ||
1260 | /* | ||
1261 | * cdrom driver request routine. | ||
1262 | */ | ||
1263 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | 1259 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, |
1264 | sector_t block) | 1260 | sector_t block) |
1265 | { | 1261 | { |
@@ -1267,8 +1263,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1267 | ide_handler_t *fn; | 1263 | ide_handler_t *fn; |
1268 | int xferlen; | 1264 | int xferlen; |
1269 | 1265 | ||
1270 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n", | 1266 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " |
1271 | __func__, rq->cmd_type, (unsigned long long)block); | 1267 | "rq->cmd_type: 0x%x, block: %llu\n", |
1268 | __func__, rq->cmd[0], rq->cmd_type, | ||
1269 | (unsigned long long)block); | ||
1272 | 1270 | ||
1273 | if (blk_fs_request(rq)) { | 1271 | if (blk_fs_request(rq)) { |
1274 | if (drive->atapi_flags & IDE_AFLAG_SEEKING) { | 1272 | if (drive->atapi_flags & IDE_AFLAG_SEEKING) { |
@@ -1412,6 +1410,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
1412 | 1410 | ||
1413 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 1411 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
1414 | *sectors_per_frame = blocklen >> SECTOR_BITS; | 1412 | *sectors_per_frame = blocklen >> SECTOR_BITS; |
1413 | |||
1414 | ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", | ||
1415 | __func__, *capacity, *sectors_per_frame); | ||
1416 | |||
1415 | return 0; | 1417 | return 0; |
1416 | } | 1418 | } |
1417 | 1419 | ||
@@ -1643,6 +1645,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) | |||
1643 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); | 1645 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); |
1644 | } | 1646 | } |
1645 | 1647 | ||
1648 | ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", | ||
1649 | __func__, curspeed, maxspeed); | ||
1650 | |||
1646 | cd->current_speed = (curspeed + (176/2)) / 176; | 1651 | cd->current_speed = (curspeed + (176/2)) / 176; |
1647 | cd->max_speed = (maxspeed + (176/2)) / 176; | 1652 | cd->max_speed = (maxspeed + (176/2)) / 176; |
1648 | } | 1653 | } |
@@ -1732,7 +1737,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | |||
1732 | return 0; | 1737 | return 0; |
1733 | 1738 | ||
1734 | if ((buf[8 + 6] & 0x01) == 0) | 1739 | if ((buf[8 + 6] & 0x01) == 0) |
1735 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 1740 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
1736 | if (buf[8 + 6] & 0x08) | 1741 | if (buf[8 + 6] & 0x08) |
1737 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; | 1742 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; |
1738 | if (buf[8 + 3] & 0x01) | 1743 | if (buf[8 + 3] & 0x01) |
@@ -1777,7 +1782,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | |||
1777 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) | 1782 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) |
1778 | printk(KERN_CONT " DVD%s%s", | 1783 | printk(KERN_CONT " DVD%s%s", |
1779 | (cdi->mask & CDC_DVD_R) ? "" : "-R", | 1784 | (cdi->mask & CDC_DVD_R) ? "" : "-R", |
1780 | (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM"); | 1785 | (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM"); |
1781 | 1786 | ||
1782 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) | 1787 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) |
1783 | printk(KERN_CONT " CD%s%s", | 1788 | printk(KERN_CONT " CD%s%s", |
@@ -1908,6 +1913,16 @@ static const struct ide_proc_devset idecd_settings[] = { | |||
1908 | IDE_PROC_DEVSET(dsc_overlap, 0, 1), | 1913 | IDE_PROC_DEVSET(dsc_overlap, 0, 1), |
1909 | { 0 }, | 1914 | { 0 }, |
1910 | }; | 1915 | }; |
1916 | |||
1917 | static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) | ||
1918 | { | ||
1919 | return idecd_proc; | ||
1920 | } | ||
1921 | |||
1922 | static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) | ||
1923 | { | ||
1924 | return idecd_settings; | ||
1925 | } | ||
1911 | #endif | 1926 | #endif |
1912 | 1927 | ||
1913 | static const struct cd_list_entry ide_cd_quirks_list[] = { | 1928 | static const struct cd_list_entry ide_cd_quirks_list[] = { |
@@ -1986,8 +2001,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) | |||
1986 | if (!drive->queue->unplug_delay) | 2001 | if (!drive->queue->unplug_delay) |
1987 | drive->queue->unplug_delay = 1; | 2002 | drive->queue->unplug_delay = 1; |
1988 | 2003 | ||
1989 | drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | | 2004 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
1990 | ide_cd_flags(id); | 2005 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); |
1991 | 2006 | ||
1992 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && | 2007 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && |
1993 | fw_rev[4] == '1' && fw_rev[6] <= '2') | 2008 | fw_rev[4] == '1' && fw_rev[6] <= '2') |
@@ -2069,8 +2084,8 @@ static ide_driver_t ide_cdrom_driver = { | |||
2069 | .end_request = ide_end_request, | 2084 | .end_request = ide_end_request, |
2070 | .error = __ide_error, | 2085 | .error = __ide_error, |
2071 | #ifdef CONFIG_IDE_PROC_FS | 2086 | #ifdef CONFIG_IDE_PROC_FS |
2072 | .proc = idecd_proc, | 2087 | .proc_entries = ide_cd_proc_entries, |
2073 | .settings = idecd_settings, | 2088 | .proc_devsets = ide_cd_proc_devsets, |
2074 | #endif | 2089 | #endif |
2075 | }; | 2090 | }; |
2076 | 2091 | ||
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 74231b41f611..df3df0041eb6 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c | |||
@@ -86,8 +86,8 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, | |||
86 | 86 | ||
87 | if (slot_nr == CDSL_CURRENT) { | 87 | if (slot_nr == CDSL_CURRENT) { |
88 | (void) cdrom_check_status(drive, NULL); | 88 | (void) cdrom_check_status(drive, NULL); |
89 | retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0; | 89 | retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; |
90 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | 90 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
91 | return retval; | 91 | return retval; |
92 | } else { | 92 | } else { |
93 | return -EINVAL; | 93 | return -EINVAL; |
@@ -136,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | |||
136 | sense = &my_sense; | 136 | sense = &my_sense; |
137 | 137 | ||
138 | /* If the drive cannot lock the door, just pretend. */ | 138 | /* If the drive cannot lock the door, just pretend. */ |
139 | if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) { | 139 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) { |
140 | stat = 0; | 140 | stat = 0; |
141 | } else { | 141 | } else { |
142 | unsigned char cmd[BLK_MAX_CDB]; | 142 | unsigned char cmd[BLK_MAX_CDB]; |
@@ -157,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | |||
157 | (sense->asc == 0x24 || sense->asc == 0x20)) { | 157 | (sense->asc == 0x24 || sense->asc == 0x20)) { |
158 | printk(KERN_ERR "%s: door locking not supported\n", | 158 | printk(KERN_ERR "%s: door locking not supported\n", |
159 | drive->name); | 159 | drive->name); |
160 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 160 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
161 | stat = 0; | 161 | stat = 0; |
162 | } | 162 | } |
163 | 163 | ||
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 3853bde8eedc..223750c1b5a6 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -14,9 +14,6 @@ | |||
14 | * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. | 14 | * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define IDEDISK_VERSION "1.18" | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/types.h> | 17 | #include <linux/types.h> |
21 | #include <linux/string.h> | 18 | #include <linux/string.h> |
22 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -39,46 +36,8 @@ | |||
39 | #include <asm/io.h> | 36 | #include <asm/io.h> |
40 | #include <asm/div64.h> | 37 | #include <asm/div64.h> |
41 | 38 | ||
42 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
43 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | ||
44 | #else | ||
45 | #define IDE_DISK_MINORS 0 | ||
46 | #endif | ||
47 | |||
48 | #include "ide-disk.h" | 39 | #include "ide-disk.h" |
49 | 40 | ||
50 | static DEFINE_MUTEX(idedisk_ref_mutex); | ||
51 | |||
52 | #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) | ||
53 | |||
54 | static void ide_disk_release(struct kref *); | ||
55 | |||
56 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | ||
57 | { | ||
58 | struct ide_disk_obj *idkp = NULL; | ||
59 | |||
60 | mutex_lock(&idedisk_ref_mutex); | ||
61 | idkp = ide_disk_g(disk); | ||
62 | if (idkp) { | ||
63 | if (ide_device_get(idkp->drive)) | ||
64 | idkp = NULL; | ||
65 | else | ||
66 | kref_get(&idkp->kref); | ||
67 | } | ||
68 | mutex_unlock(&idedisk_ref_mutex); | ||
69 | return idkp; | ||
70 | } | ||
71 | |||
72 | static void ide_disk_put(struct ide_disk_obj *idkp) | ||
73 | { | ||
74 | ide_drive_t *drive = idkp->drive; | ||
75 | |||
76 | mutex_lock(&idedisk_ref_mutex); | ||
77 | kref_put(&idkp->kref, ide_disk_release); | ||
78 | ide_device_put(drive); | ||
79 | mutex_unlock(&idedisk_ref_mutex); | ||
80 | } | ||
81 | |||
82 | static const u8 ide_rw_cmds[] = { | 41 | static const u8 ide_rw_cmds[] = { |
83 | ATA_CMD_READ_MULTI, | 42 | ATA_CMD_READ_MULTI, |
84 | ATA_CMD_WRITE_MULTI, | 43 | ATA_CMD_WRITE_MULTI, |
@@ -374,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
374 | } | 333 | } |
375 | } | 334 | } |
376 | 335 | ||
377 | static void init_idedisk_capacity(ide_drive_t *drive) | 336 | static int ide_disk_get_capacity(ide_drive_t *drive) |
378 | { | 337 | { |
379 | u16 *id = drive->id; | 338 | u16 *id = drive->id; |
380 | int lba; | 339 | int lba; |
@@ -403,11 +362,28 @@ static void init_idedisk_capacity(ide_drive_t *drive) | |||
403 | if (ata_id_hpa_enabled(id)) | 362 | if (ata_id_hpa_enabled(id)) |
404 | idedisk_check_hpa(drive); | 363 | idedisk_check_hpa(drive); |
405 | } | 364 | } |
406 | } | ||
407 | 365 | ||
408 | sector_t ide_disk_capacity(ide_drive_t *drive) | 366 | /* limit drive capacity to 137GB if LBA48 cannot be used */ |
409 | { | 367 | if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && |
410 | return drive->capacity64; | 368 | drive->capacity64 > 1ULL << 28) { |
369 | printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " | ||
370 | "%llu sectors (%llu MB)\n", | ||
371 | drive->name, (unsigned long long)drive->capacity64, | ||
372 | sectors_to_MB(drive->capacity64)); | ||
373 | drive->capacity64 = 1ULL << 28; | ||
374 | } | ||
375 | |||
376 | if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && | ||
377 | (drive->dev_flags & IDE_DFLAG_LBA48)) { | ||
378 | if (drive->capacity64 > 1ULL << 28) { | ||
379 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" | ||
380 | " will be used for accessing sectors " | ||
381 | "> %u\n", drive->name, 1 << 28); | ||
382 | } else | ||
383 | drive->dev_flags &= ~IDE_DFLAG_LBA48; | ||
384 | } | ||
385 | |||
386 | return 0; | ||
411 | } | 387 | } |
412 | 388 | ||
413 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | 389 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) |
@@ -508,7 +484,7 @@ static void update_ordered(ide_drive_t *drive) | |||
508 | * time we have trimmed the drive capacity if LBA48 is | 484 | * time we have trimmed the drive capacity if LBA48 is |
509 | * not available so we don't need to recheck that. | 485 | * not available so we don't need to recheck that. |
510 | */ | 486 | */ |
511 | capacity = ide_disk_capacity(drive); | 487 | capacity = ide_gd_capacity(drive); |
512 | barrier = ata_id_flush_enabled(id) && | 488 | barrier = ata_id_flush_enabled(id) && |
513 | (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && | 489 | (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && |
514 | ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || | 490 | ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || |
@@ -616,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache); | |||
616 | 592 | ||
617 | ide_ext_devset_rw_sync(nowerr, nowerr); | 593 | ide_ext_devset_rw_sync(nowerr, nowerr); |
618 | 594 | ||
619 | static void idedisk_setup(ide_drive_t *drive) | 595 | static int ide_disk_check(ide_drive_t *drive, const char *s) |
596 | { | ||
597 | return 1; | ||
598 | } | ||
599 | |||
600 | static void ide_disk_setup(ide_drive_t *drive) | ||
620 | { | 601 | { |
621 | struct ide_disk_obj *idkp = drive->driver_data; | 602 | struct ide_disk_obj *idkp = drive->driver_data; |
622 | ide_hwif_t *hwif = drive->hwif; | 603 | ide_hwif_t *hwif = drive->hwif; |
@@ -652,33 +633,13 @@ static void idedisk_setup(ide_drive_t *drive) | |||
652 | drive->queue->max_sectors / 2); | 633 | drive->queue->max_sectors / 2); |
653 | 634 | ||
654 | /* calculate drive capacity, and select LBA if possible */ | 635 | /* calculate drive capacity, and select LBA if possible */ |
655 | init_idedisk_capacity(drive); | 636 | ide_disk_get_capacity(drive); |
656 | |||
657 | /* limit drive capacity to 137GB if LBA48 cannot be used */ | ||
658 | if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && | ||
659 | drive->capacity64 > 1ULL << 28) { | ||
660 | printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " | ||
661 | "%llu sectors (%llu MB)\n", | ||
662 | drive->name, (unsigned long long)drive->capacity64, | ||
663 | sectors_to_MB(drive->capacity64)); | ||
664 | drive->capacity64 = 1ULL << 28; | ||
665 | } | ||
666 | |||
667 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && | ||
668 | (drive->dev_flags & IDE_DFLAG_LBA48)) { | ||
669 | if (drive->capacity64 > 1ULL << 28) { | ||
670 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" | ||
671 | " will be used for accessing sectors " | ||
672 | "> %u\n", drive->name, 1 << 28); | ||
673 | } else | ||
674 | drive->dev_flags &= ~IDE_DFLAG_LBA48; | ||
675 | } | ||
676 | 637 | ||
677 | /* | 638 | /* |
678 | * if possible, give fdisk access to more of the drive, | 639 | * if possible, give fdisk access to more of the drive, |
679 | * by correcting bios_cyls: | 640 | * by correcting bios_cyls: |
680 | */ | 641 | */ |
681 | capacity = ide_disk_capacity(drive); | 642 | capacity = ide_gd_capacity(drive); |
682 | 643 | ||
683 | if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { | 644 | if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { |
684 | if (ata_id_lba48_enabled(drive->id)) { | 645 | if (ata_id_lba48_enabled(drive->id)) { |
@@ -718,9 +679,17 @@ static void idedisk_setup(ide_drive_t *drive) | |||
718 | drive->dev_flags |= IDE_DFLAG_WCACHE; | 679 | drive->dev_flags |= IDE_DFLAG_WCACHE; |
719 | 680 | ||
720 | set_wcache(drive, 1); | 681 | set_wcache(drive, 1); |
682 | |||
683 | if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && | ||
684 | (drive->head == 0 || drive->head > 16)) { | ||
685 | printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n", | ||
686 | drive->name, drive->head); | ||
687 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
688 | } else | ||
689 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
721 | } | 690 | } |
722 | 691 | ||
723 | static void ide_cacheflush_p(ide_drive_t *drive) | 692 | static void ide_disk_flush(ide_drive_t *drive) |
724 | { | 693 | { |
725 | if (ata_id_flush_enabled(drive->id) == 0 || | 694 | if (ata_id_flush_enabled(drive->id) == 0 || |
726 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) | 695 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) |
@@ -730,267 +699,40 @@ static void ide_cacheflush_p(ide_drive_t *drive) | |||
730 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); | 699 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); |
731 | } | 700 | } |
732 | 701 | ||
733 | static void ide_disk_remove(ide_drive_t *drive) | 702 | static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) |
734 | { | ||
735 | struct ide_disk_obj *idkp = drive->driver_data; | ||
736 | struct gendisk *g = idkp->disk; | ||
737 | |||
738 | ide_proc_unregister_driver(drive, idkp->driver); | ||
739 | |||
740 | del_gendisk(g); | ||
741 | |||
742 | ide_cacheflush_p(drive); | ||
743 | |||
744 | ide_disk_put(idkp); | ||
745 | } | ||
746 | |||
747 | static void ide_disk_release(struct kref *kref) | ||
748 | { | ||
749 | struct ide_disk_obj *idkp = to_ide_disk(kref); | ||
750 | ide_drive_t *drive = idkp->drive; | ||
751 | struct gendisk *g = idkp->disk; | ||
752 | |||
753 | drive->driver_data = NULL; | ||
754 | g->private_data = NULL; | ||
755 | put_disk(g); | ||
756 | kfree(idkp); | ||
757 | } | ||
758 | |||
759 | static int ide_disk_probe(ide_drive_t *drive); | ||
760 | |||
761 | /* | ||
762 | * On HPA drives the capacity needs to be | ||
763 | * reinitilized on resume otherwise the disk | ||
764 | * can not be used and a hard reset is required | ||
765 | */ | ||
766 | static void ide_disk_resume(ide_drive_t *drive) | ||
767 | { | 703 | { |
768 | if (ata_id_hpa_enabled(drive->id)) | 704 | return 0; |
769 | init_idedisk_capacity(drive); | ||
770 | } | ||
771 | |||
772 | static void ide_device_shutdown(ide_drive_t *drive) | ||
773 | { | ||
774 | #ifdef CONFIG_ALPHA | ||
775 | /* On Alpha, halt(8) doesn't actually turn the machine off, | ||
776 | it puts you into the sort of firmware monitor. Typically, | ||
777 | it's used to boot another kernel image, so it's not much | ||
778 | different from reboot(8). Therefore, we don't need to | ||
779 | spin down the disk in this case, especially since Alpha | ||
780 | firmware doesn't handle disks in standby mode properly. | ||
781 | On the other hand, it's reasonably safe to turn the power | ||
782 | off when the shutdown process reaches the firmware prompt, | ||
783 | as the firmware initialization takes rather long time - | ||
784 | at least 10 seconds, which should be sufficient for | ||
785 | the disk to expire its write cache. */ | ||
786 | if (system_state != SYSTEM_POWER_OFF) { | ||
787 | #else | ||
788 | if (system_state == SYSTEM_RESTART) { | ||
789 | #endif | ||
790 | ide_cacheflush_p(drive); | ||
791 | return; | ||
792 | } | ||
793 | |||
794 | printk(KERN_INFO "Shutdown: %s\n", drive->name); | ||
795 | |||
796 | drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); | ||
797 | } | 705 | } |
798 | 706 | ||
799 | static ide_driver_t idedisk_driver = { | 707 | static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, |
800 | .gen_driver = { | 708 | int on) |
801 | .owner = THIS_MODULE, | ||
802 | .name = "ide-disk", | ||
803 | .bus = &ide_bus_type, | ||
804 | }, | ||
805 | .probe = ide_disk_probe, | ||
806 | .remove = ide_disk_remove, | ||
807 | .resume = ide_disk_resume, | ||
808 | .shutdown = ide_device_shutdown, | ||
809 | .version = IDEDISK_VERSION, | ||
810 | .do_request = ide_do_rw_disk, | ||
811 | .end_request = ide_end_request, | ||
812 | .error = __ide_error, | ||
813 | #ifdef CONFIG_IDE_PROC_FS | ||
814 | .proc = ide_disk_proc, | ||
815 | .settings = ide_disk_settings, | ||
816 | #endif | ||
817 | }; | ||
818 | |||
819 | static int idedisk_set_doorlock(ide_drive_t *drive, int on) | ||
820 | { | 709 | { |
821 | ide_task_t task; | 710 | ide_task_t task; |
711 | int ret; | ||
712 | |||
713 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) | ||
714 | return 0; | ||
822 | 715 | ||
823 | memset(&task, 0, sizeof(task)); | 716 | memset(&task, 0, sizeof(task)); |
824 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; | 717 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; |
825 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 718 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
826 | 719 | ||
827 | return ide_no_data_taskfile(drive, &task); | 720 | ret = ide_no_data_taskfile(drive, &task); |
828 | } | ||
829 | |||
830 | static int idedisk_open(struct inode *inode, struct file *filp) | ||
831 | { | ||
832 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
833 | struct ide_disk_obj *idkp; | ||
834 | ide_drive_t *drive; | ||
835 | |||
836 | idkp = ide_disk_get(disk); | ||
837 | if (idkp == NULL) | ||
838 | return -ENXIO; | ||
839 | |||
840 | drive = idkp->drive; | ||
841 | |||
842 | idkp->openers++; | ||
843 | |||
844 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
845 | check_disk_change(inode->i_bdev); | ||
846 | /* | ||
847 | * Ignore the return code from door_lock, | ||
848 | * since the open() has already succeeded, | ||
849 | * and the door_lock is irrelevant at this point. | ||
850 | */ | ||
851 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && | ||
852 | idedisk_set_doorlock(drive, 1)) | ||
853 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
854 | } | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | static int idedisk_release(struct inode *inode, struct file *filp) | ||
859 | { | ||
860 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
861 | struct ide_disk_obj *idkp = ide_disk_g(disk); | ||
862 | ide_drive_t *drive = idkp->drive; | ||
863 | |||
864 | if (idkp->openers == 1) | ||
865 | ide_cacheflush_p(drive); | ||
866 | |||
867 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
868 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && | ||
869 | idedisk_set_doorlock(drive, 0)) | ||
870 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
871 | } | ||
872 | 721 | ||
873 | idkp->openers--; | 722 | if (ret) |
723 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
874 | 724 | ||
875 | ide_disk_put(idkp); | 725 | return ret; |
876 | |||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
881 | { | ||
882 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | ||
883 | ide_drive_t *drive = idkp->drive; | ||
884 | |||
885 | geo->heads = drive->bios_head; | ||
886 | geo->sectors = drive->bios_sect; | ||
887 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
888 | return 0; | ||
889 | } | 726 | } |
890 | 727 | ||
891 | static int idedisk_media_changed(struct gendisk *disk) | 728 | const struct ide_disk_ops ide_ata_disk_ops = { |
892 | { | 729 | .check = ide_disk_check, |
893 | struct ide_disk_obj *idkp = ide_disk_g(disk); | 730 | .get_capacity = ide_disk_get_capacity, |
894 | ide_drive_t *drive = idkp->drive; | 731 | .setup = ide_disk_setup, |
895 | 732 | .flush = ide_disk_flush, | |
896 | /* do not scan partitions twice if this is a removable device */ | 733 | .init_media = ide_disk_init_media, |
897 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | 734 | .set_doorlock = ide_disk_set_doorlock, |
898 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | 735 | .do_request = ide_do_rw_disk, |
899 | return 0; | 736 | .end_request = ide_end_request, |
900 | } | 737 | .ioctl = ide_disk_ioctl, |
901 | |||
902 | /* if removable, always assume it was changed */ | ||
903 | return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE); | ||
904 | } | ||
905 | |||
906 | static int idedisk_revalidate_disk(struct gendisk *disk) | ||
907 | { | ||
908 | struct ide_disk_obj *idkp = ide_disk_g(disk); | ||
909 | set_capacity(disk, ide_disk_capacity(idkp->drive)); | ||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | static struct block_device_operations idedisk_ops = { | ||
914 | .owner = THIS_MODULE, | ||
915 | .open = idedisk_open, | ||
916 | .release = idedisk_release, | ||
917 | .ioctl = ide_disk_ioctl, | ||
918 | .getgeo = idedisk_getgeo, | ||
919 | .media_changed = idedisk_media_changed, | ||
920 | .revalidate_disk = idedisk_revalidate_disk | ||
921 | }; | 738 | }; |
922 | |||
923 | MODULE_DESCRIPTION("ATA DISK Driver"); | ||
924 | |||
925 | static int ide_disk_probe(ide_drive_t *drive) | ||
926 | { | ||
927 | struct ide_disk_obj *idkp; | ||
928 | struct gendisk *g; | ||
929 | |||
930 | /* strstr("foo", "") is non-NULL */ | ||
931 | if (!strstr("ide-disk", drive->driver_req)) | ||
932 | goto failed; | ||
933 | |||
934 | if (drive->media != ide_disk) | ||
935 | goto failed; | ||
936 | |||
937 | idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); | ||
938 | if (!idkp) | ||
939 | goto failed; | ||
940 | |||
941 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); | ||
942 | if (!g) | ||
943 | goto out_free_idkp; | ||
944 | |||
945 | ide_init_disk(g, drive); | ||
946 | |||
947 | kref_init(&idkp->kref); | ||
948 | |||
949 | idkp->drive = drive; | ||
950 | idkp->driver = &idedisk_driver; | ||
951 | idkp->disk = g; | ||
952 | |||
953 | g->private_data = &idkp->driver; | ||
954 | |||
955 | drive->driver_data = idkp; | ||
956 | |||
957 | idedisk_setup(drive); | ||
958 | if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && | ||
959 | (drive->head == 0 || drive->head > 16)) { | ||
960 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | ||
961 | drive->name, drive->head); | ||
962 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
963 | } else | ||
964 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
965 | |||
966 | g->minors = IDE_DISK_MINORS; | ||
967 | g->driverfs_dev = &drive->gendev; | ||
968 | g->flags |= GENHD_FL_EXT_DEVT; | ||
969 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
970 | g->flags = GENHD_FL_REMOVABLE; | ||
971 | set_capacity(g, ide_disk_capacity(drive)); | ||
972 | g->fops = &idedisk_ops; | ||
973 | add_disk(g); | ||
974 | return 0; | ||
975 | |||
976 | out_free_idkp: | ||
977 | kfree(idkp); | ||
978 | failed: | ||
979 | return -ENODEV; | ||
980 | } | ||
981 | |||
982 | static void __exit idedisk_exit(void) | ||
983 | { | ||
984 | driver_unregister(&idedisk_driver.gen_driver); | ||
985 | } | ||
986 | |||
987 | static int __init idedisk_init(void) | ||
988 | { | ||
989 | return driver_register(&idedisk_driver.gen_driver); | ||
990 | } | ||
991 | |||
992 | MODULE_ALIAS("ide:*m-disk*"); | ||
993 | MODULE_ALIAS("ide-disk"); | ||
994 | module_init(idedisk_init); | ||
995 | module_exit(idedisk_exit); | ||
996 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h index a82fa4355665..b234b0feaf7b 100644 --- a/drivers/ide/ide-disk.h +++ b/drivers/ide/ide-disk.h | |||
@@ -1,19 +1,11 @@ | |||
1 | #ifndef __IDE_DISK_H | 1 | #ifndef __IDE_DISK_H |
2 | #define __IDE_DISK_H | 2 | #define __IDE_DISK_H |
3 | 3 | ||
4 | struct ide_disk_obj { | 4 | #include "ide-gd.h" |
5 | ide_drive_t *drive; | ||
6 | ide_driver_t *driver; | ||
7 | struct gendisk *disk; | ||
8 | struct kref kref; | ||
9 | unsigned int openers; /* protected by BKL for now */ | ||
10 | }; | ||
11 | |||
12 | #define ide_disk_g(disk) \ | ||
13 | container_of((disk)->private_data, struct ide_disk_obj, driver) | ||
14 | 5 | ||
6 | #ifdef CONFIG_IDE_GD_ATA | ||
15 | /* ide-disk.c */ | 7 | /* ide-disk.c */ |
16 | sector_t ide_disk_capacity(ide_drive_t *); | 8 | extern const struct ide_disk_ops ide_ata_disk_ops; |
17 | ide_decl_devset(address); | 9 | ide_decl_devset(address); |
18 | ide_decl_devset(multcount); | 10 | ide_decl_devset(multcount); |
19 | ide_decl_devset(nowerr); | 11 | ide_decl_devset(nowerr); |
@@ -21,12 +13,17 @@ ide_decl_devset(wcache); | |||
21 | ide_decl_devset(acoustic); | 13 | ide_decl_devset(acoustic); |
22 | 14 | ||
23 | /* ide-disk_ioctl.c */ | 15 | /* ide-disk_ioctl.c */ |
24 | int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 16 | int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, |
17 | unsigned long); | ||
25 | 18 | ||
26 | #ifdef CONFIG_IDE_PROC_FS | 19 | #ifdef CONFIG_IDE_PROC_FS |
27 | /* ide-disk_proc.c */ | 20 | /* ide-disk_proc.c */ |
28 | extern ide_proc_entry_t ide_disk_proc[]; | 21 | extern ide_proc_entry_t ide_disk_proc[]; |
29 | extern const struct ide_proc_devset ide_disk_settings[]; | 22 | extern const struct ide_proc_devset ide_disk_settings[]; |
30 | #endif | 23 | #endif |
24 | #else | ||
25 | #define ide_disk_proc NULL | ||
26 | #define ide_disk_settings NULL | ||
27 | #endif | ||
31 | 28 | ||
32 | #endif /* __IDE_DISK_H */ | 29 | #endif /* __IDE_DISK_H */ |
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c index a6cf1a03a806..a49698bcf966 100644 --- a/drivers/ide/ide-disk_ioctl.c +++ b/drivers/ide/ide-disk_ioctl.c | |||
@@ -13,12 +13,10 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { | |||
13 | { 0 } | 13 | { 0 } |
14 | }; | 14 | }; |
15 | 15 | ||
16 | int ide_disk_ioctl(struct inode *inode, struct file *file, | 16 | int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, |
17 | unsigned int cmd, unsigned long arg) | 17 | unsigned int cmd, unsigned long arg) |
18 | { | 18 | { |
19 | struct block_device *bdev = inode->i_bdev; | 19 | struct block_device *bdev = inode->i_bdev; |
20 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | ||
21 | ide_drive_t *drive = idkp->drive; | ||
22 | int err; | 20 | int err; |
23 | 21 | ||
24 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); | 22 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); |
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index 4724976afe71..1146f4204c6e 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c | |||
@@ -56,7 +56,7 @@ static int proc_idedisk_read_capacity | |||
56 | ide_drive_t*drive = (ide_drive_t *)data; | 56 | ide_drive_t*drive = (ide_drive_t *)data; |
57 | int len; | 57 | int len; |
58 | 58 | ||
59 | len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive)); | 59 | len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); |
60 | 60 | ||
61 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 61 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
62 | } | 62 | } |
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 0903782689e9..cac431f0df17 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c | |||
@@ -130,7 +130,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq) | |||
130 | xcount = bcount & 0xffff; | 130 | xcount = bcount & 0xffff; |
131 | if (is_trm290) | 131 | if (is_trm290) |
132 | xcount = ((xcount >> 2) - 1) << 16; | 132 | xcount = ((xcount >> 2) - 1) << 16; |
133 | if (xcount == 0x0000) { | 133 | else if (xcount == 0x0000) { |
134 | if (count++ >= PRD_ENTRIES) | 134 | if (count++ >= PRD_ENTRIES) |
135 | goto use_pio_instead; | 135 | goto use_pio_instead; |
136 | *table++ = cpu_to_le32(0x8000); | 136 | *table++ = cpu_to_le32(0x8000); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index cf0aa25470ee..aeb1ad782f54 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -15,12 +15,6 @@ | |||
15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 | 15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define DRV_NAME "ide-floppy" | ||
19 | #define PFX DRV_NAME ": " | ||
20 | |||
21 | #define IDEFLOPPY_VERSION "1.00" | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | 18 | #include <linux/types.h> |
25 | #include <linux/string.h> | 19 | #include <linux/string.h> |
26 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -49,19 +43,6 @@ | |||
49 | 43 | ||
50 | #include "ide-floppy.h" | 44 | #include "ide-floppy.h" |
51 | 45 | ||
52 | /* module parameters */ | ||
53 | static unsigned long debug_mask; | ||
54 | module_param(debug_mask, ulong, 0644); | ||
55 | |||
56 | /* define to see debug info */ | ||
57 | #define IDEFLOPPY_DEBUG_LOG 0 | ||
58 | |||
59 | #if IDEFLOPPY_DEBUG_LOG | ||
60 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
61 | #else | ||
62 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
63 | #endif | ||
64 | |||
65 | /* | 46 | /* |
66 | * After each failed packet command we issue a request sense command and retry | 47 | * After each failed packet command we issue a request sense command and retry |
67 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. | 48 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
@@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644); | |||
83 | /* Error code returned in rq->errors to the higher part of the driver. */ | 64 | /* Error code returned in rq->errors to the higher part of the driver. */ |
84 | #define IDEFLOPPY_ERROR_GENERAL 101 | 65 | #define IDEFLOPPY_ERROR_GENERAL 101 |
85 | 66 | ||
86 | static DEFINE_MUTEX(idefloppy_ref_mutex); | ||
87 | |||
88 | static void idefloppy_cleanup_obj(struct kref *); | ||
89 | |||
90 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) | ||
91 | { | ||
92 | struct ide_floppy_obj *floppy = NULL; | ||
93 | |||
94 | mutex_lock(&idefloppy_ref_mutex); | ||
95 | floppy = ide_drv_g(disk, ide_floppy_obj); | ||
96 | if (floppy) { | ||
97 | if (ide_device_get(floppy->drive)) | ||
98 | floppy = NULL; | ||
99 | else | ||
100 | kref_get(&floppy->kref); | ||
101 | } | ||
102 | mutex_unlock(&idefloppy_ref_mutex); | ||
103 | return floppy; | ||
104 | } | ||
105 | |||
106 | static void ide_floppy_put(struct ide_floppy_obj *floppy) | ||
107 | { | ||
108 | ide_drive_t *drive = floppy->drive; | ||
109 | |||
110 | mutex_lock(&idefloppy_ref_mutex); | ||
111 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | ||
112 | ide_device_put(drive); | ||
113 | mutex_unlock(&idefloppy_ref_mutex); | ||
114 | } | ||
115 | |||
116 | /* | 67 | /* |
117 | * Used to finish servicing a request. For read/write requests, we will call | 68 | * Used to finish servicing a request. For read/write requests, we will call |
118 | * ide_end_request to pass to the next buffer. | 69 | * ide_end_request to pass to the next buffer. |
119 | */ | 70 | */ |
120 | static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | 71 | static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) |
121 | { | 72 | { |
122 | idefloppy_floppy_t *floppy = drive->driver_data; | 73 | struct ide_disk_obj *floppy = drive->driver_data; |
123 | struct request *rq = HWGROUP(drive)->rq; | 74 | struct request *rq = HWGROUP(drive)->rq; |
124 | int error; | 75 | int error; |
125 | 76 | ||
@@ -161,12 +112,12 @@ static void idefloppy_update_buffers(ide_drive_t *drive, | |||
161 | struct bio *bio = rq->bio; | 112 | struct bio *bio = rq->bio; |
162 | 113 | ||
163 | while ((bio = rq->bio) != NULL) | 114 | while ((bio = rq->bio) != NULL) |
164 | idefloppy_end_request(drive, 1, 0); | 115 | ide_floppy_end_request(drive, 1, 0); |
165 | } | 116 | } |
166 | 117 | ||
167 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) | 118 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) |
168 | { | 119 | { |
169 | idefloppy_floppy_t *floppy = drive->driver_data; | 120 | struct ide_disk_obj *floppy = drive->driver_data; |
170 | struct ide_atapi_pc *pc = drive->pc; | 121 | struct ide_atapi_pc *pc = drive->pc; |
171 | int uptodate = pc->error ? 0 : 1; | 122 | int uptodate = pc->error ? 0 : 1; |
172 | 123 | ||
@@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) | |||
200 | "Aborting request!\n"); | 151 | "Aborting request!\n"); |
201 | } | 152 | } |
202 | 153 | ||
203 | idefloppy_end_request(drive, uptodate, 0); | 154 | ide_floppy_end_request(drive, uptodate, 0); |
204 | } | 155 | } |
205 | 156 | ||
206 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | 157 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
207 | struct ide_atapi_pc *pc) | 158 | struct ide_atapi_pc *pc) |
208 | { | 159 | { |
209 | /* supress error messages resulting from Medium not present */ | 160 | /* supress error messages resulting from Medium not present */ |
@@ -222,7 +173,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | |||
222 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | 173 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, |
223 | struct ide_atapi_pc *pc) | 174 | struct ide_atapi_pc *pc) |
224 | { | 175 | { |
225 | idefloppy_floppy_t *floppy = drive->driver_data; | 176 | struct ide_disk_obj *floppy = drive->driver_data; |
226 | 177 | ||
227 | if (floppy->failed_pc == NULL && | 178 | if (floppy->failed_pc == NULL && |
228 | pc->c[0] != GPCMD_REQUEST_SENSE) | 179 | pc->c[0] != GPCMD_REQUEST_SENSE) |
@@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
286 | struct ide_atapi_pc *pc, struct request *rq, | 237 | struct ide_atapi_pc *pc, struct request *rq, |
287 | unsigned long sector) | 238 | unsigned long sector) |
288 | { | 239 | { |
289 | idefloppy_floppy_t *floppy = drive->driver_data; | 240 | struct ide_disk_obj *floppy = drive->driver_data; |
290 | int block = sector / floppy->bs_factor; | 241 | int block = sector / floppy->bs_factor; |
291 | int blocks = rq->nr_sectors / floppy->bs_factor; | 242 | int blocks = rq->nr_sectors / floppy->bs_factor; |
292 | int cmd = rq_data_dir(rq); | 243 | int cmd = rq_data_dir(rq); |
@@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
310 | pc->flags |= PC_FLAG_DMA_OK; | 261 | pc->flags |= PC_FLAG_DMA_OK; |
311 | } | 262 | } |
312 | 263 | ||
313 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | 264 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
314 | struct ide_atapi_pc *pc, struct request *rq) | 265 | struct ide_atapi_pc *pc, struct request *rq) |
315 | { | 266 | { |
316 | ide_init_pc(pc); | 267 | ide_init_pc(pc); |
@@ -329,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | |||
329 | pc->req_xfer = pc->buf_size = rq->data_len; | 280 | pc->req_xfer = pc->buf_size = rq->data_len; |
330 | } | 281 | } |
331 | 282 | ||
332 | static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | 283 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
333 | struct request *rq, sector_t block_s) | 284 | struct request *rq, sector_t block) |
334 | { | 285 | { |
335 | idefloppy_floppy_t *floppy = drive->driver_data; | 286 | struct ide_disk_obj *floppy = drive->driver_data; |
336 | ide_hwif_t *hwif = drive->hwif; | 287 | ide_hwif_t *hwif = drive->hwif; |
337 | struct ide_atapi_pc *pc; | 288 | struct ide_atapi_pc *pc; |
338 | unsigned long block = (unsigned long)block_s; | ||
339 | 289 | ||
340 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " | 290 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " |
341 | "errors: %d\n", | 291 | "errors: %d\n", |
@@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
353 | else | 303 | else |
354 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); | 304 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); |
355 | 305 | ||
356 | idefloppy_end_request(drive, 0, 0); | 306 | ide_floppy_end_request(drive, 0, 0); |
357 | return ide_stopped; | 307 | return ide_stopped; |
358 | } | 308 | } |
359 | if (blk_fs_request(rq)) { | 309 | if (blk_fs_request(rq)) { |
@@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
361 | (rq->nr_sectors % floppy->bs_factor)) { | 311 | (rq->nr_sectors % floppy->bs_factor)) { |
362 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", | 312 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", |
363 | drive->name); | 313 | drive->name); |
364 | idefloppy_end_request(drive, 0, 0); | 314 | ide_floppy_end_request(drive, 0, 0); |
365 | return ide_stopped; | 315 | return ide_stopped; |
366 | } | 316 | } |
367 | pc = &floppy->queued_pc; | 317 | pc = &floppy->queued_pc; |
368 | idefloppy_create_rw_cmd(drive, pc, rq, block); | 318 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
369 | } else if (blk_special_request(rq)) { | 319 | } else if (blk_special_request(rq)) { |
370 | pc = (struct ide_atapi_pc *) rq->buffer; | 320 | pc = (struct ide_atapi_pc *) rq->buffer; |
371 | } else if (blk_pc_request(rq)) { | 321 | } else if (blk_pc_request(rq)) { |
@@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
373 | idefloppy_blockpc_cmd(floppy, pc, rq); | 323 | idefloppy_blockpc_cmd(floppy, pc, rq); |
374 | } else { | 324 | } else { |
375 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); | 325 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); |
376 | idefloppy_end_request(drive, 0, 0); | 326 | ide_floppy_end_request(drive, 0, 0); |
377 | return ide_stopped; | 327 | return ide_stopped; |
378 | } | 328 | } |
379 | 329 | ||
@@ -394,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
394 | */ | 344 | */ |
395 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | 345 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) |
396 | { | 346 | { |
397 | idefloppy_floppy_t *floppy = drive->driver_data; | 347 | struct ide_disk_obj *floppy = drive->driver_data; |
398 | struct gendisk *disk = floppy->disk; | 348 | struct gendisk *disk = floppy->disk; |
399 | struct ide_atapi_pc pc; | 349 | struct ide_atapi_pc pc; |
400 | u8 *page; | 350 | u8 *page; |
@@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
410 | } | 360 | } |
411 | 361 | ||
412 | if (pc.buf[3] & 0x80) | 362 | if (pc.buf[3] & 0x80) |
413 | drive->atapi_flags |= IDE_AFLAG_WP; | 363 | drive->dev_flags |= IDE_DFLAG_WP; |
414 | else | 364 | else |
415 | drive->atapi_flags &= ~IDE_AFLAG_WP; | 365 | drive->dev_flags &= ~IDE_DFLAG_WP; |
416 | 366 | ||
417 | set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP)); | 367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
418 | 368 | ||
419 | page = &pc.buf[8]; | 369 | page = &pc.buf[8]; |
420 | 370 | ||
@@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
445 | drive->name, lba_capacity, capacity); | 395 | drive->name, lba_capacity, capacity); |
446 | floppy->blocks = floppy->block_size ? | 396 | floppy->blocks = floppy->block_size ? |
447 | capacity / floppy->block_size : 0; | 397 | capacity / floppy->block_size : 0; |
398 | drive->capacity64 = floppy->blocks * floppy->bs_factor; | ||
448 | } | 399 | } |
400 | |||
449 | return 0; | 401 | return 0; |
450 | } | 402 | } |
451 | 403 | ||
@@ -455,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
455 | */ | 407 | */ |
456 | static int ide_floppy_get_capacity(ide_drive_t *drive) | 408 | static int ide_floppy_get_capacity(ide_drive_t *drive) |
457 | { | 409 | { |
458 | idefloppy_floppy_t *floppy = drive->driver_data; | 410 | struct ide_disk_obj *floppy = drive->driver_data; |
459 | struct gendisk *disk = floppy->disk; | 411 | struct gendisk *disk = floppy->disk; |
460 | struct ide_atapi_pc pc; | 412 | struct ide_atapi_pc pc; |
461 | u8 *cap_desc; | 413 | u8 *cap_desc; |
@@ -466,7 +418,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
466 | drive->bios_head = drive->bios_sect = 0; | 418 | drive->bios_head = drive->bios_sect = 0; |
467 | floppy->blocks = 0; | 419 | floppy->blocks = 0; |
468 | floppy->bs_factor = 1; | 420 | floppy->bs_factor = 1; |
469 | set_capacity(floppy->disk, 0); | 421 | drive->capacity64 = 0; |
470 | 422 | ||
471 | ide_floppy_create_read_capacity_cmd(&pc); | 423 | ide_floppy_create_read_capacity_cmd(&pc); |
472 | if (ide_queue_pc_tail(drive, disk, &pc)) { | 424 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
@@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
523 | "non 512 bytes block size not " | 475 | "non 512 bytes block size not " |
524 | "fully supported\n", | 476 | "fully supported\n", |
525 | drive->name); | 477 | drive->name); |
478 | drive->capacity64 = | ||
479 | floppy->blocks * floppy->bs_factor; | ||
526 | rc = 0; | 480 | rc = 0; |
527 | } | 481 | } |
528 | break; | 482 | break; |
@@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
547 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
548 | (void) ide_floppy_get_flexible_disk_page(drive); | 502 | (void) ide_floppy_get_flexible_disk_page(drive); |
549 | 503 | ||
550 | set_capacity(disk, floppy->blocks * floppy->bs_factor); | ||
551 | |||
552 | return rc; | 504 | return rc; |
553 | } | 505 | } |
554 | 506 | ||
555 | sector_t ide_floppy_capacity(ide_drive_t *drive) | 507 | static void ide_floppy_setup(ide_drive_t *drive) |
556 | { | ||
557 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
558 | unsigned long capacity = floppy->blocks * floppy->bs_factor; | ||
559 | |||
560 | return capacity; | ||
561 | } | ||
562 | |||
563 | static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | ||
564 | { | 508 | { |
509 | struct ide_disk_obj *floppy = drive->driver_data; | ||
565 | u16 *id = drive->id; | 510 | u16 *id = drive->id; |
566 | 511 | ||
567 | drive->pc_callback = ide_floppy_callback; | 512 | drive->pc_callback = ide_floppy_callback; |
@@ -592,252 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
592 | blk_queue_max_sectors(drive->queue, 64); | 537 | blk_queue_max_sectors(drive->queue, 64); |
593 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; | 538 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
594 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | 539 | /* IOMEGA Clik! drives do not support lock/unlock commands */ |
595 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 540 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
596 | } | 541 | } |
597 | 542 | ||
598 | (void) ide_floppy_get_capacity(drive); | 543 | (void) ide_floppy_get_capacity(drive); |
599 | 544 | ||
600 | ide_proc_register_driver(drive, floppy->driver); | 545 | ide_proc_register_driver(drive, floppy->driver); |
601 | } | ||
602 | 546 | ||
603 | static void ide_floppy_remove(ide_drive_t *drive) | 547 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
604 | { | ||
605 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
606 | struct gendisk *g = floppy->disk; | ||
607 | |||
608 | ide_proc_unregister_driver(drive, floppy->driver); | ||
609 | |||
610 | del_gendisk(g); | ||
611 | |||
612 | ide_floppy_put(floppy); | ||
613 | } | 548 | } |
614 | 549 | ||
615 | static void idefloppy_cleanup_obj(struct kref *kref) | 550 | static void ide_floppy_flush(ide_drive_t *drive) |
616 | { | 551 | { |
617 | struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj); | ||
618 | ide_drive_t *drive = floppy->drive; | ||
619 | struct gendisk *g = floppy->disk; | ||
620 | |||
621 | drive->driver_data = NULL; | ||
622 | g->private_data = NULL; | ||
623 | put_disk(g); | ||
624 | kfree(floppy); | ||
625 | } | 552 | } |
626 | 553 | ||
627 | static int ide_floppy_probe(ide_drive_t *); | 554 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) |
628 | |||
629 | static ide_driver_t idefloppy_driver = { | ||
630 | .gen_driver = { | ||
631 | .owner = THIS_MODULE, | ||
632 | .name = "ide-floppy", | ||
633 | .bus = &ide_bus_type, | ||
634 | }, | ||
635 | .probe = ide_floppy_probe, | ||
636 | .remove = ide_floppy_remove, | ||
637 | .version = IDEFLOPPY_VERSION, | ||
638 | .do_request = idefloppy_do_request, | ||
639 | .end_request = idefloppy_end_request, | ||
640 | .error = __ide_error, | ||
641 | #ifdef CONFIG_IDE_PROC_FS | ||
642 | .proc = ide_floppy_proc, | ||
643 | .settings = ide_floppy_settings, | ||
644 | #endif | ||
645 | }; | ||
646 | |||
647 | static int idefloppy_open(struct inode *inode, struct file *filp) | ||
648 | { | 555 | { |
649 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
650 | struct ide_floppy_obj *floppy; | ||
651 | ide_drive_t *drive; | ||
652 | int ret = 0; | 556 | int ret = 0; |
653 | 557 | ||
654 | floppy = ide_floppy_get(disk); | 558 | if (ide_do_test_unit_ready(drive, disk)) |
655 | if (!floppy) | 559 | ide_do_start_stop(drive, disk, 1); |
656 | return -ENXIO; | ||
657 | |||
658 | drive = floppy->drive; | ||
659 | |||
660 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
661 | |||
662 | floppy->openers++; | ||
663 | |||
664 | if (floppy->openers == 1) { | ||
665 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
666 | /* Just in case */ | ||
667 | |||
668 | if (ide_do_test_unit_ready(drive, disk)) | ||
669 | ide_do_start_stop(drive, disk, 1); | ||
670 | |||
671 | if (ide_floppy_get_capacity(drive) | ||
672 | && (filp->f_flags & O_NDELAY) == 0 | ||
673 | /* | ||
674 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
675 | * unreadable disk, so that we can get the format capacity | ||
676 | * of the drive or begin the format - Sam | ||
677 | */ | ||
678 | ) { | ||
679 | ret = -EIO; | ||
680 | goto out_put_floppy; | ||
681 | } | ||
682 | |||
683 | if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { | ||
684 | ret = -EROFS; | ||
685 | goto out_put_floppy; | ||
686 | } | ||
687 | |||
688 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | ||
689 | ide_set_media_lock(drive, disk, 1); | ||
690 | check_disk_change(inode->i_bdev); | ||
691 | } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { | ||
692 | ret = -EBUSY; | ||
693 | goto out_put_floppy; | ||
694 | } | ||
695 | return 0; | ||
696 | |||
697 | out_put_floppy: | ||
698 | floppy->openers--; | ||
699 | ide_floppy_put(floppy); | ||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | static int idefloppy_release(struct inode *inode, struct file *filp) | ||
704 | { | ||
705 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
706 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
707 | ide_drive_t *drive = floppy->drive; | ||
708 | |||
709 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
710 | |||
711 | if (floppy->openers == 1) { | ||
712 | ide_set_media_lock(drive, disk, 0); | ||
713 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
714 | } | ||
715 | |||
716 | floppy->openers--; | ||
717 | |||
718 | ide_floppy_put(floppy); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
724 | { | ||
725 | struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | ||
726 | ide_floppy_obj); | ||
727 | ide_drive_t *drive = floppy->drive; | ||
728 | 560 | ||
729 | geo->heads = drive->bios_head; | 561 | ret = ide_floppy_get_capacity(drive); |
730 | geo->sectors = drive->bios_sect; | ||
731 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
732 | return 0; | ||
733 | } | ||
734 | 562 | ||
735 | static int idefloppy_media_changed(struct gendisk *disk) | 563 | set_capacity(disk, ide_gd_capacity(drive)); |
736 | { | ||
737 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
738 | ide_drive_t *drive = floppy->drive; | ||
739 | int ret; | ||
740 | 564 | ||
741 | /* do not scan partitions twice if this is a removable device */ | ||
742 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | ||
743 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
744 | return 0; | ||
745 | } | ||
746 | ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); | ||
747 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | ||
748 | return ret; | 565 | return ret; |
749 | } | 566 | } |
750 | 567 | ||
751 | static int idefloppy_revalidate_disk(struct gendisk *disk) | 568 | const struct ide_disk_ops ide_atapi_disk_ops = { |
752 | { | 569 | .check = ide_check_atapi_device, |
753 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | 570 | .get_capacity = ide_floppy_get_capacity, |
754 | set_capacity(disk, ide_floppy_capacity(floppy->drive)); | 571 | .setup = ide_floppy_setup, |
755 | return 0; | 572 | .flush = ide_floppy_flush, |
756 | } | 573 | .init_media = ide_floppy_init_media, |
757 | 574 | .set_doorlock = ide_set_media_lock, | |
758 | static struct block_device_operations idefloppy_ops = { | 575 | .do_request = ide_floppy_do_request, |
759 | .owner = THIS_MODULE, | 576 | .end_request = ide_floppy_end_request, |
760 | .open = idefloppy_open, | 577 | .ioctl = ide_floppy_ioctl, |
761 | .release = idefloppy_release, | ||
762 | .ioctl = ide_floppy_ioctl, | ||
763 | .getgeo = idefloppy_getgeo, | ||
764 | .media_changed = idefloppy_media_changed, | ||
765 | .revalidate_disk = idefloppy_revalidate_disk | ||
766 | }; | 578 | }; |
767 | |||
768 | static int ide_floppy_probe(ide_drive_t *drive) | ||
769 | { | ||
770 | idefloppy_floppy_t *floppy; | ||
771 | struct gendisk *g; | ||
772 | |||
773 | if (!strstr("ide-floppy", drive->driver_req)) | ||
774 | goto failed; | ||
775 | |||
776 | if (drive->media != ide_floppy) | ||
777 | goto failed; | ||
778 | |||
779 | if (!ide_check_atapi_device(drive, DRV_NAME)) { | ||
780 | printk(KERN_ERR PFX "%s: not supported by this version of " | ||
781 | DRV_NAME "\n", drive->name); | ||
782 | goto failed; | ||
783 | } | ||
784 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); | ||
785 | if (!floppy) { | ||
786 | printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n", | ||
787 | drive->name); | ||
788 | goto failed; | ||
789 | } | ||
790 | |||
791 | g = alloc_disk(1 << PARTN_BITS); | ||
792 | if (!g) | ||
793 | goto out_free_floppy; | ||
794 | |||
795 | ide_init_disk(g, drive); | ||
796 | |||
797 | kref_init(&floppy->kref); | ||
798 | |||
799 | floppy->drive = drive; | ||
800 | floppy->driver = &idefloppy_driver; | ||
801 | floppy->disk = g; | ||
802 | |||
803 | g->private_data = &floppy->driver; | ||
804 | |||
805 | drive->driver_data = floppy; | ||
806 | |||
807 | drive->debug_mask = debug_mask; | ||
808 | |||
809 | idefloppy_setup(drive, floppy); | ||
810 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
811 | |||
812 | g->minors = 1 << PARTN_BITS; | ||
813 | g->driverfs_dev = &drive->gendev; | ||
814 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
815 | g->flags = GENHD_FL_REMOVABLE; | ||
816 | g->fops = &idefloppy_ops; | ||
817 | add_disk(g); | ||
818 | return 0; | ||
819 | |||
820 | out_free_floppy: | ||
821 | kfree(floppy); | ||
822 | failed: | ||
823 | return -ENODEV; | ||
824 | } | ||
825 | |||
826 | static void __exit idefloppy_exit(void) | ||
827 | { | ||
828 | driver_unregister(&idefloppy_driver.gen_driver); | ||
829 | } | ||
830 | |||
831 | static int __init idefloppy_init(void) | ||
832 | { | ||
833 | printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n"); | ||
834 | return driver_register(&idefloppy_driver.gen_driver); | ||
835 | } | ||
836 | |||
837 | MODULE_ALIAS("ide:*m-floppy*"); | ||
838 | MODULE_ALIAS("ide-floppy"); | ||
839 | module_init(idefloppy_init); | ||
840 | module_exit(idefloppy_exit); | ||
841 | MODULE_LICENSE("GPL"); | ||
842 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | ||
843 | |||
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h index 17cf865e583d..c17124dd6079 100644 --- a/drivers/ide/ide-floppy.h +++ b/drivers/ide/ide-floppy.h | |||
@@ -1,37 +1,9 @@ | |||
1 | #ifndef __IDE_FLOPPY_H | 1 | #ifndef __IDE_FLOPPY_H |
2 | #define __IDE_FLOPPY_H | 2 | #define __IDE_FLOPPY_H |
3 | 3 | ||
4 | /* | 4 | #include "ide-gd.h" |
5 | * Most of our global data which we need to save even as we leave the driver | ||
6 | * due to an interrupt or a timer event is stored in a variable of type | ||
7 | * idefloppy_floppy_t, defined below. | ||
8 | */ | ||
9 | typedef struct ide_floppy_obj { | ||
10 | ide_drive_t *drive; | ||
11 | ide_driver_t *driver; | ||
12 | struct gendisk *disk; | ||
13 | struct kref kref; | ||
14 | unsigned int openers; /* protected by BKL for now */ | ||
15 | |||
16 | /* Last failed packet command */ | ||
17 | struct ide_atapi_pc *failed_pc; | ||
18 | /* used for blk_{fs,pc}_request() requests */ | ||
19 | struct ide_atapi_pc queued_pc; | ||
20 | |||
21 | /* Last error information */ | ||
22 | u8 sense_key, asc, ascq; | ||
23 | |||
24 | int progress_indication; | ||
25 | |||
26 | /* Device information */ | ||
27 | /* Current format */ | ||
28 | int blocks, block_size, bs_factor; | ||
29 | /* Last format capacity descriptor */ | ||
30 | u8 cap_desc[8]; | ||
31 | /* Copy of the flexible disk page */ | ||
32 | u8 flexible_disk_page[32]; | ||
33 | } idefloppy_floppy_t; | ||
34 | 5 | ||
6 | #ifdef CONFIG_IDE_GD_ATAPI | ||
35 | /* | 7 | /* |
36 | * Pages of the SELECT SENSE / MODE SENSE packet commands. | 8 | * Pages of the SELECT SENSE / MODE SENSE packet commands. |
37 | * See SFF-8070i spec. | 9 | * See SFF-8070i spec. |
@@ -46,17 +18,22 @@ typedef struct ide_floppy_obj { | |||
46 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 | 18 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 |
47 | 19 | ||
48 | /* ide-floppy.c */ | 20 | /* ide-floppy.c */ |
21 | extern const struct ide_disk_ops ide_atapi_disk_ops; | ||
49 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); | 22 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); |
50 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); | 23 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); |
51 | sector_t ide_floppy_capacity(ide_drive_t *); | ||
52 | 24 | ||
53 | /* ide-floppy_ioctl.c */ | 25 | /* ide-floppy_ioctl.c */ |
54 | int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); | 26 | int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, |
27 | unsigned long); | ||
55 | 28 | ||
56 | #ifdef CONFIG_IDE_PROC_FS | 29 | #ifdef CONFIG_IDE_PROC_FS |
57 | /* ide-floppy_proc.c */ | 30 | /* ide-floppy_proc.c */ |
58 | extern ide_proc_entry_t ide_floppy_proc[]; | 31 | extern ide_proc_entry_t ide_floppy_proc[]; |
59 | extern const struct ide_proc_devset ide_floppy_settings[]; | 32 | extern const struct ide_proc_devset ide_floppy_settings[]; |
60 | #endif | 33 | #endif |
34 | #else | ||
35 | #define ide_floppy_proc NULL | ||
36 | #define ide_floppy_settings NULL | ||
37 | #endif | ||
61 | 38 | ||
62 | #endif /*__IDE_FLOPPY_H */ | 39 | #endif /*__IDE_FLOPPY_H */ |
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index a3a7a0809e2b..409e4c15f9b7 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | 34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) |
35 | { | 35 | { |
36 | struct ide_floppy_obj *floppy = drive->driver_data; | 36 | struct ide_disk_obj *floppy = drive->driver_data; |
37 | struct ide_atapi_pc pc; | 37 | struct ide_atapi_pc pc; |
38 | u8 header_len, desc_cnt; | 38 | u8 header_len, desc_cnt; |
39 | int i, blocks, length, u_array_size, u_index; | 39 | int i, blocks, length, u_array_size, u_index; |
@@ -113,7 +113,7 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, | |||
113 | 113 | ||
114 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) | 114 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) |
115 | { | 115 | { |
116 | idefloppy_floppy_t *floppy = drive->driver_data; | 116 | struct ide_disk_obj *floppy = drive->driver_data; |
117 | struct ide_atapi_pc pc; | 117 | struct ide_atapi_pc pc; |
118 | 118 | ||
119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; | 119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; |
@@ -132,17 +132,17 @@ static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) | |||
132 | 132 | ||
133 | static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | 133 | static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) |
134 | { | 134 | { |
135 | idefloppy_floppy_t *floppy = drive->driver_data; | 135 | struct ide_disk_obj *floppy = drive->driver_data; |
136 | struct ide_atapi_pc pc; | 136 | struct ide_atapi_pc pc; |
137 | int blocks, length, flags, err = 0; | 137 | int blocks, length, flags, err = 0; |
138 | 138 | ||
139 | if (floppy->openers > 1) { | 139 | if (floppy->openers > 1) { |
140 | /* Don't format if someone is using the disk */ | 140 | /* Don't format if someone is using the disk */ |
141 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | 141 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; |
142 | return -EBUSY; | 142 | return -EBUSY; |
143 | } | 143 | } |
144 | 144 | ||
145 | drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS; | 145 | drive->dev_flags |= IDE_DFLAG_FORMAT_IN_PROGRESS; |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * Send ATAPI_FORMAT_UNIT to the drive. | 148 | * Send ATAPI_FORMAT_UNIT to the drive. |
@@ -174,7 +174,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | |||
174 | 174 | ||
175 | out: | 175 | out: |
176 | if (err) | 176 | if (err) |
177 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | 177 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; |
178 | return err; | 178 | return err; |
179 | } | 179 | } |
180 | 180 | ||
@@ -190,7 +190,7 @@ out: | |||
190 | 190 | ||
191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) | 191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) |
192 | { | 192 | { |
193 | idefloppy_floppy_t *floppy = drive->driver_data; | 193 | struct ide_disk_obj *floppy = drive->driver_data; |
194 | struct ide_atapi_pc pc; | 194 | struct ide_atapi_pc pc; |
195 | int progress_indication = 0x10000; | 195 | int progress_indication = 0x10000; |
196 | 196 | ||
@@ -226,7 +226,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) | |||
226 | static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, | 226 | static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, |
227 | unsigned long arg, unsigned int cmd) | 227 | unsigned long arg, unsigned int cmd) |
228 | { | 228 | { |
229 | idefloppy_floppy_t *floppy = drive->driver_data; | 229 | struct ide_disk_obj *floppy = drive->driver_data; |
230 | struct gendisk *disk = floppy->disk; | 230 | struct gendisk *disk = floppy->disk; |
231 | int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; | 231 | int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; |
232 | 232 | ||
@@ -260,13 +260,10 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, | |||
260 | } | 260 | } |
261 | } | 261 | } |
262 | 262 | ||
263 | int ide_floppy_ioctl(struct inode *inode, struct file *file, | 263 | int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, |
264 | unsigned int cmd, unsigned long arg) | 264 | struct file *file, unsigned int cmd, unsigned long arg) |
265 | { | 265 | { |
266 | struct block_device *bdev = inode->i_bdev; | 266 | struct block_device *bdev = inode->i_bdev; |
267 | struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | ||
268 | ide_floppy_obj); | ||
269 | ide_drive_t *drive = floppy->drive; | ||
270 | struct ide_atapi_pc pc; | 267 | struct ide_atapi_pc pc; |
271 | void __user *argp = (void __user *)arg; | 268 | void __user *argp = (void __user *)arg; |
272 | int err; | 269 | int err; |
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c index 76f0c6c4eca3..3ec762cb60ab 100644 --- a/drivers/ide/ide-floppy_proc.c +++ b/drivers/ide/ide-floppy_proc.c | |||
@@ -9,7 +9,7 @@ static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, | |||
9 | ide_drive_t*drive = (ide_drive_t *)data; | 9 | ide_drive_t*drive = (ide_drive_t *)data; |
10 | int len; | 10 | int len; |
11 | 11 | ||
12 | len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive)); | 12 | len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); |
13 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 13 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
14 | } | 14 | } |
15 | 15 | ||
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c new file mode 100644 index 000000000000..d44898f46c33 --- /dev/null +++ b/drivers/ide/ide-gd.c | |||
@@ -0,0 +1,398 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/errno.h> | ||
6 | #include <linux/genhd.h> | ||
7 | #include <linux/mutex.h> | ||
8 | #include <linux/ide.h> | ||
9 | #include <linux/hdreg.h> | ||
10 | |||
11 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
12 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | ||
13 | #else | ||
14 | #define IDE_DISK_MINORS 0 | ||
15 | #endif | ||
16 | |||
17 | #include "ide-disk.h" | ||
18 | #include "ide-floppy.h" | ||
19 | |||
20 | #define IDE_GD_VERSION "1.18" | ||
21 | |||
22 | /* module parameters */ | ||
23 | static unsigned long debug_mask; | ||
24 | module_param(debug_mask, ulong, 0644); | ||
25 | |||
26 | static DEFINE_MUTEX(ide_disk_ref_mutex); | ||
27 | |||
28 | static void ide_disk_release(struct kref *); | ||
29 | |||
30 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | ||
31 | { | ||
32 | struct ide_disk_obj *idkp = NULL; | ||
33 | |||
34 | mutex_lock(&ide_disk_ref_mutex); | ||
35 | idkp = ide_drv_g(disk, ide_disk_obj); | ||
36 | if (idkp) { | ||
37 | if (ide_device_get(idkp->drive)) | ||
38 | idkp = NULL; | ||
39 | else | ||
40 | kref_get(&idkp->kref); | ||
41 | } | ||
42 | mutex_unlock(&ide_disk_ref_mutex); | ||
43 | return idkp; | ||
44 | } | ||
45 | |||
46 | static void ide_disk_put(struct ide_disk_obj *idkp) | ||
47 | { | ||
48 | ide_drive_t *drive = idkp->drive; | ||
49 | |||
50 | mutex_lock(&ide_disk_ref_mutex); | ||
51 | kref_put(&idkp->kref, ide_disk_release); | ||
52 | ide_device_put(drive); | ||
53 | mutex_unlock(&ide_disk_ref_mutex); | ||
54 | } | ||
55 | |||
56 | sector_t ide_gd_capacity(ide_drive_t *drive) | ||
57 | { | ||
58 | return drive->capacity64; | ||
59 | } | ||
60 | |||
61 | static int ide_gd_probe(ide_drive_t *); | ||
62 | |||
63 | static void ide_gd_remove(ide_drive_t *drive) | ||
64 | { | ||
65 | struct ide_disk_obj *idkp = drive->driver_data; | ||
66 | struct gendisk *g = idkp->disk; | ||
67 | |||
68 | ide_proc_unregister_driver(drive, idkp->driver); | ||
69 | |||
70 | del_gendisk(g); | ||
71 | |||
72 | drive->disk_ops->flush(drive); | ||
73 | |||
74 | ide_disk_put(idkp); | ||
75 | } | ||
76 | |||
77 | static void ide_disk_release(struct kref *kref) | ||
78 | { | ||
79 | struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); | ||
80 | ide_drive_t *drive = idkp->drive; | ||
81 | struct gendisk *g = idkp->disk; | ||
82 | |||
83 | drive->disk_ops = NULL; | ||
84 | drive->driver_data = NULL; | ||
85 | g->private_data = NULL; | ||
86 | put_disk(g); | ||
87 | kfree(idkp); | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * On HPA drives the capacity needs to be | ||
92 | * reinitilized on resume otherwise the disk | ||
93 | * can not be used and a hard reset is required | ||
94 | */ | ||
95 | static void ide_gd_resume(ide_drive_t *drive) | ||
96 | { | ||
97 | if (ata_id_hpa_enabled(drive->id)) | ||
98 | (void)drive->disk_ops->get_capacity(drive); | ||
99 | } | ||
100 | |||
101 | static void ide_gd_shutdown(ide_drive_t *drive) | ||
102 | { | ||
103 | #ifdef CONFIG_ALPHA | ||
104 | /* On Alpha, halt(8) doesn't actually turn the machine off, | ||
105 | it puts you into the sort of firmware monitor. Typically, | ||
106 | it's used to boot another kernel image, so it's not much | ||
107 | different from reboot(8). Therefore, we don't need to | ||
108 | spin down the disk in this case, especially since Alpha | ||
109 | firmware doesn't handle disks in standby mode properly. | ||
110 | On the other hand, it's reasonably safe to turn the power | ||
111 | off when the shutdown process reaches the firmware prompt, | ||
112 | as the firmware initialization takes rather long time - | ||
113 | at least 10 seconds, which should be sufficient for | ||
114 | the disk to expire its write cache. */ | ||
115 | if (system_state != SYSTEM_POWER_OFF) { | ||
116 | #else | ||
117 | if (system_state == SYSTEM_RESTART) { | ||
118 | #endif | ||
119 | drive->disk_ops->flush(drive); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | printk(KERN_INFO "Shutdown: %s\n", drive->name); | ||
124 | |||
125 | drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); | ||
126 | } | ||
127 | |||
128 | #ifdef CONFIG_IDE_PROC_FS | ||
129 | static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) | ||
130 | { | ||
131 | return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc; | ||
132 | } | ||
133 | |||
134 | static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) | ||
135 | { | ||
136 | return (drive->media == ide_disk) ? ide_disk_settings | ||
137 | : ide_floppy_settings; | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, | ||
142 | struct request *rq, sector_t sector) | ||
143 | { | ||
144 | return drive->disk_ops->do_request(drive, rq, sector); | ||
145 | } | ||
146 | |||
147 | static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) | ||
148 | { | ||
149 | return drive->disk_ops->end_request(drive, uptodate, nrsecs); | ||
150 | } | ||
151 | |||
152 | static ide_driver_t ide_gd_driver = { | ||
153 | .gen_driver = { | ||
154 | .owner = THIS_MODULE, | ||
155 | .name = "ide-gd", | ||
156 | .bus = &ide_bus_type, | ||
157 | }, | ||
158 | .probe = ide_gd_probe, | ||
159 | .remove = ide_gd_remove, | ||
160 | .resume = ide_gd_resume, | ||
161 | .shutdown = ide_gd_shutdown, | ||
162 | .version = IDE_GD_VERSION, | ||
163 | .do_request = ide_gd_do_request, | ||
164 | .end_request = ide_gd_end_request, | ||
165 | .error = __ide_error, | ||
166 | #ifdef CONFIG_IDE_PROC_FS | ||
167 | .proc_entries = ide_disk_proc_entries, | ||
168 | .proc_devsets = ide_disk_proc_devsets, | ||
169 | #endif | ||
170 | }; | ||
171 | |||
172 | static int ide_gd_open(struct inode *inode, struct file *filp) | ||
173 | { | ||
174 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
175 | struct ide_disk_obj *idkp; | ||
176 | ide_drive_t *drive; | ||
177 | int ret = 0; | ||
178 | |||
179 | idkp = ide_disk_get(disk); | ||
180 | if (idkp == NULL) | ||
181 | return -ENXIO; | ||
182 | |||
183 | drive = idkp->drive; | ||
184 | |||
185 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
186 | |||
187 | idkp->openers++; | ||
188 | |||
189 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
190 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | ||
191 | /* Just in case */ | ||
192 | |||
193 | ret = drive->disk_ops->init_media(drive, disk); | ||
194 | |||
195 | /* | ||
196 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
197 | * unreadable disk, so that we can get the format capacity | ||
198 | * of the drive or begin the format - Sam | ||
199 | */ | ||
200 | if (ret && (filp->f_flags & O_NDELAY) == 0) { | ||
201 | ret = -EIO; | ||
202 | goto out_put_idkp; | ||
203 | } | ||
204 | |||
205 | if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { | ||
206 | ret = -EROFS; | ||
207 | goto out_put_idkp; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Ignore the return code from door_lock, | ||
212 | * since the open() has already succeeded, | ||
213 | * and the door_lock is irrelevant at this point. | ||
214 | */ | ||
215 | drive->disk_ops->set_doorlock(drive, disk, 1); | ||
216 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | ||
217 | check_disk_change(inode->i_bdev); | ||
218 | } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { | ||
219 | ret = -EBUSY; | ||
220 | goto out_put_idkp; | ||
221 | } | ||
222 | return 0; | ||
223 | |||
224 | out_put_idkp: | ||
225 | idkp->openers--; | ||
226 | ide_disk_put(idkp); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int ide_gd_release(struct inode *inode, struct file *filp) | ||
231 | { | ||
232 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
233 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
234 | ide_drive_t *drive = idkp->drive; | ||
235 | |||
236 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
237 | |||
238 | if (idkp->openers == 1) | ||
239 | drive->disk_ops->flush(drive); | ||
240 | |||
241 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
242 | drive->disk_ops->set_doorlock(drive, disk, 0); | ||
243 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | ||
244 | } | ||
245 | |||
246 | idkp->openers--; | ||
247 | |||
248 | ide_disk_put(idkp); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
254 | { | ||
255 | struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | ||
256 | ide_drive_t *drive = idkp->drive; | ||
257 | |||
258 | geo->heads = drive->bios_head; | ||
259 | geo->sectors = drive->bios_sect; | ||
260 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int ide_gd_media_changed(struct gendisk *disk) | ||
265 | { | ||
266 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
267 | ide_drive_t *drive = idkp->drive; | ||
268 | int ret; | ||
269 | |||
270 | /* do not scan partitions twice if this is a removable device */ | ||
271 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | ||
272 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); | ||
277 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; | ||
278 | |||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static int ide_gd_revalidate_disk(struct gendisk *disk) | ||
283 | { | ||
284 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
285 | set_capacity(disk, ide_gd_capacity(idkp->drive)); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int ide_gd_ioctl(struct inode *inode, struct file *file, | ||
290 | unsigned int cmd, unsigned long arg) | ||
291 | { | ||
292 | struct block_device *bdev = inode->i_bdev; | ||
293 | struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | ||
294 | ide_drive_t *drive = idkp->drive; | ||
295 | |||
296 | return drive->disk_ops->ioctl(drive, inode, file, cmd, arg); | ||
297 | } | ||
298 | |||
299 | static struct block_device_operations ide_gd_ops = { | ||
300 | .owner = THIS_MODULE, | ||
301 | .open = ide_gd_open, | ||
302 | .release = ide_gd_release, | ||
303 | .ioctl = ide_gd_ioctl, | ||
304 | .getgeo = ide_gd_getgeo, | ||
305 | .media_changed = ide_gd_media_changed, | ||
306 | .revalidate_disk = ide_gd_revalidate_disk | ||
307 | }; | ||
308 | |||
309 | static int ide_gd_probe(ide_drive_t *drive) | ||
310 | { | ||
311 | const struct ide_disk_ops *disk_ops = NULL; | ||
312 | struct ide_disk_obj *idkp; | ||
313 | struct gendisk *g; | ||
314 | |||
315 | /* strstr("foo", "") is non-NULL */ | ||
316 | if (!strstr("ide-gd", drive->driver_req)) | ||
317 | goto failed; | ||
318 | |||
319 | #ifdef CONFIG_IDE_GD_ATA | ||
320 | if (drive->media == ide_disk) | ||
321 | disk_ops = &ide_ata_disk_ops; | ||
322 | #endif | ||
323 | #ifdef CONFIG_IDE_GD_ATAPI | ||
324 | if (drive->media == ide_floppy) | ||
325 | disk_ops = &ide_atapi_disk_ops; | ||
326 | #endif | ||
327 | if (disk_ops == NULL) | ||
328 | goto failed; | ||
329 | |||
330 | if (disk_ops->check(drive, DRV_NAME) == 0) { | ||
331 | printk(KERN_ERR PFX "%s: not supported by this driver\n", | ||
332 | drive->name); | ||
333 | goto failed; | ||
334 | } | ||
335 | |||
336 | idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); | ||
337 | if (!idkp) { | ||
338 | printk(KERN_ERR PFX "%s: can't allocate a disk structure\n", | ||
339 | drive->name); | ||
340 | goto failed; | ||
341 | } | ||
342 | |||
343 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); | ||
344 | if (!g) | ||
345 | goto out_free_idkp; | ||
346 | |||
347 | ide_init_disk(g, drive); | ||
348 | |||
349 | kref_init(&idkp->kref); | ||
350 | |||
351 | idkp->drive = drive; | ||
352 | idkp->driver = &ide_gd_driver; | ||
353 | idkp->disk = g; | ||
354 | |||
355 | g->private_data = &idkp->driver; | ||
356 | |||
357 | drive->driver_data = idkp; | ||
358 | drive->debug_mask = debug_mask; | ||
359 | drive->disk_ops = disk_ops; | ||
360 | |||
361 | disk_ops->setup(drive); | ||
362 | |||
363 | set_capacity(g, ide_gd_capacity(drive)); | ||
364 | |||
365 | g->minors = IDE_DISK_MINORS; | ||
366 | g->driverfs_dev = &drive->gendev; | ||
367 | g->flags |= GENHD_FL_EXT_DEVT; | ||
368 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
369 | g->flags = GENHD_FL_REMOVABLE; | ||
370 | g->fops = &ide_gd_ops; | ||
371 | add_disk(g); | ||
372 | return 0; | ||
373 | |||
374 | out_free_idkp: | ||
375 | kfree(idkp); | ||
376 | failed: | ||
377 | return -ENODEV; | ||
378 | } | ||
379 | |||
380 | static int __init ide_gd_init(void) | ||
381 | { | ||
382 | printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n"); | ||
383 | return driver_register(&ide_gd_driver.gen_driver); | ||
384 | } | ||
385 | |||
386 | static void __exit ide_gd_exit(void) | ||
387 | { | ||
388 | driver_unregister(&ide_gd_driver.gen_driver); | ||
389 | } | ||
390 | |||
391 | MODULE_ALIAS("ide:*m-disk*"); | ||
392 | MODULE_ALIAS("ide-disk"); | ||
393 | MODULE_ALIAS("ide:*m-floppy*"); | ||
394 | MODULE_ALIAS("ide-floppy"); | ||
395 | module_init(ide_gd_init); | ||
396 | module_exit(ide_gd_exit); | ||
397 | MODULE_LICENSE("GPL"); | ||
398 | MODULE_DESCRIPTION("generic ATA/ATAPI disk driver"); | ||
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h new file mode 100644 index 000000000000..7d3d101713e0 --- /dev/null +++ b/drivers/ide/ide-gd.h | |||
@@ -0,0 +1,44 @@ | |||
1 | #ifndef __IDE_GD_H | ||
2 | #define __IDE_GD_H | ||
3 | |||
4 | #define DRV_NAME "ide-gd" | ||
5 | #define PFX DRV_NAME ": " | ||
6 | |||
7 | /* define to see debug info */ | ||
8 | #define IDE_GD_DEBUG_LOG 0 | ||
9 | |||
10 | #if IDE_GD_DEBUG_LOG | ||
11 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
12 | #else | ||
13 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
14 | #endif | ||
15 | |||
16 | struct ide_disk_obj { | ||
17 | ide_drive_t *drive; | ||
18 | ide_driver_t *driver; | ||
19 | struct gendisk *disk; | ||
20 | struct kref kref; | ||
21 | unsigned int openers; /* protected by BKL for now */ | ||
22 | |||
23 | /* Last failed packet command */ | ||
24 | struct ide_atapi_pc *failed_pc; | ||
25 | /* used for blk_{fs,pc}_request() requests */ | ||
26 | struct ide_atapi_pc queued_pc; | ||
27 | |||
28 | /* Last error information */ | ||
29 | u8 sense_key, asc, ascq; | ||
30 | |||
31 | int progress_indication; | ||
32 | |||
33 | /* Device information */ | ||
34 | /* Current format */ | ||
35 | int blocks, block_size, bs_factor; | ||
36 | /* Last format capacity descriptor */ | ||
37 | u8 cap_desc[8]; | ||
38 | /* Copy of the flexible disk page */ | ||
39 | u8 flexible_disk_page[32]; | ||
40 | }; | ||
41 | |||
42 | sector_t ide_gd_capacity(ide_drive_t *); | ||
43 | |||
44 | #endif /* __IDE_GD_H */ | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index b762deb2dacb..bb7a1ed8094e 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -755,7 +755,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
755 | 755 | ||
756 | udelay(1); | 756 | udelay(1); |
757 | SELECT_DRIVE(drive); | 757 | SELECT_DRIVE(drive); |
758 | SELECT_MASK(drive, 0); | 758 | SELECT_MASK(drive, 1); |
759 | udelay(1); | 759 | udelay(1); |
760 | tp_ops->set_irq(hwif, 0); | 760 | tp_ops->set_irq(hwif, 0); |
761 | 761 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 19f8c7770a25..1649ea54f76c 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -208,6 +208,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
208 | drive->ready_stat = 0; | 208 | drive->ready_stat = 0; |
209 | if (ata_id_cdb_intr(id)) | 209 | if (ata_id_cdb_intr(id)) |
210 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; | 210 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; |
211 | drive->dev_flags |= IDE_DFLAG_DOORLOCKING; | ||
211 | /* we don't do head unloading on ATAPI devices */ | 212 | /* we don't do head unloading on ATAPI devices */ |
212 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | 213 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; |
213 | return; | 214 | return; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index b26926487cc0..c31d0dd7a532 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -567,10 +567,10 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t | |||
567 | void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) | 567 | void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) |
568 | { | 568 | { |
569 | mutex_lock(&ide_setting_mtx); | 569 | mutex_lock(&ide_setting_mtx); |
570 | drive->settings = driver->settings; | 570 | drive->settings = driver->proc_devsets(drive); |
571 | mutex_unlock(&ide_setting_mtx); | 571 | mutex_unlock(&ide_setting_mtx); |
572 | 572 | ||
573 | ide_add_proc_entries(drive->proc, driver->proc, drive); | 573 | ide_add_proc_entries(drive->proc, driver->proc_entries(drive), drive); |
574 | } | 574 | } |
575 | 575 | ||
576 | EXPORT_SYMBOL(ide_proc_register_driver); | 576 | EXPORT_SYMBOL(ide_proc_register_driver); |
@@ -591,7 +591,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) | |||
591 | { | 591 | { |
592 | unsigned long flags; | 592 | unsigned long flags; |
593 | 593 | ||
594 | ide_remove_proc_entries(drive->proc, driver->proc); | 594 | ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); |
595 | 595 | ||
596 | mutex_lock(&ide_setting_mtx); | 596 | mutex_lock(&ide_setting_mtx); |
597 | spin_lock_irqsave(&ide_lock, flags); | 597 | spin_lock_irqsave(&ide_lock, flags); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d879c7797cde..b2b2e5e8d38e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -2108,7 +2108,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) | |||
2108 | 2108 | ||
2109 | /* device lacks locking support according to capabilities page */ | 2109 | /* device lacks locking support according to capabilities page */ |
2110 | if ((caps[6] & 1) == 0) | 2110 | if ((caps[6] & 1) == 0) |
2111 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 2111 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
2112 | 2112 | ||
2113 | if (caps[7] & 0x02) | 2113 | if (caps[7] & 0x02) |
2114 | tape->blk_size = 512; | 2114 | tape->blk_size = 512; |
@@ -2298,6 +2298,16 @@ static ide_proc_entry_t idetape_proc[] = { | |||
2298 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, | 2298 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, |
2299 | { NULL, 0, NULL, NULL } | 2299 | { NULL, 0, NULL, NULL } |
2300 | }; | 2300 | }; |
2301 | |||
2302 | static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) | ||
2303 | { | ||
2304 | return idetape_proc; | ||
2305 | } | ||
2306 | |||
2307 | static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) | ||
2308 | { | ||
2309 | return idetape_settings; | ||
2310 | } | ||
2301 | #endif | 2311 | #endif |
2302 | 2312 | ||
2303 | static int ide_tape_probe(ide_drive_t *); | 2313 | static int ide_tape_probe(ide_drive_t *); |
@@ -2315,8 +2325,8 @@ static ide_driver_t idetape_driver = { | |||
2315 | .end_request = idetape_end_request, | 2325 | .end_request = idetape_end_request, |
2316 | .error = __ide_error, | 2326 | .error = __ide_error, |
2317 | #ifdef CONFIG_IDE_PROC_FS | 2327 | #ifdef CONFIG_IDE_PROC_FS |
2318 | .proc = idetape_proc, | 2328 | .proc_entries = ide_tape_proc_entries, |
2319 | .settings = idetape_settings, | 2329 | .proc_devsets = ide_tape_proc_devsets, |
2320 | #endif | 2330 | #endif |
2321 | }; | 2331 | }; |
2322 | 2332 | ||
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 02e6ee7d751d..ab44a1f5f5a9 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -11,7 +11,6 @@ obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o | |||
11 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o | 11 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o |
12 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o | 12 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o |
13 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o | 13 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o |
14 | obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o | ||
15 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o | 14 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o |
16 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o | 15 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o |
17 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o | 16 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index 8689a706f537..8f1b2d9f0513 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = { | |||
46 | .quirkproc = ide_undecoded_slave, | 46 | .quirkproc = ide_undecoded_slave, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static unsigned int delkin_cb_init_chipset(struct pci_dev *dev) | ||
50 | { | ||
51 | unsigned long base = pci_resource_start(dev, 0); | ||
52 | int i; | ||
53 | |||
54 | outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ | ||
55 | inb(base + 0x17); /* read status to clear interrupts */ | ||
56 | |||
57 | for (i = 0; i < sizeof(setup); ++i) { | ||
58 | if (setup[i]) | ||
59 | outb(setup[i], base + i); | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
49 | static const struct ide_port_info delkin_cb_port_info = { | 65 | static const struct ide_port_info delkin_cb_port_info = { |
50 | .port_ops = &delkin_cb_port_ops, | 66 | .port_ops = &delkin_cb_port_ops, |
51 | .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | | 67 | .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | |
52 | IDE_HFLAG_NO_DMA, | 68 | IDE_HFLAG_NO_DMA, |
69 | .init_chipset = delkin_cb_init_chipset, | ||
53 | }; | 70 | }; |
54 | 71 | ||
55 | static int __devinit | 72 | static int __devinit |
@@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
57 | { | 74 | { |
58 | struct ide_host *host; | 75 | struct ide_host *host; |
59 | unsigned long base; | 76 | unsigned long base; |
60 | int i, rc; | 77 | int rc; |
61 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 78 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
62 | 79 | ||
63 | rc = pci_enable_device(dev); | 80 | rc = pci_enable_device(dev); |
@@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
72 | return rc; | 89 | return rc; |
73 | } | 90 | } |
74 | base = pci_resource_start(dev, 0); | 91 | base = pci_resource_start(dev, 0); |
75 | outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ | 92 | |
76 | inb(base + 0x17); /* read status to clear interrupts */ | 93 | delkin_cb_init_chipset(dev); |
77 | for (i = 0; i < sizeof(setup); ++i) { | ||
78 | if (setup[i]) | ||
79 | outb(setup[i], base + i); | ||
80 | } | ||
81 | 94 | ||
82 | memset(&hw, 0, sizeof(hw)); | 95 | memset(&hw, 0, sizeof(hw)); |
83 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); | 96 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); |
@@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev) | |||
110 | pci_disable_device(dev); | 123 | pci_disable_device(dev); |
111 | } | 124 | } |
112 | 125 | ||
126 | #ifdef CONFIG_PM | ||
127 | static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state) | ||
128 | { | ||
129 | pci_save_state(dev); | ||
130 | pci_disable_device(dev); | ||
131 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int delkin_cb_resume(struct pci_dev *dev) | ||
137 | { | ||
138 | struct ide_host *host = pci_get_drvdata(dev); | ||
139 | int rc; | ||
140 | |||
141 | pci_set_power_state(dev, PCI_D0); | ||
142 | |||
143 | rc = pci_enable_device(dev); | ||
144 | if (rc) | ||
145 | return rc; | ||
146 | |||
147 | pci_restore_state(dev); | ||
148 | pci_set_master(dev); | ||
149 | |||
150 | if (host->init_chipset) | ||
151 | host->init_chipset(dev); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | #else | ||
156 | #define delkin_cb_suspend NULL | ||
157 | #define delkin_cb_resume NULL | ||
158 | #endif | ||
159 | |||
113 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { | 160 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { |
114 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 161 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
115 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 162 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
@@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = { | |||
122 | .id_table = delkin_cb_pci_tbl, | 169 | .id_table = delkin_cb_pci_tbl, |
123 | .probe = delkin_cb_probe, | 170 | .probe = delkin_cb_probe, |
124 | .remove = delkin_cb_remove, | 171 | .remove = delkin_cb_remove, |
172 | .suspend = delkin_cb_suspend, | ||
173 | .resume = delkin_cb_resume, | ||
125 | }; | 174 | }; |
126 | 175 | ||
127 | static int __init delkin_cb_init(void) | 176 | static int __init delkin_cb_init(void) |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c deleted file mode 100644 index fb1a3aa57f07..000000000000 --- a/drivers/ide/pci/hpt34x.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public License | ||
5 | * | ||
6 | * | ||
7 | * 00:12.0 Unknown mass storage controller: | ||
8 | * Triones Technologies, Inc. | ||
9 | * Unknown device 0003 (rev 01) | ||
10 | * | ||
11 | * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) | ||
12 | * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) | ||
13 | * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) | ||
14 | * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) | ||
15 | * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) | ||
16 | * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) | ||
17 | * | ||
18 | * ide-pci.c reference | ||
19 | * | ||
20 | * Since there are two cards that report almost identically, | ||
21 | * the only discernable difference is the values reported in pcicmd. | ||
22 | * Booting-BIOS card or HPT363 :: pcicmd == 0x07 | ||
23 | * Non-bootable card or HPT343 :: pcicmd == 0x05 | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/ide.h> | ||
34 | |||
35 | #define DRV_NAME "hpt34x" | ||
36 | |||
37 | #define HPT343_DEBUG_DRIVE_INFO 0 | ||
38 | |||
39 | static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed) | ||
40 | { | ||
41 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | ||
42 | u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; | ||
43 | u8 hi_speed, lo_speed; | ||
44 | |||
45 | hi_speed = speed >> 4; | ||
46 | lo_speed = speed & 0x0f; | ||
47 | |||
48 | if (hi_speed & 7) { | ||
49 | hi_speed = (hi_speed & 4) ? 0x01 : 0x10; | ||
50 | } else { | ||
51 | lo_speed <<= 5; | ||
52 | lo_speed >>= 5; | ||
53 | } | ||
54 | |||
55 | pci_read_config_dword(dev, 0x44, ®1); | ||
56 | pci_read_config_dword(dev, 0x48, ®2); | ||
57 | tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); | ||
58 | tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn))); | ||
59 | pci_write_config_dword(dev, 0x44, tmp1); | ||
60 | pci_write_config_dword(dev, 0x48, tmp2); | ||
61 | |||
62 | #if HPT343_DEBUG_DRIVE_INFO | ||
63 | printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ | ||
64 | " (0x%02x 0x%02x)\n", | ||
65 | drive->name, ide_xfer_verbose(speed), | ||
66 | drive->dn, reg1, tmp1, reg2, tmp2, | ||
67 | hi_speed, lo_speed); | ||
68 | #endif /* HPT343_DEBUG_DRIVE_INFO */ | ||
69 | } | ||
70 | |||
71 | static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
72 | { | ||
73 | hpt34x_set_mode(drive, XFER_PIO_0 + pio); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * If the BIOS does not set the IO base addaress to XX00, 343 will fail. | ||
78 | */ | ||
79 | #define HPT34X_PCI_INIT_REG 0x80 | ||
80 | |||
81 | static unsigned int init_chipset_hpt34x(struct pci_dev *dev) | ||
82 | { | ||
83 | int i = 0; | ||
84 | unsigned long hpt34xIoBase = pci_resource_start(dev, 4); | ||
85 | unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c }; | ||
86 | unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 }; | ||
87 | u16 cmd; | ||
88 | unsigned long flags; | ||
89 | |||
90 | local_irq_save(flags); | ||
91 | |||
92 | pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); | ||
93 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
94 | |||
95 | if (cmd & PCI_COMMAND_MEMORY) | ||
96 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); | ||
97 | else | ||
98 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); | ||
99 | |||
100 | /* | ||
101 | * Since 20-23 can be assigned and are R/W, we correct them. | ||
102 | */ | ||
103 | pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); | ||
104 | for(i=0; i<4; i++) { | ||
105 | dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]); | ||
106 | dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i]; | ||
107 | dev->resource[i].flags = IORESOURCE_IO; | ||
108 | pci_write_config_dword(dev, | ||
109 | (PCI_BASE_ADDRESS_0 + (i * 4)), | ||
110 | dev->resource[i].start); | ||
111 | } | ||
112 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
113 | |||
114 | local_irq_restore(flags); | ||
115 | |||
116 | return dev->irq; | ||
117 | } | ||
118 | |||
119 | static const struct ide_port_ops hpt34x_port_ops = { | ||
120 | .set_pio_mode = hpt34x_set_pio_mode, | ||
121 | .set_dma_mode = hpt34x_set_mode, | ||
122 | }; | ||
123 | |||
124 | #define IDE_HFLAGS_HPT34X \ | ||
125 | (IDE_HFLAG_NO_ATAPI_DMA | \ | ||
126 | IDE_HFLAG_NO_DSC | \ | ||
127 | IDE_HFLAG_NO_AUTODMA) | ||
128 | |||
129 | static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { | ||
130 | { /* 0: HPT343 */ | ||
131 | .name = DRV_NAME, | ||
132 | .init_chipset = init_chipset_hpt34x, | ||
133 | .port_ops = &hpt34x_port_ops, | ||
134 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE, | ||
135 | .pio_mask = ATA_PIO5, | ||
136 | }, | ||
137 | { /* 1: HPT345 */ | ||
138 | .name = DRV_NAME, | ||
139 | .init_chipset = init_chipset_hpt34x, | ||
140 | .port_ops = &hpt34x_port_ops, | ||
141 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD, | ||
142 | .pio_mask = ATA_PIO5, | ||
143 | #ifdef CONFIG_HPT34X_AUTODMA | ||
144 | .swdma_mask = ATA_SWDMA2, | ||
145 | .mwdma_mask = ATA_MWDMA2, | ||
146 | .udma_mask = ATA_UDMA2, | ||
147 | #endif | ||
148 | } | ||
149 | }; | ||
150 | |||
151 | static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
152 | { | ||
153 | const struct ide_port_info *d; | ||
154 | u16 pcicmd = 0; | ||
155 | |||
156 | pci_read_config_word(dev, PCI_COMMAND, &pcicmd); | ||
157 | |||
158 | d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; | ||
159 | |||
160 | return ide_pci_init_one(dev, d, NULL); | ||
161 | } | ||
162 | |||
163 | static const struct pci_device_id hpt34x_pci_tbl[] = { | ||
164 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 }, | ||
165 | { 0, }, | ||
166 | }; | ||
167 | MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl); | ||
168 | |||
169 | static struct pci_driver hpt34x_pci_driver = { | ||
170 | .name = "HPT34x_IDE", | ||
171 | .id_table = hpt34x_pci_tbl, | ||
172 | .probe = hpt34x_init_one, | ||
173 | .remove = ide_pci_remove, | ||
174 | .suspend = ide_pci_suspend, | ||
175 | .resume = ide_pci_resume, | ||
176 | }; | ||
177 | |||
178 | static int __init hpt34x_ide_init(void) | ||
179 | { | ||
180 | return ide_pci_register_driver(&hpt34x_pci_driver); | ||
181 | } | ||
182 | |||
183 | static void __exit hpt34x_ide_exit(void) | ||
184 | { | ||
185 | pci_unregister_driver(&hpt34x_pci_driver); | ||
186 | } | ||
187 | |||
188 | module_init(hpt34x_ide_init); | ||
189 | module_exit(hpt34x_ide_exit); | ||
190 | |||
191 | MODULE_AUTHOR("Andre Hedrick"); | ||
192 | MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE"); | ||
193 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 9cf171cb9376..a7909e9c720e 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
4 | * Portions Copyright (C) 2003 Red Hat Inc | 4 | * Portions Copyright (C) 2003 Red Hat Inc |
5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz |
6 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. | 6 | * Portions Copyright (C) 2005-2008 MontaVista Software, Inc. |
7 | * | 7 | * |
8 | * Thanks to HighPoint Technologies for their assistance, and hardware. | 8 | * Thanks to HighPoint Technologies for their assistance, and hardware. |
9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his | 9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his |
@@ -748,26 +748,24 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) | |||
748 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 748 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
749 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 749 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
750 | 750 | ||
751 | if (drive->quirk_list) { | 751 | if (drive->quirk_list == 0) |
752 | if (info->chip_type >= HPT370) { | 752 | return; |
753 | u8 scr1 = 0; | 753 | |
754 | 754 | if (info->chip_type >= HPT370) { | |
755 | pci_read_config_byte(dev, 0x5a, &scr1); | 755 | u8 scr1 = 0; |
756 | if (((scr1 & 0x10) >> 4) != mask) { | 756 | |
757 | if (mask) | 757 | pci_read_config_byte(dev, 0x5a, &scr1); |
758 | scr1 |= 0x10; | 758 | if (((scr1 & 0x10) >> 4) != mask) { |
759 | else | ||
760 | scr1 &= ~0x10; | ||
761 | pci_write_config_byte(dev, 0x5a, scr1); | ||
762 | } | ||
763 | } else { | ||
764 | if (mask) | 759 | if (mask) |
765 | disable_irq(hwif->irq); | 760 | scr1 |= 0x10; |
766 | else | 761 | else |
767 | enable_irq (hwif->irq); | 762 | scr1 &= ~0x10; |
763 | pci_write_config_byte(dev, 0x5a, scr1); | ||
768 | } | 764 | } |
769 | } else | 765 | } else if (mask) |
770 | outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr); | 766 | disable_irq(hwif->irq); |
767 | else | ||
768 | enable_irq(hwif->irq); | ||
771 | } | 769 | } |
772 | 770 | ||
773 | /* | 771 | /* |
@@ -1289,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) | |||
1289 | 1287 | ||
1290 | static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) | 1288 | static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) |
1291 | { | 1289 | { |
1292 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
1293 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 1290 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
1294 | int serialize = HPT_SERIALIZE_IO; | 1291 | int serialize = HPT_SERIALIZE_IO; |
1295 | u8 chip_type = info->chip_type; | 1292 | u8 chip_type = info->chip_type; |
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 9ce1d8059921..49f163aa51e3 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c | |||
@@ -617,7 +617,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, | |||
617 | unsigned long intmask_port; | 617 | unsigned long intmask_port; |
618 | unsigned long mode_port; | 618 | unsigned long mode_port; |
619 | unsigned long ecmode_port; | 619 | unsigned long ecmode_port; |
620 | unsigned long dma_status_port; | ||
621 | u32 reg = 0; | 620 | u32 reg = 0; |
622 | struct scc_ports *ports; | 621 | struct scc_ports *ports; |
623 | int rc; | 622 | int rc; |
@@ -637,7 +636,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, | |||
637 | intmask_port = dma_base + 0x010; | 636 | intmask_port = dma_base + 0x010; |
638 | mode_port = ctl_base + 0x024; | 637 | mode_port = ctl_base + 0x024; |
639 | ecmode_port = ctl_base + 0xf00; | 638 | ecmode_port = ctl_base + 0xf00; |
640 | dma_status_port = dma_base + 0x004; | ||
641 | 639 | ||
642 | /* controller initialization */ | 640 | /* controller initialization */ |
643 | reg = 0; | 641 | reg = 0; |
@@ -843,8 +841,6 @@ static u8 scc_cable_detect(ide_hwif_t *hwif) | |||
843 | 841 | ||
844 | static void __devinit init_hwif_scc(ide_hwif_t *hwif) | 842 | static void __devinit init_hwif_scc(ide_hwif_t *hwif) |
845 | { | 843 | { |
846 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
847 | |||
848 | /* PTERADD */ | 844 | /* PTERADD */ |
849 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); | 845 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); |
850 | 846 | ||
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index dd634541ce36..8af9b23499fd 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -101,18 +101,8 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, | |||
101 | for (i = 0; i <= 7; i++) | 101 | for (i = 0; i <= 7; i++) |
102 | hw->io_ports_array[i] = reg + i * 4; | 102 | hw->io_ports_array[i] = reg + i * 4; |
103 | 103 | ||
104 | if (ctrl_port) | 104 | hw->io_ports.ctl_addr = ctrl_port; |
105 | hw->io_ports.ctl_addr = ctrl_port; | 105 | hw->io_ports.irq_addr = irq_port; |
106 | |||
107 | if (irq_port) | ||
108 | hw->io_ports.irq_addr = irq_port; | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | sgiioc4_maskproc(ide_drive_t * drive, int mask) | ||
113 | { | ||
114 | writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0), | ||
115 | (void __iomem *)drive->hwif->io_ports.ctl_addr); | ||
116 | } | 106 | } |
117 | 107 | ||
118 | static int | 108 | static int |
@@ -310,16 +300,14 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif) | |||
310 | unsigned long port = hwif->io_ports.status_addr; | 300 | unsigned long port = hwif->io_ports.status_addr; |
311 | u8 reg = (u8) readb((void __iomem *) port); | 301 | u8 reg = (u8) readb((void __iomem *) port); |
312 | 302 | ||
313 | if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */ | 303 | if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ |
314 | if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ | 304 | unsigned long other_ir = port - 0x110; |
315 | unsigned long other_ir = port - 0x110; | 305 | unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); |
316 | unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); | ||
317 | 306 | ||
318 | /* Clear the Interrupt, Error bits on the IOC4 */ | 307 | /* Clear the Interrupt, Error bits on the IOC4 */ |
319 | if (intr_reg & 0x03) { | 308 | if (intr_reg & 0x03) { |
320 | writel(0x03, (void __iomem *) other_ir); | 309 | writel(0x03, (void __iomem *) other_ir); |
321 | intr_reg = (u32) readl((void __iomem *) other_ir); | 310 | intr_reg = (u32) readl((void __iomem *) other_ir); |
322 | } | ||
323 | } | 311 | } |
324 | } | 312 | } |
325 | 313 | ||
@@ -332,13 +320,9 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
332 | { | 320 | { |
333 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 321 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
334 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; | 322 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; |
335 | void __iomem *virt_dma_base; | ||
336 | int num_ports = sizeof (ioc4_dma_regs_t); | 323 | int num_ports = sizeof (ioc4_dma_regs_t); |
337 | void *pad; | 324 | void *pad; |
338 | 325 | ||
339 | if (dma_base == 0) | ||
340 | return -1; | ||
341 | |||
342 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); | 326 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); |
343 | 327 | ||
344 | if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { | 328 | if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { |
@@ -348,14 +332,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
348 | return -1; | 332 | return -1; |
349 | } | 333 | } |
350 | 334 | ||
351 | virt_dma_base = ioremap(dma_base, num_ports); | 335 | hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr + |
352 | if (virt_dma_base == NULL) { | 336 | IOC4_DMA_OFFSET; |
353 | printk(KERN_ERR "%s(%s) -- ERROR: unable to map addresses " | ||
354 | "0x%lx to 0x%lx\n", __func__, hwif->name, | ||
355 | dma_base, dma_base + num_ports - 1); | ||
356 | goto dma_remap_failure; | ||
357 | } | ||
358 | hwif->dma_base = (unsigned long) virt_dma_base; | ||
359 | 337 | ||
360 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; | 338 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; |
361 | 339 | ||
@@ -379,9 +357,6 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
379 | printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); | 357 | printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); |
380 | 358 | ||
381 | dma_pci_alloc_failure: | 359 | dma_pci_alloc_failure: |
382 | iounmap(virt_dma_base); | ||
383 | |||
384 | dma_remap_failure: | ||
385 | release_mem_region(dma_base, num_ports); | 360 | release_mem_region(dma_base, num_ports); |
386 | 361 | ||
387 | return -1; | 362 | return -1; |
@@ -563,8 +538,6 @@ static const struct ide_port_ops sgiioc4_port_ops = { | |||
563 | .set_dma_mode = sgiioc4_set_dma_mode, | 538 | .set_dma_mode = sgiioc4_set_dma_mode, |
564 | /* reset DMA engine, clear IRQs */ | 539 | /* reset DMA engine, clear IRQs */ |
565 | .resetproc = sgiioc4_resetproc, | 540 | .resetproc = sgiioc4_resetproc, |
566 | /* mask on/off NIEN register */ | ||
567 | .maskproc = sgiioc4_maskproc, | ||
568 | }; | 541 | }; |
569 | 542 | ||
570 | static const struct ide_dma_ops sgiioc4_dma_ops = { | 543 | static const struct ide_dma_ops sgiioc4_dma_ops = { |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e3e40427e00e..c7ff1e11ea85 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -179,7 +179,7 @@ config LEDS_TRIGGER_TIMER | |||
179 | 179 | ||
180 | config LEDS_TRIGGER_IDE_DISK | 180 | config LEDS_TRIGGER_IDE_DISK |
181 | bool "LED IDE Disk Trigger" | 181 | bool "LED IDE Disk Trigger" |
182 | depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK | 182 | depends on LEDS_TRIGGERS && IDE_GD_ATA |
183 | help | 183 | help |
184 | This allows LEDs to be controlled by IDE disk activity. | 184 | This allows LEDs to be controlled by IDE disk activity. |
185 | If unsure, say Y. | 185 | If unsure, say Y. |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index ba5aa2008273..e4c0db4dc7b1 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -123,7 +123,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
123 | irqnr = asic->irq_base + | 123 | irqnr = asic->irq_base + |
124 | (ASIC3_GPIOS_PER_BANK * bank) | 124 | (ASIC3_GPIOS_PER_BANK * bank) |
125 | + i; | 125 | + i; |
126 | desc = irq_desc + irqnr; | 126 | desc = irq_to_desc(irqnr); |
127 | desc->handle_irq(irqnr, desc); | 127 | desc->handle_irq(irqnr, desc); |
128 | if (asic->irq_bothedge[bank] & bit) | 128 | if (asic->irq_bothedge[bank] & bit) |
129 | asic3_irq_flip_edge(asic, base, | 129 | asic3_irq_flip_edge(asic, base, |
@@ -136,7 +136,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { | 136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
137 | /* They start at bit 4 and go up */ | 137 | /* They start at bit 4 and go up */ |
138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | 138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { |
139 | desc = irq_desc + asic->irq_base + i; | 139 | desc = irq_to_desc(asic->irq_base + i); |
140 | desc->handle_irq(asic->irq_base + i, | 140 | desc->handle_irq(asic->irq_base + i, |
141 | desc); | 141 | desc); |
142 | } | 142 | } |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 50dff6e0088d..1a4d04664d6d 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
@@ -112,7 +112,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc) | |||
112 | /* Run irq handler */ | 112 | /* Run irq handler */ |
113 | pr_debug("got IRQ %d\n", irqpin); | 113 | pr_debug("got IRQ %d\n", irqpin); |
114 | irq = ei->irq_start + irqpin; | 114 | irq = ei->irq_start + irqpin; |
115 | desc = &irq_desc[irq]; | 115 | desc = irq_to_desc(irq); |
116 | desc->handle_irq(irq, desc); | 116 | desc->handle_irq(irq, desc); |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 406989e992ba..7a72e75d5c67 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -132,6 +132,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
132 | 132 | ||
133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); | 133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); |
134 | blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); | 134 | blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); |
135 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); | ||
135 | 136 | ||
136 | #ifdef CONFIG_MMC_BLOCK_BOUNCE | 137 | #ifdef CONFIG_MMC_BLOCK_BOUNCE |
137 | if (host->max_hw_segs == 1) { | 138 | if (host->max_hw_segs == 1) { |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index ae16d845d746..3b2085b57769 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> | 4 | * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> |
5 | * | 5 | * |
6 | * Current driver maintained by Ben Dooks and Simtec Electronics | ||
7 | * Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org> | ||
8 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
@@ -13,6 +16,7 @@ | |||
13 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
14 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
15 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/cpufreq.h> | ||
16 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
17 | #include <linux/io.h> | 21 | #include <linux/io.h> |
18 | 22 | ||
@@ -39,9 +43,9 @@ enum dbg_channels { | |||
39 | dbg_conf = (1 << 8), | 43 | dbg_conf = (1 << 8), |
40 | }; | 44 | }; |
41 | 45 | ||
42 | static const int dbgmap_err = dbg_err | dbg_fail; | 46 | static const int dbgmap_err = dbg_fail; |
43 | static const int dbgmap_info = dbg_info | dbg_conf; | 47 | static const int dbgmap_info = dbg_info | dbg_conf; |
44 | static const int dbgmap_debug = dbg_debug; | 48 | static const int dbgmap_debug = dbg_err | dbg_debug; |
45 | 49 | ||
46 | #define dbg(host, channels, args...) \ | 50 | #define dbg(host, channels, args...) \ |
47 | do { \ | 51 | do { \ |
@@ -189,7 +193,7 @@ static inline void clear_imask(struct s3cmci_host *host) | |||
189 | } | 193 | } |
190 | 194 | ||
191 | static inline int get_data_buffer(struct s3cmci_host *host, | 195 | static inline int get_data_buffer(struct s3cmci_host *host, |
192 | u32 *words, u32 **pointer) | 196 | u32 *bytes, u32 **pointer) |
193 | { | 197 | { |
194 | struct scatterlist *sg; | 198 | struct scatterlist *sg; |
195 | 199 | ||
@@ -206,7 +210,7 @@ static inline int get_data_buffer(struct s3cmci_host *host, | |||
206 | } | 210 | } |
207 | sg = &host->mrq->data->sg[host->pio_sgptr]; | 211 | sg = &host->mrq->data->sg[host->pio_sgptr]; |
208 | 212 | ||
209 | *words = sg->length >> 2; | 213 | *bytes = sg->length; |
210 | *pointer = sg_virt(sg); | 214 | *pointer = sg_virt(sg); |
211 | 215 | ||
212 | host->pio_sgptr++; | 216 | host->pio_sgptr++; |
@@ -222,7 +226,7 @@ static inline u32 fifo_count(struct s3cmci_host *host) | |||
222 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); | 226 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); |
223 | 227 | ||
224 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; | 228 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; |
225 | return fifostat >> 2; | 229 | return fifostat; |
226 | } | 230 | } |
227 | 231 | ||
228 | static inline u32 fifo_free(struct s3cmci_host *host) | 232 | static inline u32 fifo_free(struct s3cmci_host *host) |
@@ -230,13 +234,15 @@ static inline u32 fifo_free(struct s3cmci_host *host) | |||
230 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); | 234 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); |
231 | 235 | ||
232 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; | 236 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; |
233 | return (63 - fifostat) >> 2; | 237 | return 63 - fifostat; |
234 | } | 238 | } |
235 | 239 | ||
236 | static void do_pio_read(struct s3cmci_host *host) | 240 | static void do_pio_read(struct s3cmci_host *host) |
237 | { | 241 | { |
238 | int res; | 242 | int res; |
239 | u32 fifo; | 243 | u32 fifo; |
244 | u32 *ptr; | ||
245 | u32 fifo_words; | ||
240 | void __iomem *from_ptr; | 246 | void __iomem *from_ptr; |
241 | 247 | ||
242 | /* write real prescaler to host, it might be set slow to fix */ | 248 | /* write real prescaler to host, it might be set slow to fix */ |
@@ -245,8 +251,8 @@ static void do_pio_read(struct s3cmci_host *host) | |||
245 | from_ptr = host->base + host->sdidata; | 251 | from_ptr = host->base + host->sdidata; |
246 | 252 | ||
247 | while ((fifo = fifo_count(host))) { | 253 | while ((fifo = fifo_count(host))) { |
248 | if (!host->pio_words) { | 254 | if (!host->pio_bytes) { |
249 | res = get_data_buffer(host, &host->pio_words, | 255 | res = get_data_buffer(host, &host->pio_bytes, |
250 | &host->pio_ptr); | 256 | &host->pio_ptr); |
251 | if (res) { | 257 | if (res) { |
252 | host->pio_active = XFER_NONE; | 258 | host->pio_active = XFER_NONE; |
@@ -259,26 +265,47 @@ static void do_pio_read(struct s3cmci_host *host) | |||
259 | 265 | ||
260 | dbg(host, dbg_pio, | 266 | dbg(host, dbg_pio, |
261 | "pio_read(): new target: [%i]@[%p]\n", | 267 | "pio_read(): new target: [%i]@[%p]\n", |
262 | host->pio_words, host->pio_ptr); | 268 | host->pio_bytes, host->pio_ptr); |
263 | } | 269 | } |
264 | 270 | ||
265 | dbg(host, dbg_pio, | 271 | dbg(host, dbg_pio, |
266 | "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", | 272 | "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", |
267 | fifo, host->pio_words, | 273 | fifo, host->pio_bytes, |
268 | readl(host->base + S3C2410_SDIDCNT)); | 274 | readl(host->base + S3C2410_SDIDCNT)); |
269 | 275 | ||
270 | if (fifo > host->pio_words) | 276 | /* If we have reached the end of the block, we can |
271 | fifo = host->pio_words; | 277 | * read a word and get 1 to 3 bytes. If we in the |
278 | * middle of the block, we have to read full words, | ||
279 | * otherwise we will write garbage, so round down to | ||
280 | * an even multiple of 4. */ | ||
281 | if (fifo >= host->pio_bytes) | ||
282 | fifo = host->pio_bytes; | ||
283 | else | ||
284 | fifo -= fifo & 3; | ||
272 | 285 | ||
273 | host->pio_words -= fifo; | 286 | host->pio_bytes -= fifo; |
274 | host->pio_count += fifo; | 287 | host->pio_count += fifo; |
275 | 288 | ||
276 | while (fifo--) | 289 | fifo_words = fifo >> 2; |
277 | *(host->pio_ptr++) = readl(from_ptr); | 290 | ptr = host->pio_ptr; |
291 | while (fifo_words--) | ||
292 | *ptr++ = readl(from_ptr); | ||
293 | host->pio_ptr = ptr; | ||
294 | |||
295 | if (fifo & 3) { | ||
296 | u32 n = fifo & 3; | ||
297 | u32 data = readl(from_ptr); | ||
298 | u8 *p = (u8 *)host->pio_ptr; | ||
299 | |||
300 | while (n--) { | ||
301 | *p++ = data; | ||
302 | data >>= 8; | ||
303 | } | ||
304 | } | ||
278 | } | 305 | } |
279 | 306 | ||
280 | if (!host->pio_words) { | 307 | if (!host->pio_bytes) { |
281 | res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); | 308 | res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr); |
282 | if (res) { | 309 | if (res) { |
283 | dbg(host, dbg_pio, | 310 | dbg(host, dbg_pio, |
284 | "pio_read(): complete (no more buffers).\n"); | 311 | "pio_read(): complete (no more buffers).\n"); |
@@ -298,12 +325,13 @@ static void do_pio_write(struct s3cmci_host *host) | |||
298 | void __iomem *to_ptr; | 325 | void __iomem *to_ptr; |
299 | int res; | 326 | int res; |
300 | u32 fifo; | 327 | u32 fifo; |
328 | u32 *ptr; | ||
301 | 329 | ||
302 | to_ptr = host->base + host->sdidata; | 330 | to_ptr = host->base + host->sdidata; |
303 | 331 | ||
304 | while ((fifo = fifo_free(host))) { | 332 | while ((fifo = fifo_free(host))) { |
305 | if (!host->pio_words) { | 333 | if (!host->pio_bytes) { |
306 | res = get_data_buffer(host, &host->pio_words, | 334 | res = get_data_buffer(host, &host->pio_bytes, |
307 | &host->pio_ptr); | 335 | &host->pio_ptr); |
308 | if (res) { | 336 | if (res) { |
309 | dbg(host, dbg_pio, | 337 | dbg(host, dbg_pio, |
@@ -315,18 +343,27 @@ static void do_pio_write(struct s3cmci_host *host) | |||
315 | 343 | ||
316 | dbg(host, dbg_pio, | 344 | dbg(host, dbg_pio, |
317 | "pio_write(): new source: [%i]@[%p]\n", | 345 | "pio_write(): new source: [%i]@[%p]\n", |
318 | host->pio_words, host->pio_ptr); | 346 | host->pio_bytes, host->pio_ptr); |
319 | 347 | ||
320 | } | 348 | } |
321 | 349 | ||
322 | if (fifo > host->pio_words) | 350 | /* If we have reached the end of the block, we have to |
323 | fifo = host->pio_words; | 351 | * write exactly the remaining number of bytes. If we |
352 | * in the middle of the block, we have to write full | ||
353 | * words, so round down to an even multiple of 4. */ | ||
354 | if (fifo >= host->pio_bytes) | ||
355 | fifo = host->pio_bytes; | ||
356 | else | ||
357 | fifo -= fifo & 3; | ||
324 | 358 | ||
325 | host->pio_words -= fifo; | 359 | host->pio_bytes -= fifo; |
326 | host->pio_count += fifo; | 360 | host->pio_count += fifo; |
327 | 361 | ||
362 | fifo = (fifo + 3) >> 2; | ||
363 | ptr = host->pio_ptr; | ||
328 | while (fifo--) | 364 | while (fifo--) |
329 | writel(*(host->pio_ptr++), to_ptr); | 365 | writel(*ptr++, to_ptr); |
366 | host->pio_ptr = ptr; | ||
330 | } | 367 | } |
331 | 368 | ||
332 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); | 369 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); |
@@ -349,9 +386,9 @@ static void pio_tasklet(unsigned long data) | |||
349 | clear_imask(host); | 386 | clear_imask(host); |
350 | if (host->pio_active != XFER_NONE) { | 387 | if (host->pio_active != XFER_NONE) { |
351 | dbg(host, dbg_err, "unfinished %s " | 388 | dbg(host, dbg_err, "unfinished %s " |
352 | "- pio_count:[%u] pio_words:[%u]\n", | 389 | "- pio_count:[%u] pio_bytes:[%u]\n", |
353 | (host->pio_active == XFER_READ) ? "read" : "write", | 390 | (host->pio_active == XFER_READ) ? "read" : "write", |
354 | host->pio_count, host->pio_words); | 391 | host->pio_count, host->pio_bytes); |
355 | 392 | ||
356 | if (host->mrq->data) | 393 | if (host->mrq->data) |
357 | host->mrq->data->error = -EINVAL; | 394 | host->mrq->data->error = -EINVAL; |
@@ -812,11 +849,10 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) | |||
812 | /* We cannot deal with unaligned blocks with more than | 849 | /* We cannot deal with unaligned blocks with more than |
813 | * one block being transfered. */ | 850 | * one block being transfered. */ |
814 | 851 | ||
815 | if (data->blocks > 1) | 852 | if (data->blocks > 1) { |
853 | pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz); | ||
816 | return -EINVAL; | 854 | return -EINVAL; |
817 | 855 | } | |
818 | /* No support yet for non-word block transfers. */ | ||
819 | return -EINVAL; | ||
820 | } | 856 | } |
821 | 857 | ||
822 | while (readl(host->base + S3C2410_SDIDSTA) & | 858 | while (readl(host->base + S3C2410_SDIDSTA) & |
@@ -896,7 +932,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data) | |||
896 | BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); | 932 | BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); |
897 | 933 | ||
898 | host->pio_sgptr = 0; | 934 | host->pio_sgptr = 0; |
899 | host->pio_words = 0; | 935 | host->pio_bytes = 0; |
900 | host->pio_count = 0; | 936 | host->pio_count = 0; |
901 | host->pio_active = rw ? XFER_WRITE : XFER_READ; | 937 | host->pio_active = rw ? XFER_WRITE : XFER_READ; |
902 | 938 | ||
@@ -1033,10 +1069,33 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1033 | s3cmci_send_request(mmc); | 1069 | s3cmci_send_request(mmc); |
1034 | } | 1070 | } |
1035 | 1071 | ||
1072 | static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios) | ||
1073 | { | ||
1074 | u32 mci_psc; | ||
1075 | |||
1076 | /* Set clock */ | ||
1077 | for (mci_psc = 0; mci_psc < 255; mci_psc++) { | ||
1078 | host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); | ||
1079 | |||
1080 | if (host->real_rate <= ios->clock) | ||
1081 | break; | ||
1082 | } | ||
1083 | |||
1084 | if (mci_psc > 255) | ||
1085 | mci_psc = 255; | ||
1086 | |||
1087 | host->prescaler = mci_psc; | ||
1088 | writel(host->prescaler, host->base + S3C2410_SDIPRE); | ||
1089 | |||
1090 | /* If requested clock is 0, real_rate will be 0, too */ | ||
1091 | if (ios->clock == 0) | ||
1092 | host->real_rate = 0; | ||
1093 | } | ||
1094 | |||
1036 | static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 1095 | static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
1037 | { | 1096 | { |
1038 | struct s3cmci_host *host = mmc_priv(mmc); | 1097 | struct s3cmci_host *host = mmc_priv(mmc); |
1039 | u32 mci_psc, mci_con; | 1098 | u32 mci_con; |
1040 | 1099 | ||
1041 | /* Set the power state */ | 1100 | /* Set the power state */ |
1042 | 1101 | ||
@@ -1074,23 +1133,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1074 | break; | 1133 | break; |
1075 | } | 1134 | } |
1076 | 1135 | ||
1077 | /* Set clock */ | 1136 | s3cmci_set_clk(host, ios); |
1078 | for (mci_psc = 0; mci_psc < 255; mci_psc++) { | ||
1079 | host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); | ||
1080 | |||
1081 | if (host->real_rate <= ios->clock) | ||
1082 | break; | ||
1083 | } | ||
1084 | |||
1085 | if (mci_psc > 255) | ||
1086 | mci_psc = 255; | ||
1087 | |||
1088 | host->prescaler = mci_psc; | ||
1089 | writel(host->prescaler, host->base + S3C2410_SDIPRE); | ||
1090 | |||
1091 | /* If requested clock is 0, real_rate will be 0, too */ | ||
1092 | if (ios->clock == 0) | ||
1093 | host->real_rate = 0; | ||
1094 | 1137 | ||
1095 | /* Set CLOCK_ENABLE */ | 1138 | /* Set CLOCK_ENABLE */ |
1096 | if (ios->clock) | 1139 | if (ios->clock) |
@@ -1148,6 +1191,61 @@ static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | |||
1148 | * checks. Any zero fields to ensure reaonable defaults are picked. */ | 1191 | * checks. Any zero fields to ensure reaonable defaults are picked. */ |
1149 | }; | 1192 | }; |
1150 | 1193 | ||
1194 | #ifdef CONFIG_CPU_FREQ | ||
1195 | |||
1196 | static int s3cmci_cpufreq_transition(struct notifier_block *nb, | ||
1197 | unsigned long val, void *data) | ||
1198 | { | ||
1199 | struct s3cmci_host *host; | ||
1200 | struct mmc_host *mmc; | ||
1201 | unsigned long newclk; | ||
1202 | unsigned long flags; | ||
1203 | |||
1204 | host = container_of(nb, struct s3cmci_host, freq_transition); | ||
1205 | newclk = clk_get_rate(host->clk); | ||
1206 | mmc = host->mmc; | ||
1207 | |||
1208 | if ((val == CPUFREQ_PRECHANGE && newclk > host->clk_rate) || | ||
1209 | (val == CPUFREQ_POSTCHANGE && newclk < host->clk_rate)) { | ||
1210 | spin_lock_irqsave(&mmc->lock, flags); | ||
1211 | |||
1212 | host->clk_rate = newclk; | ||
1213 | |||
1214 | if (mmc->ios.power_mode != MMC_POWER_OFF && | ||
1215 | mmc->ios.clock != 0) | ||
1216 | s3cmci_set_clk(host, &mmc->ios); | ||
1217 | |||
1218 | spin_unlock_irqrestore(&mmc->lock, flags); | ||
1219 | } | ||
1220 | |||
1221 | return 0; | ||
1222 | } | ||
1223 | |||
1224 | static inline int s3cmci_cpufreq_register(struct s3cmci_host *host) | ||
1225 | { | ||
1226 | host->freq_transition.notifier_call = s3cmci_cpufreq_transition; | ||
1227 | |||
1228 | return cpufreq_register_notifier(&host->freq_transition, | ||
1229 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1230 | } | ||
1231 | |||
1232 | static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host) | ||
1233 | { | ||
1234 | cpufreq_unregister_notifier(&host->freq_transition, | ||
1235 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1236 | } | ||
1237 | |||
1238 | #else | ||
1239 | static inline int s3cmci_cpufreq_register(struct s3cmci_host *host) | ||
1240 | { | ||
1241 | return 0; | ||
1242 | } | ||
1243 | |||
1244 | static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host) | ||
1245 | { | ||
1246 | } | ||
1247 | #endif | ||
1248 | |||
1151 | static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | 1249 | static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) |
1152 | { | 1250 | { |
1153 | struct s3cmci_host *host; | 1251 | struct s3cmci_host *host; |
@@ -1298,10 +1396,16 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | |||
1298 | (host->is2440?"2440":""), | 1396 | (host->is2440?"2440":""), |
1299 | host->base, host->irq, host->irq_cd, host->dma); | 1397 | host->base, host->irq, host->irq_cd, host->dma); |
1300 | 1398 | ||
1399 | ret = s3cmci_cpufreq_register(host); | ||
1400 | if (ret) { | ||
1401 | dev_err(&pdev->dev, "failed to register cpufreq\n"); | ||
1402 | goto free_dmabuf; | ||
1403 | } | ||
1404 | |||
1301 | ret = mmc_add_host(mmc); | 1405 | ret = mmc_add_host(mmc); |
1302 | if (ret) { | 1406 | if (ret) { |
1303 | dev_err(&pdev->dev, "failed to add mmc host.\n"); | 1407 | dev_err(&pdev->dev, "failed to add mmc host.\n"); |
1304 | goto free_dmabuf; | 1408 | goto free_cpufreq; |
1305 | } | 1409 | } |
1306 | 1410 | ||
1307 | platform_set_drvdata(pdev, mmc); | 1411 | platform_set_drvdata(pdev, mmc); |
@@ -1309,6 +1413,9 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | |||
1309 | 1413 | ||
1310 | return 0; | 1414 | return 0; |
1311 | 1415 | ||
1416 | free_cpufreq: | ||
1417 | s3cmci_cpufreq_deregister(host); | ||
1418 | |||
1312 | free_dmabuf: | 1419 | free_dmabuf: |
1313 | clk_disable(host->clk); | 1420 | clk_disable(host->clk); |
1314 | 1421 | ||
@@ -1342,6 +1449,7 @@ static void s3cmci_shutdown(struct platform_device *pdev) | |||
1342 | if (host->irq_cd >= 0) | 1449 | if (host->irq_cd >= 0) |
1343 | free_irq(host->irq_cd, host); | 1450 | free_irq(host->irq_cd, host); |
1344 | 1451 | ||
1452 | s3cmci_cpufreq_deregister(host); | ||
1345 | mmc_remove_host(mmc); | 1453 | mmc_remove_host(mmc); |
1346 | clk_disable(host->clk); | 1454 | clk_disable(host->clk); |
1347 | } | 1455 | } |
@@ -1455,7 +1563,7 @@ module_exit(s3cmci_exit); | |||
1455 | 1563 | ||
1456 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); | 1564 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); |
1457 | MODULE_LICENSE("GPL v2"); | 1565 | MODULE_LICENSE("GPL v2"); |
1458 | MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>"); | 1566 | MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>"); |
1459 | MODULE_ALIAS("platform:s3c2410-sdi"); | 1567 | MODULE_ALIAS("platform:s3c2410-sdi"); |
1460 | MODULE_ALIAS("platform:s3c2412-sdi"); | 1568 | MODULE_ALIAS("platform:s3c2412-sdi"); |
1461 | MODULE_ALIAS("platform:s3c2440-sdi"); | 1569 | MODULE_ALIAS("platform:s3c2440-sdi"); |
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h index 37d9c60010c9..ca1ba3d58cfd 100644 --- a/drivers/mmc/host/s3cmci.h +++ b/drivers/mmc/host/s3cmci.h | |||
@@ -51,7 +51,7 @@ struct s3cmci_host { | |||
51 | int dma_complete; | 51 | int dma_complete; |
52 | 52 | ||
53 | u32 pio_sgptr; | 53 | u32 pio_sgptr; |
54 | u32 pio_words; | 54 | u32 pio_bytes; |
55 | u32 pio_count; | 55 | u32 pio_count; |
56 | u32 *pio_ptr; | 56 | u32 *pio_ptr; |
57 | #define XFER_NONE 0 | 57 | #define XFER_NONE 0 |
@@ -67,4 +67,8 @@ struct s3cmci_host { | |||
67 | 67 | ||
68 | unsigned int ccnt, dcnt; | 68 | unsigned int ccnt, dcnt; |
69 | struct tasklet_struct pio_tasklet; | 69 | struct tasklet_struct pio_tasklet; |
70 | |||
71 | #ifdef CONFIG_CPU_FREQ | ||
72 | struct notifier_block freq_transition; | ||
73 | #endif | ||
70 | }; | 74 | }; |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 491ee16da5c1..9ba295d9dd97 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -90,7 +90,7 @@ static int vortex_debug = 1; | |||
90 | #include <linux/eisa.h> | 90 | #include <linux/eisa.h> |
91 | #include <linux/bitops.h> | 91 | #include <linux/bitops.h> |
92 | #include <linux/jiffies.h> | 92 | #include <linux/jiffies.h> |
93 | #include <asm/irq.h> /* For NR_IRQS only. */ | 93 | #include <asm/irq.h> /* For nr_irqs only. */ |
94 | #include <asm/io.h> | 94 | #include <asm/io.h> |
95 | #include <asm/uaccess.h> | 95 | #include <asm/uaccess.h> |
96 | 96 | ||
@@ -1221,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev, | |||
1221 | if (print_info) | 1221 | if (print_info) |
1222 | printk(", IRQ %d\n", dev->irq); | 1222 | printk(", IRQ %d\n", dev->irq); |
1223 | /* Tell them about an invalid IRQ. */ | 1223 | /* Tell them about an invalid IRQ. */ |
1224 | if (dev->irq <= 0 || dev->irq >= NR_IRQS) | 1224 | if (dev->irq <= 0 || dev->irq >= nr_irqs) |
1225 | printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", | 1225 | printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", |
1226 | dev->irq); | 1226 | dev->irq); |
1227 | 1227 | ||
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 17ac6975d70d..b6a816e60c0f 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c | |||
@@ -416,10 +416,10 @@ static int ser12_open(struct net_device *dev) | |||
416 | if (!dev || !bc) | 416 | if (!dev || !bc) |
417 | return -ENXIO; | 417 | return -ENXIO; |
418 | if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT || | 418 | if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT || |
419 | dev->irq < 2 || dev->irq > NR_IRQS) { | 419 | dev->irq < 2 || dev->irq > nr_irqs) { |
420 | printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) " | 420 | printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) " |
421 | "or irq (2 <= irq <= %d)\n", | 421 | "or irq (2 <= irq <= %d)\n", |
422 | 0xffff-SER12_EXTENT, NR_IRQS); | 422 | 0xffff-SER12_EXTENT, nr_irqs); |
423 | return -ENXIO; | 423 | return -ENXIO; |
424 | } | 424 | } |
425 | if (bc->baud < 300 || bc->baud > 4800) { | 425 | if (bc->baud < 300 || bc->baud > 4800) { |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 45ae9d1191d7..c17e39bc5460 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1465,7 +1465,7 @@ static void z8530_init(void) | |||
1465 | printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); | 1465 | printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); |
1466 | 1466 | ||
1467 | flag=" "; | 1467 | flag=" "; |
1468 | for (k = 0; k < NR_IRQS; k++) | 1468 | for (k = 0; k < nr_irqs; k++) |
1469 | if (Ivec[k].used) | 1469 | if (Ivec[k].used) |
1470 | { | 1470 | { |
1471 | printk("%s%d", flag, k); | 1471 | printk("%s%d", flag, k); |
@@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1728 | 1728 | ||
1729 | if (hwcfg.irq == 2) hwcfg.irq = 9; | 1729 | if (hwcfg.irq == 2) hwcfg.irq = 9; |
1730 | 1730 | ||
1731 | if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS) | 1731 | if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs) |
1732 | return -EINVAL; | 1732 | return -EINVAL; |
1733 | 1733 | ||
1734 | if (!Ivec[hwcfg.irq].used && hwcfg.irq) | 1734 | if (!Ivec[hwcfg.irq].used && hwcfg.irq) |
@@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(void) | |||
2148 | } | 2148 | } |
2149 | 2149 | ||
2150 | /* To unload the port must be closed so no real IRQ pending */ | 2150 | /* To unload the port must be closed so no real IRQ pending */ |
2151 | for (k=0; k < NR_IRQS ; k++) | 2151 | for (k = 0; k < nr_irqs ; k++) |
2152 | if (Ivec[k].used) free_irq(k, NULL); | 2152 | if (Ivec[k].used) free_irq(k, NULL); |
2153 | 2153 | ||
2154 | local_irq_enable(); | 2154 | local_irq_enable(); |
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index f972fef87c98..ee51b6a5e605 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c | |||
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *dev ) | |||
318 | continue; | 318 | continue; |
319 | } | 319 | } |
320 | 320 | ||
321 | if( pci_irq_line <= 0 || pci_irq_line >= NR_IRQS ) | 321 | if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs) |
322 | printk( KERN_WARNING " WARNING: The PCI BIOS assigned " | 322 | printk( KERN_WARNING " WARNING: The PCI BIOS assigned " |
323 | "this PCI card to IRQ %d, which is unlikely " | 323 | "this PCI card to IRQ %d, which is unlikely " |
324 | "to work!.\n" | 324 | "to work!.\n" |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index fd56128525d1..3bc54b30c3a1 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -298,7 +298,8 @@ struct pci_port_ops dino_port_ops = { | |||
298 | 298 | ||
299 | static void dino_disable_irq(unsigned int irq) | 299 | static void dino_disable_irq(unsigned int irq) |
300 | { | 300 | { |
301 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 301 | struct irq_desc *desc = irq_to_desc(irq); |
302 | struct dino_device *dino_dev = desc->chip_data; | ||
302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
303 | 304 | ||
304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); | 305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); |
@@ -310,7 +311,8 @@ static void dino_disable_irq(unsigned int irq) | |||
310 | 311 | ||
311 | static void dino_enable_irq(unsigned int irq) | 312 | static void dino_enable_irq(unsigned int irq) |
312 | { | 313 | { |
313 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 314 | struct irq_desc *desc = irq_to_desc(irq); |
315 | struct dino_device *dino_dev = desc->chip_data; | ||
314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 316 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
315 | u32 tmp; | 317 | u32 tmp; |
316 | 318 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 771cef592542..7891db50c483 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -346,10 +346,10 @@ static int __init eisa_probe(struct parisc_device *dev) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* Reserve IRQ2 */ | 348 | /* Reserve IRQ2 */ |
349 | irq_desc[2].action = &irq2_action; | 349 | irq_to_desc(2)->action = &irq2_action; |
350 | 350 | ||
351 | for (i = 0; i < 16; i++) { | 351 | for (i = 0; i < 16; i++) { |
352 | irq_desc[i].chip = &eisa_interrupt_type; | 352 | irq_to_desc(i)->chip = &eisa_interrupt_type; |
353 | } | 353 | } |
354 | 354 | ||
355 | EISA_bus = 1; | 355 | EISA_bus = 1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index f7d088b897ee..e76db9e4d504 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -108,7 +108,8 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | |||
108 | 108 | ||
109 | static void gsc_asic_disable_irq(unsigned int irq) | 109 | static void gsc_asic_disable_irq(unsigned int irq) |
110 | { | 110 | { |
111 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 111 | struct irq_desc *desc = irq_to_desc(irq); |
112 | struct gsc_asic *irq_dev = desc->chip_data; | ||
112 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
113 | u32 imr; | 114 | u32 imr; |
114 | 115 | ||
@@ -123,7 +124,8 @@ static void gsc_asic_disable_irq(unsigned int irq) | |||
123 | 124 | ||
124 | static void gsc_asic_enable_irq(unsigned int irq) | 125 | static void gsc_asic_enable_irq(unsigned int irq) |
125 | { | 126 | { |
126 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 127 | struct irq_desc *desc = irq_to_desc(irq); |
128 | struct gsc_asic *irq_dev = desc->chip_data; | ||
127 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 129 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
128 | u32 imr; | 130 | u32 imr; |
129 | 131 | ||
@@ -159,12 +161,14 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = { | |||
159 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | 161 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) |
160 | { | 162 | { |
161 | static int irq = GSC_IRQ_BASE; | 163 | static int irq = GSC_IRQ_BASE; |
164 | struct irq_desc *desc; | ||
162 | 165 | ||
163 | if (irq > GSC_IRQ_MAX) | 166 | if (irq > GSC_IRQ_MAX) |
164 | return NO_IRQ; | 167 | return NO_IRQ; |
165 | 168 | ||
166 | irq_desc[irq].chip = type; | 169 | desc = irq_to_desc(irq); |
167 | irq_desc[irq].chip_data = data; | 170 | desc->chip = type; |
171 | desc->chip_data = data; | ||
168 | return irq++; | 172 | return irq++; |
169 | } | 173 | } |
170 | 174 | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 6fb3f7979f21..7beffcab2745 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -619,7 +619,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) | |||
619 | 619 | ||
620 | static struct vector_info *iosapic_get_vector(unsigned int irq) | 620 | static struct vector_info *iosapic_get_vector(unsigned int irq) |
621 | { | 621 | { |
622 | return irq_desc[irq].chip_data; | 622 | struct irq_desc *desc = irq_to_desc(irq); |
623 | |||
624 | return desc->chip_data; | ||
623 | } | 625 | } |
624 | 626 | ||
625 | static void iosapic_disable_irq(unsigned int irq) | 627 | static void iosapic_disable_irq(unsigned int irq) |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 1e8d2d17f04c..1e93c837514f 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -363,7 +363,9 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | for (i = 0; i < 16; i++) { | 365 | for (i = 0; i < 16; i++) { |
366 | irq_desc[i].chip = &superio_interrupt_type; | 366 | struct irq_desc *desc = irq_to_desc(i); |
367 | |||
368 | desc->chip = &superio_interrupt_type; | ||
367 | } | 369 | } |
368 | 370 | ||
369 | /* | 371 | /* |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index e842e756308a..8b29c307f1a1 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -193,7 +193,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) | |||
193 | { | 193 | { |
194 | struct acpi_dmar_hardware_unit *drhd; | 194 | struct acpi_dmar_hardware_unit *drhd; |
195 | static int include_all; | 195 | static int include_all; |
196 | int ret; | 196 | int ret = 0; |
197 | 197 | ||
198 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; | 198 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; |
199 | 199 | ||
@@ -212,7 +212,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) | |||
212 | include_all = 1; | 212 | include_all = 1; |
213 | } | 213 | } |
214 | 214 | ||
215 | if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) { | 215 | if (ret) { |
216 | list_del(&dmaru->list); | 216 | list_del(&dmaru->list); |
217 | kfree(dmaru); | 217 | kfree(dmaru); |
218 | } | 218 | } |
@@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) | |||
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | /** | ||
293 | * dmar_table_detect - checks to see if the platform supports DMAR devices | ||
294 | */ | ||
295 | static int __init dmar_table_detect(void) | ||
296 | { | ||
297 | acpi_status status = AE_OK; | ||
298 | |||
299 | /* if we could find DMAR table, then there are DMAR devices */ | ||
300 | status = acpi_get_table(ACPI_SIG_DMAR, 0, | ||
301 | (struct acpi_table_header **)&dmar_tbl); | ||
302 | |||
303 | if (ACPI_SUCCESS(status) && !dmar_tbl) { | ||
304 | printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | ||
305 | status = AE_NOT_FOUND; | ||
306 | } | ||
307 | |||
308 | return (ACPI_SUCCESS(status) ? 1 : 0); | ||
309 | } | ||
292 | 310 | ||
293 | /** | 311 | /** |
294 | * parse_dmar_table - parses the DMA reporting table | 312 | * parse_dmar_table - parses the DMA reporting table |
@@ -300,6 +318,12 @@ parse_dmar_table(void) | |||
300 | struct acpi_dmar_header *entry_header; | 318 | struct acpi_dmar_header *entry_header; |
301 | int ret = 0; | 319 | int ret = 0; |
302 | 320 | ||
321 | /* | ||
322 | * Do it again, earlier dmar_tbl mapping could be mapped with | ||
323 | * fixed map. | ||
324 | */ | ||
325 | dmar_table_detect(); | ||
326 | |||
303 | dmar = (struct acpi_table_dmar *)dmar_tbl; | 327 | dmar = (struct acpi_table_dmar *)dmar_tbl; |
304 | if (!dmar) | 328 | if (!dmar) |
305 | return -ENODEV; | 329 | return -ENODEV; |
@@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev) | |||
373 | 397 | ||
374 | int __init dmar_dev_scope_init(void) | 398 | int __init dmar_dev_scope_init(void) |
375 | { | 399 | { |
376 | struct dmar_drhd_unit *drhd; | 400 | struct dmar_drhd_unit *drhd, *drhd_n; |
377 | int ret = -ENODEV; | 401 | int ret = -ENODEV; |
378 | 402 | ||
379 | for_each_drhd_unit(drhd) { | 403 | list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { |
380 | ret = dmar_parse_dev(drhd); | 404 | ret = dmar_parse_dev(drhd); |
381 | if (ret) | 405 | if (ret) |
382 | return ret; | 406 | return ret; |
@@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void) | |||
384 | 408 | ||
385 | #ifdef CONFIG_DMAR | 409 | #ifdef CONFIG_DMAR |
386 | { | 410 | { |
387 | struct dmar_rmrr_unit *rmrr; | 411 | struct dmar_rmrr_unit *rmrr, *rmrr_n; |
388 | for_each_rmrr_units(rmrr) { | 412 | list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) { |
389 | ret = rmrr_parse_dev(rmrr); | 413 | ret = rmrr_parse_dev(rmrr); |
390 | if (ret) | 414 | if (ret) |
391 | return ret; | 415 | return ret; |
@@ -430,30 +454,11 @@ int __init dmar_table_init(void) | |||
430 | return 0; | 454 | return 0; |
431 | } | 455 | } |
432 | 456 | ||
433 | /** | ||
434 | * early_dmar_detect - checks to see if the platform supports DMAR devices | ||
435 | */ | ||
436 | int __init early_dmar_detect(void) | ||
437 | { | ||
438 | acpi_status status = AE_OK; | ||
439 | |||
440 | /* if we could find DMAR table, then there are DMAR devices */ | ||
441 | status = acpi_get_table(ACPI_SIG_DMAR, 0, | ||
442 | (struct acpi_table_header **)&dmar_tbl); | ||
443 | |||
444 | if (ACPI_SUCCESS(status) && !dmar_tbl) { | ||
445 | printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | ||
446 | status = AE_NOT_FOUND; | ||
447 | } | ||
448 | |||
449 | return (ACPI_SUCCESS(status) ? 1 : 0); | ||
450 | } | ||
451 | |||
452 | void __init detect_intel_iommu(void) | 457 | void __init detect_intel_iommu(void) |
453 | { | 458 | { |
454 | int ret; | 459 | int ret; |
455 | 460 | ||
456 | ret = early_dmar_detect(); | 461 | ret = dmar_table_detect(); |
457 | 462 | ||
458 | #ifdef CONFIG_DMAR | 463 | #ifdef CONFIG_DMAR |
459 | { | 464 | { |
@@ -479,14 +484,16 @@ void __init detect_intel_iommu(void) | |||
479 | " x2apic support\n"); | 484 | " x2apic support\n"); |
480 | 485 | ||
481 | dmar_disabled = 1; | 486 | dmar_disabled = 1; |
482 | return; | 487 | goto end; |
483 | } | 488 | } |
484 | 489 | ||
485 | if (ret && !no_iommu && !iommu_detected && !swiotlb && | 490 | if (ret && !no_iommu && !iommu_detected && !swiotlb && |
486 | !dmar_disabled) | 491 | !dmar_disabled) |
487 | iommu_detected = 1; | 492 | iommu_detected = 1; |
488 | } | 493 | } |
494 | end: | ||
489 | #endif | 495 | #endif |
496 | dmar_tbl = NULL; | ||
490 | } | 497 | } |
491 | 498 | ||
492 | 499 | ||
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 279c940a0039..bf7d6ce9bbb3 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
126 | cfg->msg.address_hi = 0xffffffff; | 126 | cfg->msg.address_hi = 0xffffffff; |
127 | 127 | ||
128 | irq = create_irq(); | 128 | irq = create_irq(); |
129 | if (irq < 0) { | 129 | |
130 | if (irq <= 0) { | ||
130 | kfree(cfg); | 131 | kfree(cfg); |
131 | return -EBUSY; | 132 | return -EBUSY; |
132 | } | 133 | } |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 738d4c89581c..2de5a3238c94 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/interrupt.h> | ||
1 | #include <linux/dmar.h> | 2 | #include <linux/dmar.h> |
2 | #include <linux/spinlock.h> | 3 | #include <linux/spinlock.h> |
3 | #include <linux/jiffies.h> | 4 | #include <linux/jiffies.h> |
@@ -11,41 +12,64 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; | |||
11 | static int ir_ioapic_num; | 12 | static int ir_ioapic_num; |
12 | int intr_remapping_enabled; | 13 | int intr_remapping_enabled; |
13 | 14 | ||
14 | static struct { | 15 | struct irq_2_iommu { |
15 | struct intel_iommu *iommu; | 16 | struct intel_iommu *iommu; |
16 | u16 irte_index; | 17 | u16 irte_index; |
17 | u16 sub_handle; | 18 | u16 sub_handle; |
18 | u8 irte_mask; | 19 | u8 irte_mask; |
19 | } irq_2_iommu[NR_IRQS]; | 20 | }; |
21 | |||
22 | static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; | ||
23 | |||
24 | static struct irq_2_iommu *irq_2_iommu(unsigned int irq) | ||
25 | { | ||
26 | return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL; | ||
27 | } | ||
28 | |||
29 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) | ||
30 | { | ||
31 | return irq_2_iommu(irq); | ||
32 | } | ||
20 | 33 | ||
21 | static DEFINE_SPINLOCK(irq_2_ir_lock); | 34 | static DEFINE_SPINLOCK(irq_2_ir_lock); |
22 | 35 | ||
23 | int irq_remapped(int irq) | 36 | static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq) |
24 | { | 37 | { |
25 | if (irq > NR_IRQS) | 38 | struct irq_2_iommu *irq_iommu; |
26 | return 0; | 39 | |
40 | irq_iommu = irq_2_iommu(irq); | ||
41 | |||
42 | if (!irq_iommu) | ||
43 | return NULL; | ||
44 | |||
45 | if (!irq_iommu->iommu) | ||
46 | return NULL; | ||
27 | 47 | ||
28 | if (!irq_2_iommu[irq].iommu) | 48 | return irq_iommu; |
29 | return 0; | 49 | } |
30 | 50 | ||
31 | return 1; | 51 | int irq_remapped(int irq) |
52 | { | ||
53 | return valid_irq_2_iommu(irq) != NULL; | ||
32 | } | 54 | } |
33 | 55 | ||
34 | int get_irte(int irq, struct irte *entry) | 56 | int get_irte(int irq, struct irte *entry) |
35 | { | 57 | { |
36 | int index; | 58 | int index; |
59 | struct irq_2_iommu *irq_iommu; | ||
37 | 60 | ||
38 | if (!entry || irq > NR_IRQS) | 61 | if (!entry) |
39 | return -1; | 62 | return -1; |
40 | 63 | ||
41 | spin_lock(&irq_2_ir_lock); | 64 | spin_lock(&irq_2_ir_lock); |
42 | if (!irq_2_iommu[irq].iommu) { | 65 | irq_iommu = valid_irq_2_iommu(irq); |
66 | if (!irq_iommu) { | ||
43 | spin_unlock(&irq_2_ir_lock); | 67 | spin_unlock(&irq_2_ir_lock); |
44 | return -1; | 68 | return -1; |
45 | } | 69 | } |
46 | 70 | ||
47 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 71 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
48 | *entry = *(irq_2_iommu[irq].iommu->ir_table->base + index); | 72 | *entry = *(irq_iommu->iommu->ir_table->base + index); |
49 | 73 | ||
50 | spin_unlock(&irq_2_ir_lock); | 74 | spin_unlock(&irq_2_ir_lock); |
51 | return 0; | 75 | return 0; |
@@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry) | |||
54 | int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | 78 | int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) |
55 | { | 79 | { |
56 | struct ir_table *table = iommu->ir_table; | 80 | struct ir_table *table = iommu->ir_table; |
81 | struct irq_2_iommu *irq_iommu; | ||
57 | u16 index, start_index; | 82 | u16 index, start_index; |
58 | unsigned int mask = 0; | 83 | unsigned int mask = 0; |
59 | int i; | 84 | int i; |
@@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
61 | if (!count) | 86 | if (!count) |
62 | return -1; | 87 | return -1; |
63 | 88 | ||
89 | /* protect irq_2_iommu_alloc later */ | ||
90 | if (irq >= nr_irqs) | ||
91 | return -1; | ||
92 | |||
64 | /* | 93 | /* |
65 | * start the IRTE search from index 0. | 94 | * start the IRTE search from index 0. |
66 | */ | 95 | */ |
@@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
100 | for (i = index; i < index + count; i++) | 129 | for (i = index; i < index + count; i++) |
101 | table->base[i].present = 1; | 130 | table->base[i].present = 1; |
102 | 131 | ||
103 | irq_2_iommu[irq].iommu = iommu; | 132 | irq_iommu = irq_2_iommu_alloc(irq); |
104 | irq_2_iommu[irq].irte_index = index; | 133 | irq_iommu->iommu = iommu; |
105 | irq_2_iommu[irq].sub_handle = 0; | 134 | irq_iommu->irte_index = index; |
106 | irq_2_iommu[irq].irte_mask = mask; | 135 | irq_iommu->sub_handle = 0; |
136 | irq_iommu->irte_mask = mask; | ||
107 | 137 | ||
108 | spin_unlock(&irq_2_ir_lock); | 138 | spin_unlock(&irq_2_ir_lock); |
109 | 139 | ||
@@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | |||
124 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) | 154 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) |
125 | { | 155 | { |
126 | int index; | 156 | int index; |
157 | struct irq_2_iommu *irq_iommu; | ||
127 | 158 | ||
128 | spin_lock(&irq_2_ir_lock); | 159 | spin_lock(&irq_2_ir_lock); |
129 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 160 | irq_iommu = valid_irq_2_iommu(irq); |
161 | if (!irq_iommu) { | ||
130 | spin_unlock(&irq_2_ir_lock); | 162 | spin_unlock(&irq_2_ir_lock); |
131 | return -1; | 163 | return -1; |
132 | } | 164 | } |
133 | 165 | ||
134 | *sub_handle = irq_2_iommu[irq].sub_handle; | 166 | *sub_handle = irq_iommu->sub_handle; |
135 | index = irq_2_iommu[irq].irte_index; | 167 | index = irq_iommu->irte_index; |
136 | spin_unlock(&irq_2_ir_lock); | 168 | spin_unlock(&irq_2_ir_lock); |
137 | return index; | 169 | return index; |
138 | } | 170 | } |
139 | 171 | ||
140 | int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | 172 | int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) |
141 | { | 173 | { |
174 | struct irq_2_iommu *irq_iommu; | ||
175 | |||
142 | spin_lock(&irq_2_ir_lock); | 176 | spin_lock(&irq_2_ir_lock); |
143 | if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) { | ||
144 | spin_unlock(&irq_2_ir_lock); | ||
145 | return -1; | ||
146 | } | ||
147 | 177 | ||
148 | irq_2_iommu[irq].iommu = iommu; | 178 | irq_iommu = irq_2_iommu_alloc(irq); |
149 | irq_2_iommu[irq].irte_index = index; | 179 | |
150 | irq_2_iommu[irq].sub_handle = subhandle; | 180 | irq_iommu->iommu = iommu; |
151 | irq_2_iommu[irq].irte_mask = 0; | 181 | irq_iommu->irte_index = index; |
182 | irq_iommu->sub_handle = subhandle; | ||
183 | irq_iommu->irte_mask = 0; | ||
152 | 184 | ||
153 | spin_unlock(&irq_2_ir_lock); | 185 | spin_unlock(&irq_2_ir_lock); |
154 | 186 | ||
@@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | |||
157 | 189 | ||
158 | int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) | 190 | int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) |
159 | { | 191 | { |
192 | struct irq_2_iommu *irq_iommu; | ||
193 | |||
160 | spin_lock(&irq_2_ir_lock); | 194 | spin_lock(&irq_2_ir_lock); |
161 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 195 | irq_iommu = valid_irq_2_iommu(irq); |
196 | if (!irq_iommu) { | ||
162 | spin_unlock(&irq_2_ir_lock); | 197 | spin_unlock(&irq_2_ir_lock); |
163 | return -1; | 198 | return -1; |
164 | } | 199 | } |
165 | 200 | ||
166 | irq_2_iommu[irq].iommu = NULL; | 201 | irq_iommu->iommu = NULL; |
167 | irq_2_iommu[irq].irte_index = 0; | 202 | irq_iommu->irte_index = 0; |
168 | irq_2_iommu[irq].sub_handle = 0; | 203 | irq_iommu->sub_handle = 0; |
169 | irq_2_iommu[irq].irte_mask = 0; | 204 | irq_2_iommu(irq)->irte_mask = 0; |
170 | 205 | ||
171 | spin_unlock(&irq_2_ir_lock); | 206 | spin_unlock(&irq_2_ir_lock); |
172 | 207 | ||
@@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified) | |||
178 | int index; | 213 | int index; |
179 | struct irte *irte; | 214 | struct irte *irte; |
180 | struct intel_iommu *iommu; | 215 | struct intel_iommu *iommu; |
216 | struct irq_2_iommu *irq_iommu; | ||
181 | 217 | ||
182 | spin_lock(&irq_2_ir_lock); | 218 | spin_lock(&irq_2_ir_lock); |
183 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 219 | irq_iommu = valid_irq_2_iommu(irq); |
220 | if (!irq_iommu) { | ||
184 | spin_unlock(&irq_2_ir_lock); | 221 | spin_unlock(&irq_2_ir_lock); |
185 | return -1; | 222 | return -1; |
186 | } | 223 | } |
187 | 224 | ||
188 | iommu = irq_2_iommu[irq].iommu; | 225 | iommu = irq_iommu->iommu; |
189 | 226 | ||
190 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 227 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
191 | irte = &iommu->ir_table->base[index]; | 228 | irte = &iommu->ir_table->base[index]; |
192 | 229 | ||
193 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); | 230 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); |
@@ -203,18 +240,20 @@ int flush_irte(int irq) | |||
203 | { | 240 | { |
204 | int index; | 241 | int index; |
205 | struct intel_iommu *iommu; | 242 | struct intel_iommu *iommu; |
243 | struct irq_2_iommu *irq_iommu; | ||
206 | 244 | ||
207 | spin_lock(&irq_2_ir_lock); | 245 | spin_lock(&irq_2_ir_lock); |
208 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 246 | irq_iommu = valid_irq_2_iommu(irq); |
247 | if (!irq_iommu) { | ||
209 | spin_unlock(&irq_2_ir_lock); | 248 | spin_unlock(&irq_2_ir_lock); |
210 | return -1; | 249 | return -1; |
211 | } | 250 | } |
212 | 251 | ||
213 | iommu = irq_2_iommu[irq].iommu; | 252 | iommu = irq_iommu->iommu; |
214 | 253 | ||
215 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 254 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
216 | 255 | ||
217 | qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); | 256 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
218 | spin_unlock(&irq_2_ir_lock); | 257 | spin_unlock(&irq_2_ir_lock); |
219 | 258 | ||
220 | return 0; | 259 | return 0; |
@@ -246,28 +285,30 @@ int free_irte(int irq) | |||
246 | int index, i; | 285 | int index, i; |
247 | struct irte *irte; | 286 | struct irte *irte; |
248 | struct intel_iommu *iommu; | 287 | struct intel_iommu *iommu; |
288 | struct irq_2_iommu *irq_iommu; | ||
249 | 289 | ||
250 | spin_lock(&irq_2_ir_lock); | 290 | spin_lock(&irq_2_ir_lock); |
251 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 291 | irq_iommu = valid_irq_2_iommu(irq); |
292 | if (!irq_iommu) { | ||
252 | spin_unlock(&irq_2_ir_lock); | 293 | spin_unlock(&irq_2_ir_lock); |
253 | return -1; | 294 | return -1; |
254 | } | 295 | } |
255 | 296 | ||
256 | iommu = irq_2_iommu[irq].iommu; | 297 | iommu = irq_iommu->iommu; |
257 | 298 | ||
258 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 299 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
259 | irte = &iommu->ir_table->base[index]; | 300 | irte = &iommu->ir_table->base[index]; |
260 | 301 | ||
261 | if (!irq_2_iommu[irq].sub_handle) { | 302 | if (!irq_iommu->sub_handle) { |
262 | for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++) | 303 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) |
263 | set_64bit((unsigned long *)irte, 0); | 304 | set_64bit((unsigned long *)irte, 0); |
264 | qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); | 305 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
265 | } | 306 | } |
266 | 307 | ||
267 | irq_2_iommu[irq].iommu = NULL; | 308 | irq_iommu->iommu = NULL; |
268 | irq_2_iommu[irq].irte_index = 0; | 309 | irq_iommu->irte_index = 0; |
269 | irq_2_iommu[irq].sub_handle = 0; | 310 | irq_iommu->sub_handle = 0; |
270 | irq_2_iommu[irq].irte_mask = 0; | 311 | irq_iommu->irte_mask = 0; |
271 | 312 | ||
272 | spin_unlock(&irq_2_ir_lock); | 313 | spin_unlock(&irq_2_ir_lock); |
273 | 314 | ||
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index a0ffb8ebfe00..9e1140f085fd 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
273 | goto fail0d; | 273 | goto fail0d; |
274 | cf->socket.pci_irq = board->irq_pin; | 274 | cf->socket.pci_irq = board->irq_pin; |
275 | } else | 275 | } else |
276 | cf->socket.pci_irq = NR_IRQS + 1; | 276 | cf->socket.pci_irq = nr_irqs + 1; |
277 | 277 | ||
278 | /* pcmcia layer only remaps "real" memory not iospace */ | 278 | /* pcmcia layer only remaps "real" memory not iospace */ |
279 | cf->socket.io_offset = (unsigned long) | 279 | cf->socket.io_offset = (unsigned long) |
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 117dc12ab438..9ef69cdb3183 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -233,15 +233,18 @@ static struct hw_interrupt_type hd64465_ss_irq_type = { | |||
233 | */ | 233 | */ |
234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | 234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) |
235 | { | 235 | { |
236 | struct irq_desc *desc; | ||
237 | |||
236 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); | 238 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); |
237 | 239 | ||
238 | if (irq >= HS_NUM_MAPPED_IRQS) | 240 | if (irq >= HS_NUM_MAPPED_IRQS) |
239 | return; | 241 | return; |
240 | 242 | ||
243 | desc = irq_to_desc(irq); | ||
241 | hs_mapped_irq[irq].sock = sp; | 244 | hs_mapped_irq[irq].sock = sp; |
242 | /* insert ourselves as the irq controller */ | 245 | /* insert ourselves as the irq controller */ |
243 | hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; | 246 | hs_mapped_irq[irq].old_handler = desc->chip; |
244 | irq_desc[irq].chip = &hd64465_ss_irq_type; | 247 | desc->chip = &hd64465_ss_irq_type; |
245 | } | 248 | } |
246 | 249 | ||
247 | 250 | ||
@@ -250,13 +253,16 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | |||
250 | */ | 253 | */ |
251 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | 254 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) |
252 | { | 255 | { |
256 | struct irq_desc *desc; | ||
257 | |||
253 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); | 258 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); |
254 | 259 | ||
255 | if (irq >= HS_NUM_MAPPED_IRQS) | 260 | if (irq >= HS_NUM_MAPPED_IRQS) |
256 | return; | 261 | return; |
257 | 262 | ||
263 | desc = irq_to_desc(irq); | ||
258 | /* restore the original irq controller */ | 264 | /* restore the original irq controller */ |
259 | irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; | 265 | desc->chip = hs_mapped_irq[irq].old_handler; |
260 | } | 266 | } |
261 | 267 | ||
262 | /*============================================================*/ | 268 | /*============================================================*/ |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index eee2f1cb213c..b2c412419059 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup(char *options) | |||
639 | int irq; | 639 | int irq; |
640 | options += 4; | 640 | options += 4; |
641 | irq = simple_strtoul(options, &options, 0); | 641 | irq = simple_strtoul(options, &options, 0); |
642 | if (irq >= 0 && irq < NR_IRQS) | 642 | if (irq >= 0 && irq < nr_irqs) |
643 | vrc4171_irq = irq; | 643 | vrc4171_irq = irq; |
644 | 644 | ||
645 | if (*options != ',') | 645 | if (*options != ',') |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 884b635f028b..834dcc6d785f 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
360 | spin_unlock_irq(&rtc_lock); | 360 | spin_unlock_irq(&rtc_lock); |
361 | 361 | ||
362 | aie_irq = platform_get_irq(pdev, 0); | 362 | aie_irq = platform_get_irq(pdev, 0); |
363 | if (aie_irq < 0 || aie_irq >= NR_IRQS) { | 363 | if (aie_irq < 0 || aie_irq >= nr_irqs) { |
364 | retval = -EBUSY; | 364 | retval = -EBUSY; |
365 | goto err_device_unregister; | 365 | goto err_device_unregister; |
366 | } | 366 | } |
@@ -371,7 +371,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
371 | goto err_device_unregister; | 371 | goto err_device_unregister; |
372 | 372 | ||
373 | pie_irq = platform_get_irq(pdev, 1); | 373 | pie_irq = platform_get_irq(pdev, 1); |
374 | if (pie_irq < 0 || pie_irq >= NR_IRQS) | 374 | if (pie_irq < 0 || pie_irq >= nr_irqs) |
375 | goto err_free_irq; | 375 | goto err_free_irq; |
376 | 376 | ||
377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, | 377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index b5a868d85eb4..1e5478abd90e 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) | |||
337 | #else | 337 | #else |
338 | #define IRQ_MIN 9 | 338 | #define IRQ_MIN 9 |
339 | #if defined(__PPC) | 339 | #if defined(__PPC) |
340 | #define IRQ_MAX (NR_IRQS-1) | 340 | #define IRQ_MAX (nr_irqs-1) |
341 | #else | 341 | #else |
342 | #define IRQ_MAX 12 | 342 | #define IRQ_MAX 12 |
343 | #endif | 343 | #endif |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 740bad435995..afc96e844a25 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -343,6 +343,11 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r | |||
343 | } | 343 | } |
344 | 344 | ||
345 | #ifdef CONFIG_IDE_PROC_FS | 345 | #ifdef CONFIG_IDE_PROC_FS |
346 | static ide_proc_entry_t idescsi_proc[] = { | ||
347 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | ||
348 | { NULL, 0, NULL, NULL } | ||
349 | }; | ||
350 | |||
346 | #define ide_scsi_devset_get(name, field) \ | 351 | #define ide_scsi_devset_get(name, field) \ |
347 | static int get_##name(ide_drive_t *drive) \ | 352 | static int get_##name(ide_drive_t *drive) \ |
348 | { \ | 353 | { \ |
@@ -378,6 +383,16 @@ static const struct ide_proc_devset idescsi_settings[] = { | |||
378 | IDE_PROC_DEVSET(transform, 0, 3), | 383 | IDE_PROC_DEVSET(transform, 0, 3), |
379 | { 0 }, | 384 | { 0 }, |
380 | }; | 385 | }; |
386 | |||
387 | static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive) | ||
388 | { | ||
389 | return idescsi_proc; | ||
390 | } | ||
391 | |||
392 | static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive) | ||
393 | { | ||
394 | return idescsi_settings; | ||
395 | } | ||
381 | #endif | 396 | #endif |
382 | 397 | ||
383 | /* | 398 | /* |
@@ -419,13 +434,6 @@ static void ide_scsi_remove(ide_drive_t *drive) | |||
419 | 434 | ||
420 | static int ide_scsi_probe(ide_drive_t *); | 435 | static int ide_scsi_probe(ide_drive_t *); |
421 | 436 | ||
422 | #ifdef CONFIG_IDE_PROC_FS | ||
423 | static ide_proc_entry_t idescsi_proc[] = { | ||
424 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | ||
425 | { NULL, 0, NULL, NULL } | ||
426 | }; | ||
427 | #endif | ||
428 | |||
429 | static ide_driver_t idescsi_driver = { | 437 | static ide_driver_t idescsi_driver = { |
430 | .gen_driver = { | 438 | .gen_driver = { |
431 | .owner = THIS_MODULE, | 439 | .owner = THIS_MODULE, |
@@ -439,8 +447,8 @@ static ide_driver_t idescsi_driver = { | |||
439 | .end_request = idescsi_end_request, | 447 | .end_request = idescsi_end_request, |
440 | .error = idescsi_atapi_error, | 448 | .error = idescsi_atapi_error, |
441 | #ifdef CONFIG_IDE_PROC_FS | 449 | #ifdef CONFIG_IDE_PROC_FS |
442 | .proc = idescsi_proc, | 450 | .proc_entries = ide_scsi_proc_entries, |
443 | .settings = idescsi_settings, | 451 | .proc_devsets = ide_scsi_proc_devsets, |
444 | #endif | 452 | #endif |
445 | }; | 453 | }; |
446 | 454 | ||
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 381b12ac20e0..d935b2d04f93 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | static struct m68k_serial m68k_soft[NR_PORTS]; | 68 | static struct m68k_serial m68k_soft[NR_PORTS]; |
69 | struct m68k_serial *IRQ_ports[NR_IRQS]; | ||
70 | 69 | ||
71 | static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS; | 70 | static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS; |
72 | 71 | ||
@@ -375,15 +374,11 @@ clear_and_return: | |||
375 | */ | 374 | */ |
376 | irqreturn_t rs_interrupt(int irq, void *dev_id) | 375 | irqreturn_t rs_interrupt(int irq, void *dev_id) |
377 | { | 376 | { |
378 | struct m68k_serial * info; | 377 | struct m68k_serial *info = dev_id; |
379 | m68328_uart *uart; | 378 | m68328_uart *uart; |
380 | unsigned short rx; | 379 | unsigned short rx; |
381 | unsigned short tx; | 380 | unsigned short tx; |
382 | 381 | ||
383 | info = IRQ_ports[irq]; | ||
384 | if(!info) | ||
385 | return IRQ_NONE; | ||
386 | |||
387 | uart = &uart_addr[info->line]; | 382 | uart = &uart_addr[info->line]; |
388 | rx = uart->urx.w; | 383 | rx = uart->urx.w; |
389 | 384 | ||
@@ -1383,8 +1378,6 @@ rs68328_init(void) | |||
1383 | info->port, info->irq); | 1378 | info->port, info->irq); |
1384 | printk(" is a builtin MC68328 UART\n"); | 1379 | printk(" is a builtin MC68328 UART\n"); |
1385 | 1380 | ||
1386 | IRQ_ports[info->irq] = info; /* waste of space */ | ||
1387 | |||
1388 | #ifdef CONFIG_M68VZ328 | 1381 | #ifdef CONFIG_M68VZ328 |
1389 | if (i > 0 ) | 1382 | if (i > 0 ) |
1390 | PJSEL &= 0xCF; /* PSW enable second port output */ | 1383 | PJSEL &= 0xCF; /* PSW enable second port output */ |
@@ -1393,7 +1386,7 @@ rs68328_init(void) | |||
1393 | if (request_irq(uart_irqs[i], | 1386 | if (request_irq(uart_irqs[i], |
1394 | rs_interrupt, | 1387 | rs_interrupt, |
1395 | IRQF_DISABLED, | 1388 | IRQF_DISABLED, |
1396 | "M68328_UART", NULL)) | 1389 | "M68328_UART", info)) |
1397 | panic("Unable to attach 68328 serial interrupt\n"); | 1390 | panic("Unable to attach 68328 serial interrupt\n"); |
1398 | } | 1391 | } |
1399 | local_irq_restore(flags); | 1392 | local_irq_restore(flags); |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 1528de23a650..303272af386e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -156,11 +156,15 @@ struct uart_8250_port { | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | struct irq_info { | 158 | struct irq_info { |
159 | spinlock_t lock; | 159 | struct hlist_node node; |
160 | int irq; | ||
161 | spinlock_t lock; /* Protects list not the hash */ | ||
160 | struct list_head *head; | 162 | struct list_head *head; |
161 | }; | 163 | }; |
162 | 164 | ||
163 | static struct irq_info irq_lists[NR_IRQS]; | 165 | #define NR_IRQ_HASH 32 /* Can be adjusted later */ |
166 | static struct hlist_head irq_lists[NR_IRQ_HASH]; | ||
167 | static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */ | ||
164 | 168 | ||
165 | /* | 169 | /* |
166 | * Here we define the default xmit fifo size used for each type of UART. | 170 | * Here we define the default xmit fifo size used for each type of UART. |
@@ -1545,15 +1549,43 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) | |||
1545 | BUG_ON(i->head != &up->list); | 1549 | BUG_ON(i->head != &up->list); |
1546 | i->head = NULL; | 1550 | i->head = NULL; |
1547 | } | 1551 | } |
1548 | |||
1549 | spin_unlock_irq(&i->lock); | 1552 | spin_unlock_irq(&i->lock); |
1553 | /* List empty so throw away the hash node */ | ||
1554 | if (i->head == NULL) { | ||
1555 | hlist_del(&i->node); | ||
1556 | kfree(i); | ||
1557 | } | ||
1550 | } | 1558 | } |
1551 | 1559 | ||
1552 | static int serial_link_irq_chain(struct uart_8250_port *up) | 1560 | static int serial_link_irq_chain(struct uart_8250_port *up) |
1553 | { | 1561 | { |
1554 | struct irq_info *i = irq_lists + up->port.irq; | 1562 | struct hlist_head *h; |
1563 | struct hlist_node *n; | ||
1564 | struct irq_info *i; | ||
1555 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; | 1565 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; |
1556 | 1566 | ||
1567 | mutex_lock(&hash_mutex); | ||
1568 | |||
1569 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | ||
1570 | |||
1571 | hlist_for_each(n, h) { | ||
1572 | i = hlist_entry(n, struct irq_info, node); | ||
1573 | if (i->irq == up->port.irq) | ||
1574 | break; | ||
1575 | } | ||
1576 | |||
1577 | if (n == NULL) { | ||
1578 | i = kzalloc(sizeof(struct irq_info), GFP_KERNEL); | ||
1579 | if (i == NULL) { | ||
1580 | mutex_unlock(&hash_mutex); | ||
1581 | return -ENOMEM; | ||
1582 | } | ||
1583 | spin_lock_init(&i->lock); | ||
1584 | i->irq = up->port.irq; | ||
1585 | hlist_add_head(&i->node, h); | ||
1586 | } | ||
1587 | mutex_unlock(&hash_mutex); | ||
1588 | |||
1557 | spin_lock_irq(&i->lock); | 1589 | spin_lock_irq(&i->lock); |
1558 | 1590 | ||
1559 | if (i->head) { | 1591 | if (i->head) { |
@@ -1577,14 +1609,28 @@ static int serial_link_irq_chain(struct uart_8250_port *up) | |||
1577 | 1609 | ||
1578 | static void serial_unlink_irq_chain(struct uart_8250_port *up) | 1610 | static void serial_unlink_irq_chain(struct uart_8250_port *up) |
1579 | { | 1611 | { |
1580 | struct irq_info *i = irq_lists + up->port.irq; | 1612 | struct irq_info *i; |
1613 | struct hlist_node *n; | ||
1614 | struct hlist_head *h; | ||
1581 | 1615 | ||
1616 | mutex_lock(&hash_mutex); | ||
1617 | |||
1618 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | ||
1619 | |||
1620 | hlist_for_each(n, h) { | ||
1621 | i = hlist_entry(n, struct irq_info, node); | ||
1622 | if (i->irq == up->port.irq) | ||
1623 | break; | ||
1624 | } | ||
1625 | |||
1626 | BUG_ON(n == NULL); | ||
1582 | BUG_ON(i->head == NULL); | 1627 | BUG_ON(i->head == NULL); |
1583 | 1628 | ||
1584 | if (list_empty(i->head)) | 1629 | if (list_empty(i->head)) |
1585 | free_irq(up->port.irq, i); | 1630 | free_irq(up->port.irq, i); |
1586 | 1631 | ||
1587 | serial_do_unlink(i, up); | 1632 | serial_do_unlink(i, up); |
1633 | mutex_unlock(&hash_mutex); | ||
1588 | } | 1634 | } |
1589 | 1635 | ||
1590 | /* Base timer interval for polling */ | 1636 | /* Base timer interval for polling */ |
@@ -2447,7 +2493,7 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
2447 | static int | 2493 | static int |
2448 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) | 2494 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) |
2449 | { | 2495 | { |
2450 | if (ser->irq >= NR_IRQS || ser->irq < 0 || | 2496 | if (ser->irq >= nr_irqs || ser->irq < 0 || |
2451 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | 2497 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || |
2452 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || | 2498 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || |
2453 | ser->type == PORT_STARTECH) | 2499 | ser->type == PORT_STARTECH) |
@@ -2967,7 +3013,7 @@ EXPORT_SYMBOL(serial8250_unregister_port); | |||
2967 | 3013 | ||
2968 | static int __init serial8250_init(void) | 3014 | static int __init serial8250_init(void) |
2969 | { | 3015 | { |
2970 | int ret, i; | 3016 | int ret; |
2971 | 3017 | ||
2972 | if (nr_uarts > UART_NR) | 3018 | if (nr_uarts > UART_NR) |
2973 | nr_uarts = UART_NR; | 3019 | nr_uarts = UART_NR; |
@@ -2976,9 +3022,6 @@ static int __init serial8250_init(void) | |||
2976 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 3022 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
2977 | share_irqs ? "en" : "dis"); | 3023 | share_irqs ? "en" : "dis"); |
2978 | 3024 | ||
2979 | for (i = 0; i < NR_IRQS; i++) | ||
2980 | spin_lock_init(&irq_lists[i].lock); | ||
2981 | |||
2982 | #ifdef CONFIG_SPARC | 3025 | #ifdef CONFIG_SPARC |
2983 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); | 3026 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); |
2984 | #else | 3027 | #else |
@@ -3006,15 +3049,15 @@ static int __init serial8250_init(void) | |||
3006 | goto out; | 3049 | goto out; |
3007 | 3050 | ||
3008 | platform_device_del(serial8250_isa_devs); | 3051 | platform_device_del(serial8250_isa_devs); |
3009 | put_dev: | 3052 | put_dev: |
3010 | platform_device_put(serial8250_isa_devs); | 3053 | platform_device_put(serial8250_isa_devs); |
3011 | unreg_uart_drv: | 3054 | unreg_uart_drv: |
3012 | #ifdef CONFIG_SPARC | 3055 | #ifdef CONFIG_SPARC |
3013 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3056 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
3014 | #else | 3057 | #else |
3015 | uart_unregister_driver(&serial8250_reg); | 3058 | uart_unregister_driver(&serial8250_reg); |
3016 | #endif | 3059 | #endif |
3017 | out: | 3060 | out: |
3018 | return ret; | 3061 | return ret; |
3019 | } | 3062 | } |
3020 | 3063 | ||
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 90b56c2c31e2..71562689116f 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
512 | int ret = 0; | 512 | int ret = 0; |
513 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 513 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
514 | ret = -EINVAL; | 514 | ret = -EINVAL; |
515 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 515 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
516 | ret = -EINVAL; | 516 | ret = -EINVAL; |
517 | if (ser->baud_base < 9600) | 517 | if (ser->baud_base < 9600) |
518 | ret = -EINVAL; | 518 | ret = -EINVAL; |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 9d08f27208a1..b7180046f8db 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
572 | int ret = 0; | 572 | int ret = 0; |
573 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 573 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
574 | ret = -EINVAL; | 574 | ret = -EINVAL; |
575 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 575 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
576 | ret = -EINVAL; | 576 | ret = -EINVAL; |
577 | if (ser->baud_base < 9600) | 577 | if (ser->baud_base < 9600) |
578 | ret = -EINVAL; | 578 | ret = -EINVAL; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a6c4d744495e..bde4b4b0b80f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -623,7 +623,7 @@ static int cpm_uart_verify_port(struct uart_port *port, | |||
623 | 623 | ||
624 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) | 624 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) |
625 | ret = -EINVAL; | 625 | ret = -EINVAL; |
626 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 626 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
627 | ret = -EINVAL; | 627 | ret = -EINVAL; |
628 | if (ser->baud_base < 9600) | 628 | if (ser->baud_base < 9600) |
629 | ret = -EINVAL; | 629 | ret = -EINVAL; |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 23d030511019..611c97a15654 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct uart_port *port, int flags) | |||
922 | static int | 922 | static int |
923 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) | 923 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) |
924 | { | 924 | { |
925 | if (ser->irq >= NR_IRQS || ser->irq < 0 || | 925 | if (ser->irq >= nr_irqs || ser->irq < 0 || |
926 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | 926 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || |
927 | ser->type >= ARRAY_SIZE(uart_config)) | 927 | ser->type >= ARRAY_SIZE(uart_config)) |
928 | return -EINVAL; | 928 | return -EINVAL; |
@@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void) | |||
1162 | 1162 | ||
1163 | printk(KERN_INFO "Serial: M32R SIO driver\n"); | 1163 | printk(KERN_INFO "Serial: M32R SIO driver\n"); |
1164 | 1164 | ||
1165 | for (i = 0; i < NR_IRQS; i++) | 1165 | for (i = 0; i < nr_irqs; i++) |
1166 | spin_lock_init(&irq_lists[i].lock); | 1166 | spin_lock_init(&irq_lists[i].lock); |
1167 | 1167 | ||
1168 | ret = uart_register_driver(&m32r_sio_reg); | 1168 | ret = uart_register_driver(&m32r_sio_reg); |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 6bdf3362e3b1..874786a11fe9 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_state *state, | |||
741 | if (port->ops->verify_port) | 741 | if (port->ops->verify_port) |
742 | retval = port->ops->verify_port(port, &new_serial); | 742 | retval = port->ops->verify_port(port, &new_serial); |
743 | 743 | ||
744 | if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || | 744 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || |
745 | (new_serial.baud_base < 9600)) | 745 | (new_serial.baud_base < 9600)) |
746 | retval = -EINVAL; | 746 | retval = -EINVAL; |
747 | 747 | ||
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index cb49a5ac022f..61dc8b3daa26 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struct uart_port* port, | |||
460 | 460 | ||
461 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) | 461 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) |
462 | ret = -EINVAL; | 462 | ret = -EINVAL; |
463 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 463 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
464 | ret = -EINVAL; | 464 | ret = -EINVAL; |
465 | if (ser->baud_base < 9600) /* *** FIXME: is this true? */ | 465 | if (ser->baud_base < 9600) /* *** FIXME: is this true? */ |
466 | ret = -EINVAL; | 466 | ret = -EINVAL; |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 3b9d2d83b590..f0658d2c45b2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1149,7 +1149,7 @@ static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1149 | { | 1149 | { |
1150 | struct sci_port *s = &sci_ports[port->line]; | 1150 | struct sci_port *s = &sci_ports[port->line]; |
1151 | 1151 | ||
1152 | if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS) | 1152 | if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) |
1153 | return -EINVAL; | 1153 | return -EINVAL; |
1154 | if (ser->baud_base < 2400) | 1154 | if (ser->baud_base < 2400) |
1155 | /* No paper tape reader for Mitch.. */ | 1155 | /* No paper tape reader for Mitch.. */ |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 539c933b335f..315a9333ca3c 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uart_port *port, | |||
1066 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) | 1066 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) |
1067 | return -EINVAL; | 1067 | return -EINVAL; |
1068 | 1068 | ||
1069 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 1069 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
1070 | return -EINVAL; | 1070 | return -EINVAL; |
1071 | 1071 | ||
1072 | if (ser->baud_base < 9600) | 1072 | if (ser->baud_base < 9600) |
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/video/imacfb.c +++ /dev/null | |||
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 05a28106e8eb..8782ec1f5aa0 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -154,7 +154,7 @@ static int ibwdt_set_heartbeat(int t) | |||
154 | return -EINVAL; | 154 | return -EINVAL; |
155 | 155 | ||
156 | for (i = 0x0F; i > -1; i--) | 156 | for (i = 0x0F; i > -1; i--) |
157 | if (wd_times[i] > t) | 157 | if (wd_times[i] >= t) |
158 | break; | 158 | break; |
159 | wd_margin = i; | 159 | wd_margin = i; |
160 | return 0; | 160 | return 0; |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c3290bc186a0..9ce1ab6c268d 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -125,7 +125,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
125 | 125 | ||
126 | BUG_ON(irq == -1); | 126 | BUG_ON(irq == -1); |
127 | #ifdef CONFIG_SMP | 127 | #ifdef CONFIG_SMP |
128 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); | 128 | irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu); |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); | 131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); |
@@ -137,10 +137,12 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
137 | static void init_evtchn_cpu_bindings(void) | 137 | static void init_evtchn_cpu_bindings(void) |
138 | { | 138 | { |
139 | #ifdef CONFIG_SMP | 139 | #ifdef CONFIG_SMP |
140 | struct irq_desc *desc; | ||
140 | int i; | 141 | int i; |
142 | |||
141 | /* By default all event channels notify CPU#0. */ | 143 | /* By default all event channels notify CPU#0. */ |
142 | for (i = 0; i < NR_IRQS; i++) | 144 | for_each_irq_desc(i, desc) |
143 | irq_desc[i].affinity = cpumask_of_cpu(0); | 145 | desc->affinity = cpumask_of_cpu(0); |
144 | #endif | 146 | #endif |
145 | 147 | ||
146 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); | 148 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); |
@@ -229,12 +231,12 @@ static int find_unbound_irq(void) | |||
229 | int irq; | 231 | int irq; |
230 | 232 | ||
231 | /* Only allocate from dynirq range */ | 233 | /* Only allocate from dynirq range */ |
232 | for (irq = 0; irq < NR_IRQS; irq++) | 234 | for_each_irq_nr(irq) |
233 | if (irq_bindcount[irq] == 0) | 235 | if (irq_bindcount[irq] == 0) |
234 | break; | 236 | break; |
235 | 237 | ||
236 | if (irq == NR_IRQS) | 238 | if (irq == nr_irqs) |
237 | panic("No available IRQ to bind to: increase NR_IRQS!\n"); | 239 | panic("No available IRQ to bind to: increase nr_irqs!\n"); |
238 | 240 | ||
239 | return irq; | 241 | return irq; |
240 | } | 242 | } |
@@ -790,7 +792,7 @@ void xen_irq_resume(void) | |||
790 | mask_evtchn(evtchn); | 792 | mask_evtchn(evtchn); |
791 | 793 | ||
792 | /* No IRQ <-> event-channel mappings. */ | 794 | /* No IRQ <-> event-channel mappings. */ |
793 | for (irq = 0; irq < NR_IRQS; irq++) | 795 | for_each_irq_nr(irq) |
794 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ | 796 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ |
795 | 797 | ||
796 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) | 798 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) |
@@ -822,7 +824,7 @@ void __init xen_init_IRQ(void) | |||
822 | mask_evtchn(i); | 824 | mask_evtchn(i); |
823 | 825 | ||
824 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ | 826 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ |
825 | for (i = 0; i < NR_IRQS; i++) | 827 | for_each_irq_nr(i) |
826 | irq_bindcount[i] = 0; | 828 | irq_bindcount[i] = 0; |
827 | 829 | ||
828 | irq_ctx_init(smp_processor_id()); | 830 | irq_ctx_init(smp_processor_id()); |