diff options
author | Zhang, Yanmin <yanmin_zhang@linux.intel.com> | 2007-07-16 02:39:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:40 -0400 |
commit | ed4aaadb1a7913f509f05d3e67840541a180713f (patch) | |
tree | 7089fd2fe0f56d552ea153e2925363d0febaa952 | |
parent | 012bfdf00ce2f36a1add75a0d18303656c6294ef (diff) |
fix jvc cdrom drive lockup
Before calling init_hwif_default, ide_unregister gets lock ide_lock and
disables irq. init_hwif_default calls ide_default_io_base which calls
pci_get_device and later pci_get_subsys tries to apply for semaphore
pci_bus_sem and goes to sleep.
Mostly, pci_get_device should be called when irq is turned on.
ide_default_io_base just needs find if list pci_devices is empty.
Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
Cc: Greg KH <greg@kroah.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/pci/probe.c | 12 | ||||
-rw-r--r-- | include/asm-i386/ide.h | 4 | ||||
-rw-r--r-- | include/linux/pci.h | 3 |
3 files changed, 16 insertions, 3 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a7bce75c6732..34b8dae0d90f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -22,6 +22,18 @@ EXPORT_SYMBOL(pci_root_buses); | |||
22 | 22 | ||
23 | LIST_HEAD(pci_devices); | 23 | LIST_HEAD(pci_devices); |
24 | 24 | ||
25 | /* | ||
26 | * Some device drivers need know if pci is initiated. | ||
27 | * Basically, we think pci is not initiated when there | ||
28 | * is no device in list of pci_devices. | ||
29 | */ | ||
30 | int no_pci_devices(void) | ||
31 | { | ||
32 | return list_empty(&pci_devices); | ||
33 | } | ||
34 | |||
35 | EXPORT_SYMBOL(no_pci_devices); | ||
36 | |||
25 | #ifdef HAVE_PCI_LEGACY | 37 | #ifdef HAVE_PCI_LEGACY |
26 | /** | 38 | /** |
27 | * pci_create_legacy_files - create legacy I/O port and memory files | 39 | * pci_create_legacy_files - create legacy I/O port and memory files |
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h index 0fc240c80f49..e7817a3d6578 100644 --- a/include/asm-i386/ide.h +++ b/include/asm-i386/ide.h | |||
@@ -40,14 +40,13 @@ static __inline__ int ide_default_irq(unsigned long base) | |||
40 | 40 | ||
41 | static __inline__ unsigned long ide_default_io_base(int index) | 41 | static __inline__ unsigned long ide_default_io_base(int index) |
42 | { | 42 | { |
43 | struct pci_dev *pdev; | ||
44 | /* | 43 | /* |
45 | * If PCI is present then it is not safe to poke around | 44 | * If PCI is present then it is not safe to poke around |
46 | * the other legacy IDE ports. Only 0x1f0 and 0x170 are | 45 | * the other legacy IDE ports. Only 0x1f0 and 0x170 are |
47 | * defined compatibility mode ports for PCI. A user can | 46 | * defined compatibility mode ports for PCI. A user can |
48 | * override this using ide= but we must default safe. | 47 | * override this using ide= but we must default safe. |
49 | */ | 48 | */ |
50 | if ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL)) == NULL) { | 49 | if (no_pci_devices()) { |
51 | switch(index) { | 50 | switch(index) { |
52 | case 2: return 0x1e8; | 51 | case 2: return 0x1e8; |
53 | case 3: return 0x168; | 52 | case 3: return 0x168; |
@@ -55,7 +54,6 @@ static __inline__ unsigned long ide_default_io_base(int index) | |||
55 | case 5: return 0x160; | 54 | case 5: return 0x160; |
56 | } | 55 | } |
57 | } | 56 | } |
58 | pci_dev_put(pdev); | ||
59 | switch (index) { | 57 | switch (index) { |
60 | case 0: return 0x1f0; | 58 | case 0: return 0x1f0; |
61 | case 1: return 0x170; | 59 | case 1: return 0x170; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 37a71580ad8a..5e84f2e8d54c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -432,6 +432,8 @@ extern struct bus_type pci_bus_type; | |||
432 | * code, or pci core code. */ | 432 | * code, or pci core code. */ |
433 | extern struct list_head pci_root_buses; /* list of all known PCI buses */ | 433 | extern struct list_head pci_root_buses; /* list of all known PCI buses */ |
434 | extern struct list_head pci_devices; /* list of all devices */ | 434 | extern struct list_head pci_devices; /* list of all devices */ |
435 | /* Some device drivers need know if pci is initiated */ | ||
436 | extern int no_pci_devices(void); | ||
435 | 437 | ||
436 | void pcibios_fixup_bus(struct pci_bus *); | 438 | void pcibios_fixup_bus(struct pci_bus *); |
437 | int __must_check pcibios_enable_device(struct pci_dev *, int mask); | 439 | int __must_check pcibios_enable_device(struct pci_dev *, int mask); |
@@ -724,6 +726,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev * | |||
724 | { return NULL; } | 726 | { return NULL; } |
725 | 727 | ||
726 | #define pci_dev_present(ids) (0) | 728 | #define pci_dev_present(ids) (0) |
729 | #define no_pci_devices() (1) | ||
727 | #define pci_find_present(ids) (NULL) | 730 | #define pci_find_present(ids) (NULL) |
728 | #define pci_dev_put(dev) do { } while (0) | 731 | #define pci_dev_put(dev) do { } while (0) |
729 | 732 | ||