Commit a37f6b84 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6:
  ide cs5520: Initialize second port's interrupt number.
  ide: improve handling of Power Management requests
  ide: add QUANTUM FIREBALLct20 30 with firmware APL.090 to ivb_list[]
  ide: relax DMA info validity checking
  ide-cd: Improve "weird block size" error message
  ide-cd: Don't warn on bogus block size unless it actually matters.
  ide: fix handling of unexpected IRQs vs request_irq()
parents 9d73777e d7e2f36d
...@@ -135,6 +135,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic ...@@ -135,6 +135,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
hw[0].irq = 14; hw[0].irq = 14;
hw[1].irq = 15;
return ide_host_add(d, hws, 2, NULL); return ide_host_add(d, hws, 2, NULL);
} }
......
...@@ -876,9 +876,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, ...@@ -876,9 +876,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
return stat; return stat;
/* /*
* Sanity check the given block size * Sanity check the given block size, in so far as making
* sure the sectors_per_frame we give to the caller won't
* end up being bogus.
*/ */
blocklen = be32_to_cpu(capbuf.blocklen); blocklen = be32_to_cpu(capbuf.blocklen);
blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
switch (blocklen) { switch (blocklen) {
case 512: case 512:
case 1024: case 1024:
...@@ -886,10 +889,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, ...@@ -886,10 +889,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
case 4096: case 4096:
break; break;
default: default:
printk(KERN_ERR PFX "%s: weird block size %u\n", printk_once(KERN_ERR PFX "%s: weird block size %u; "
"setting default block size to 2048\n",
drive->name, blocklen); drive->name, blocklen);
printk(KERN_ERR PFX "%s: default to 2kb block size\n",
drive->name);
blocklen = 2048; blocklen = 2048;
break; break;
} }
......
...@@ -361,9 +361,6 @@ static int ide_tune_dma(ide_drive_t *drive) ...@@ -361,9 +361,6 @@ static int ide_tune_dma(ide_drive_t *drive)
if (__ide_dma_bad_drive(drive)) if (__ide_dma_bad_drive(drive))
return 0; return 0;
if (ide_id_dma_bug(drive))
return 0;
if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
return config_drive_for_dma(drive); return config_drive_for_dma(drive);
...@@ -394,24 +391,6 @@ static int ide_dma_check(ide_drive_t *drive) ...@@ -394,24 +391,6 @@ static int ide_dma_check(ide_drive_t *drive)
return -1; return -1;
} }
int ide_id_dma_bug(ide_drive_t *drive)
{
u16 *id = drive->id;
if (id[ATA_ID_FIELD_VALID] & 4) {
if ((id[ATA_ID_UDMA_MODES] >> 8) &&
(id[ATA_ID_MWDMA_MODES] >> 8))
goto err_out;
} else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
(id[ATA_ID_SWDMA_MODES] >> 8))
goto err_out;
return 0;
err_out:
printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
return 1;
}
int ide_set_dma(ide_drive_t *drive) int ide_set_dma(ide_drive_t *drive)
{ {
int rc; int rc;
......
...@@ -476,10 +476,14 @@ void do_ide_request(struct request_queue *q) ...@@ -476,10 +476,14 @@ void do_ide_request(struct request_queue *q)
if (!ide_lock_port(hwif)) { if (!ide_lock_port(hwif)) {
ide_hwif_t *prev_port; ide_hwif_t *prev_port;
WARN_ON_ONCE(hwif->rq);
repeat: repeat:
prev_port = hwif->host->cur_port; prev_port = hwif->host->cur_port;
if (drive->dev_flags & IDE_DFLAG_BLOCKED)
rq = hwif->rq;
else
WARN_ON_ONCE(hwif->rq);
if (drive->dev_flags & IDE_DFLAG_SLEEPING && if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) { time_after(drive->sleep, jiffies)) {
ide_unlock_port(hwif); ide_unlock_port(hwif);
...@@ -506,43 +510,29 @@ void do_ide_request(struct request_queue *q) ...@@ -506,43 +510,29 @@ void do_ide_request(struct request_queue *q)
hwif->cur_dev = drive; hwif->cur_dev = drive;
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
if (rq == NULL) {
spin_unlock_irq(&hwif->lock); spin_unlock_irq(&hwif->lock);
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
/* /*
* we know that the queue isn't empty, but this can happen * we know that the queue isn't empty, but this can
* if the q->prep_rq_fn() decides to kill a request * happen if ->prep_rq_fn() decides to kill a request
*/ */
if (!rq)
rq = blk_fetch_request(drive->queue); rq = blk_fetch_request(drive->queue);
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
spin_lock_irq(&hwif->lock); spin_lock_irq(&hwif->lock);
if (!rq) { if (rq == NULL) {
ide_unlock_port(hwif); ide_unlock_port(hwif);
goto out; goto out;
} }
}
/* /*
* Sanity: don't accept a request that isn't a PM request * Sanity: don't accept a request that isn't a PM request
* if we are currently power managed. This is very important as * if we are currently power managed.
* blk_stop_queue() doesn't prevent the blk_fetch_request()
* above to return us whatever is in the queue. Since we call
* ide_do_request() ourselves, we end up taking requests while
* the queue is blocked...
*
* We let requests forced at head of queue with ide-preempt
* though. I hope that doesn't happen too much, hopefully not
* unless the subdriver triggers such a thing in its own PM
* state machine.
*/ */
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
blk_pm_request(rq) == 0 && blk_pm_request(rq) == 0);
(rq->cmd_flags & REQ_PREEMPT) == 0) {
/* there should be no pending command at this point */
ide_unlock_port(hwif);
goto plug_device;
}
hwif->rq = rq; hwif->rq = rq;
......
...@@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); ...@@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list);
*/ */
static const struct drive_list_entry ivb_list[] = { static const struct drive_list_entry ivb_list[] = {
{ "QUANTUM FIREBALLlct10 05" , "A03.0900" }, { "QUANTUM FIREBALLlct10 05" , "A03.0900" },
{ "QUANTUM FIREBALLlct20 30" , "APL.0900" },
{ "TSSTcorp CDDVDW SH-S202J" , "SB00" }, { "TSSTcorp CDDVDW SH-S202J" , "SB00" },
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202J" , "SB01" },
{ "TSSTcorp CDDVDW SH-S202N" , "SB00" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" },
...@@ -329,9 +330,6 @@ int ide_driveid_update(ide_drive_t *drive) ...@@ -329,9 +330,6 @@ int ide_driveid_update(ide_drive_t *drive)
kfree(id); kfree(id);
if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive))
ide_dma_off(drive);
return 1; return 1;
out_err: out_err:
if (rc == 2) if (rc == 2)
......
...@@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) ...@@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
return j; return j;
} }
static void ide_host_enable_irqs(struct ide_host *host)
{
ide_hwif_t *hwif;
int i;
ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
/* clear any pending IRQs */
hwif->tp_ops->read_status(hwif);
/* unmask IRQs */
if (hwif->io_ports.ctl_addr)
hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
}
}
/* /*
* This routine sets up the IRQ for an IDE interface. * This routine sets up the IRQ for an IDE interface.
*/ */
...@@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif)
if (irq_handler == NULL) if (irq_handler == NULL)
irq_handler = ide_intr; irq_handler = ide_intr;
if (io_ports->ctl_addr)
hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up; goto out_up;
...@@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ...@@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_port_tune_devices(hwif); ide_port_tune_devices(hwif);
} }
ide_host_enable_irqs(host);
ide_host_for_each_port(i, hwif, host) { ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL) if (hwif == NULL)
continue; continue;
......
...@@ -1361,7 +1361,6 @@ int ide_in_drive_list(u16 *, const struct drive_list_entry *); ...@@ -1361,7 +1361,6 @@ int ide_in_drive_list(u16 *, const struct drive_list_entry *);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
int ide_dma_good_drive(ide_drive_t *); int ide_dma_good_drive(ide_drive_t *);
int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_bad_drive(ide_drive_t *);
int ide_id_dma_bug(ide_drive_t *);
u8 ide_find_dma_mode(ide_drive_t *, u8); u8 ide_find_dma_mode(ide_drive_t *, u8);
...@@ -1402,7 +1401,6 @@ void ide_dma_lost_irq(ide_drive_t *); ...@@ -1402,7 +1401,6 @@ void ide_dma_lost_irq(ide_drive_t *);
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int); ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int);
#else #else
static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; } static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment