mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
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()
This commit is contained in:
commit
a37f6b84c4
7 changed files with 50 additions and 65 deletions
|
@ -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]);
|
||||
hw[0].irq = 14;
|
||||
hw[1].irq = 15;
|
||||
|
||||
return ide_host_add(d, hws, 2, NULL);
|
||||
}
|
||||
|
|
|
@ -876,9 +876,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
|
|||
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 = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
|
||||
switch (blocklen) {
|
||||
case 512:
|
||||
case 1024:
|
||||
|
@ -886,10 +889,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
|
|||
case 4096:
|
||||
break;
|
||||
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);
|
||||
printk(KERN_ERR PFX "%s: default to 2kb block size\n",
|
||||
drive->name);
|
||||
blocklen = 2048;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -361,9 +361,6 @@ static int ide_tune_dma(ide_drive_t *drive)
|
|||
if (__ide_dma_bad_drive(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_id_dma_bug(drive))
|
||||
return 0;
|
||||
|
||||
if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
|
||||
return config_drive_for_dma(drive);
|
||||
|
||||
|
@ -394,24 +391,6 @@ static int ide_dma_check(ide_drive_t *drive)
|
|||
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 rc;
|
||||
|
|
|
@ -476,10 +476,14 @@ void do_ide_request(struct request_queue *q)
|
|||
|
||||
if (!ide_lock_port(hwif)) {
|
||||
ide_hwif_t *prev_port;
|
||||
|
||||
WARN_ON_ONCE(hwif->rq);
|
||||
repeat:
|
||||
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 &&
|
||||
time_after(drive->sleep, jiffies)) {
|
||||
ide_unlock_port(hwif);
|
||||
|
@ -506,43 +510,29 @@ repeat:
|
|||
hwif->cur_dev = drive;
|
||||
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
|
||||
|
||||
spin_unlock_irq(&hwif->lock);
|
||||
spin_lock_irq(q->queue_lock);
|
||||
/*
|
||||
* we know that the queue isn't empty, but this can happen
|
||||
* if the q->prep_rq_fn() decides to kill a request
|
||||
*/
|
||||
if (!rq)
|
||||
if (rq == NULL) {
|
||||
spin_unlock_irq(&hwif->lock);
|
||||
spin_lock_irq(q->queue_lock);
|
||||
/*
|
||||
* we know that the queue isn't empty, but this can
|
||||
* happen if ->prep_rq_fn() decides to kill a request
|
||||
*/
|
||||
rq = blk_fetch_request(drive->queue);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
spin_lock_irq(&hwif->lock);
|
||||
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
spin_lock_irq(&hwif->lock);
|
||||
|
||||
if (!rq) {
|
||||
ide_unlock_port(hwif);
|
||||
goto out;
|
||||
if (rq == NULL) {
|
||||
ide_unlock_port(hwif);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity: don't accept a request that isn't a PM request
|
||||
* if we are currently power managed. This is very important as
|
||||
* 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 we are currently power managed.
|
||||
*/
|
||||
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
|
||||
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;
|
||||
}
|
||||
BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
|
||||
blk_pm_request(rq) == 0);
|
||||
|
||||
hwif->rq = rq;
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list);
|
|||
*/
|
||||
static const struct drive_list_entry ivb_list[] = {
|
||||
{ "QUANTUM FIREBALLlct10 05" , "A03.0900" },
|
||||
{ "QUANTUM FIREBALLlct20 30" , "APL.0900" },
|
||||
{ "TSSTcorp CDDVDW SH-S202J" , "SB00" },
|
||||
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" },
|
||||
{ "TSSTcorp CDDVDW SH-S202N" , "SB00" },
|
||||
|
@ -329,9 +330,6 @@ int ide_driveid_update(ide_drive_t *drive)
|
|||
|
||||
kfree(id);
|
||||
|
||||
if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive))
|
||||
ide_dma_off(drive);
|
||||
|
||||
return 1;
|
||||
out_err:
|
||||
if (rc == 2)
|
||||
|
|
|
@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
|
|||
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.
|
||||
*/
|
||||
|
@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif)
|
|||
if (irq_handler == NULL)
|
||||
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))
|
||||
goto out_up;
|
||||
|
||||
|
@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
|
|||
ide_port_tune_devices(hwif);
|
||||
}
|
||||
|
||||
ide_host_enable_irqs(host);
|
||||
|
||||
ide_host_for_each_port(i, hwif, host) {
|
||||
if (hwif == NULL)
|
||||
continue;
|
||||
|
|
|
@ -1361,7 +1361,6 @@ int ide_in_drive_list(u16 *, const struct drive_list_entry *);
|
|||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
int ide_dma_good_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);
|
||||
|
||||
|
@ -1402,7 +1401,6 @@ void ide_dma_lost_irq(ide_drive_t *);
|
|||
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int);
|
||||
|
||||
#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_max_dma_mode(ide_drive_t *drive) { return 0; }
|
||||
static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; }
|
||||
|
|
Loading…
Reference in a new issue