Skip to content

Commit

Permalink
fix jvc cdrom drive lockup
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: Greg KH <[email protected]>
Cc: Bartlomiej Zolnierkiewicz <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Zhang, Yanmin authored and Linus Torvalds committed Jul 16, 2007
1 parent 012bfdf commit ed4aaad
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
12 changes: 12 additions & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ EXPORT_SYMBOL(pci_root_buses);

LIST_HEAD(pci_devices);

/*
* Some device drivers need know if pci is initiated.
* Basically, we think pci is not initiated when there
* is no device in list of pci_devices.
*/
int no_pci_devices(void)
{
return list_empty(&pci_devices);
}

EXPORT_SYMBOL(no_pci_devices);

#ifdef HAVE_PCI_LEGACY
/**
* pci_create_legacy_files - create legacy I/O port and memory files
Expand Down
4 changes: 1 addition & 3 deletions include/asm-i386/ide.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,20 @@ static __inline__ int ide_default_irq(unsigned long base)

static __inline__ unsigned long ide_default_io_base(int index)
{
struct pci_dev *pdev;
/*
* If PCI is present then it is not safe to poke around
* the other legacy IDE ports. Only 0x1f0 and 0x170 are
* defined compatibility mode ports for PCI. A user can
* override this using ide= but we must default safe.
*/
if ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL)) == NULL) {
if (no_pci_devices()) {
switch(index) {
case 2: return 0x1e8;
case 3: return 0x168;
case 4: return 0x1e0;
case 5: return 0x160;
}
}
pci_dev_put(pdev);
switch (index) {
case 0: return 0x1f0;
case 1: return 0x170;
Expand Down
3 changes: 3 additions & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ extern struct bus_type pci_bus_type;
* code, or pci core code. */
extern struct list_head pci_root_buses; /* list of all known PCI buses */
extern struct list_head pci_devices; /* list of all devices */
/* Some device drivers need know if pci is initiated */
extern int no_pci_devices(void);

void pcibios_fixup_bus(struct pci_bus *);
int __must_check pcibios_enable_device(struct pci_dev *, int mask);
Expand Down Expand Up @@ -724,6 +726,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *
{ return NULL; }

#define pci_dev_present(ids) (0)
#define no_pci_devices() (1)
#define pci_find_present(ids) (NULL)
#define pci_dev_put(dev) do { } while (0)

Expand Down

0 comments on commit ed4aaad

Please sign in to comment.