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
@ -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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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 @@ repeat:
|
|||||||
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);
|
||||||
|
|
||||||
spin_unlock_irq(&hwif->lock);
|
if (rq == NULL) {
|
||||||
spin_lock_irq(q->queue_lock);
|
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
|
* we know that the queue isn't empty, but this can
|
||||||
*/
|
* 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_lock_irq(&hwif->lock);
|
||||||
|
|
||||||
spin_unlock_irq(q->queue_lock);
|
if (rq == NULL) {
|
||||||
spin_lock_irq(&hwif->lock);
|
ide_unlock_port(hwif);
|
||||||
|
goto out;
|
||||||
if (!rq) {
|
}
|
||||||
ide_unlock_port(hwif);
|
|
||||||
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);
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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 *);
|
|||||||
#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 *);
|
|||||||
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) { ; }
|
||||||
|
Loading…
Reference in New Issue
Block a user