IDE updates part 3
Subsystems (2)
Hi,
The last part of IDE changes for 2.6.31 merge window:
* Fix ide-cd OOPSing on failed commands. (Rainer Weikusat)
* IORDY handling fixes.
* Sanitize methods for IRQ clearing/testing. (Sergei Shtylyov)
* ATAPI support update. (Borislav Petkov)
* Misc fixes/cleanups.
Linus, please pull from 'for-2.6.31' branch of:
master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git for-2.6.31
to receive the following updates:
drivers/ide/at91_ide.c | 3 +- drivers/ide/buddha.c | 40 +++++---- drivers/ide/cmd640.c | 13 +++ drivers/ide/cmd64x.c | 103 +++++++--------------- drivers/ide/cs5536.c | 23 +++-- drivers/ide/falconide.c | 1 - drivers/ide/gayle.c | 33 ++++--- drivers/ide/ht6560b.c | 33 +++++-- drivers/ide/icside.c | 10 ++- drivers/ide/ide-atapi.c | 138 +++++++++++++++++++----------- drivers/ide/ide-cd.c | 78 +++-------------- drivers/ide/ide-disk.c | 9 +-- drivers/ide/ide-floppy.c | 56 +++++------- drivers/ide/ide-floppy_ioctl.c | 43 +++++----- drivers/ide/ide-io.c | 8 +- drivers/ide/ide-ioctls.c | 13 +-- drivers/ide/ide-probe.c | 17 +++- drivers/ide/ide-tape.c | 186 ++++++++++++++++++---------------------- drivers/ide/ide-xfer-mode.c | 12 +++ drivers/ide/it8172.c | 2 +- drivers/ide/it8213.c | 2 +- drivers/ide/macide.c | 30 ++++--- drivers/ide/opti621.c | 8 +- drivers/ide/pdc202xx_old.c | 24 +++++- drivers/ide/piix.c | 2 +- drivers/ide/q40ide.c | 7 +- drivers/ide/qd65xx.c | 11 ++- drivers/ide/qd65xx.h | 11 ++- drivers/ide/sgiioc4.c | 119 ++++++++++++-------------- drivers/ide/siimage.c | 42 +++------ drivers/ide/sl82c105.c | 32 +++++-- drivers/ide/slc90e66.c | 2 +- include/linux/ata.h | 14 +++ include/linux/ide.h | 47 +++++----- 34 files changed, 598 insertions(+), 574 deletions(-)
Bartlomiej Zolnierkiewicz (7):
Merge branch 'bp-remove-pc-buf' into for-next
ata: add ata_id_pio_need_iordy() helper (v2)
ide: IORDY handling fixes
ide: don't enable IORDY at a probe time
ide: filter out invalid DMA xfer mode changes in HDIO_DRIVE_CMD ioctl handler
ide: BUG() on unknown requests
Merge branch 'for-2.6.31' into 2.6.31
Borislav Petkov (16):
ide-tape: fix potential fs requests bug
ide-atapi: switch to blk_rq_bytes() on do_request() path
ide-atapi: switch to rq->resid_len
ide-atapi: add a len-parameter to ide_queue_pc_tail
ide-atapi: add a buffer-arg to ide_queue_pc_tail ide-floppy/ide_floppy_get_flexible_disk_page: use local buffer ide-floppy/ide_floppy_get_sfrp_bit: use local buffer ide-floppy/ide_floppy_format_unit: use local buffer
ide-atapi: use local sense buffer ide-floppy/ide_floppy_get_format_progress: use local sense buffer ide-tape/ide_tape_get_bsize_from_bdesc: use local buffer
ide-tape: fix READ POSITION cmd handling
ide-atapi: remove pc->buf
ide-cd: use whole request_sense buffer in EH
ide: unify interrupt reason checking
ide-tape: fix build issue
Joao Ramos (1):
ide: do not access ide_drive_t 'drive_data' field directly
Rainer Weikusat (1):
ide-cd: prevent null pointer deref via cdrom_newpc_intr
Sergei Shtylyov (11):
sgiioc4: coding style cleanup
ide: call clear_irq() method in ide_timer_expiry()
cmd64x: implement clear_irq() method (take 2)
siimage: use ide_dma_test_irq() (take 2)
ide: move IRQ clearing from ack_intr() method to clear_irq() method (take 2)
ide: move ack_intr() method into 'struct ide_port_ops' (take 2)
cmd640: implement test_irq() method
cmd64x: implement test_irq() method
pdc202xx_old: implement test_irq() method (take 2)
siimage: implement test_irq() method
sl82c105: implement test_irq() method
drivers/ide/at91_ide.c +1 -2
@@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) timing =ide_timing_find_mode (XFER_PIO_0 + pio);BUG_ON (!timing); -if ((pio >2 ||ata_id_has_iordy (drive->id)) && - !(ata_id_is_cfa (drive->id) && pio >4 )) +if (ide_pio_need_iordy (drive, pio)) use_iordy =1 ;apply_timings (chipselect, pio, timing, use_iordy);
drivers/ide/buddha.c +21 -19
@@ -99,7 +99,7 @@ static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };* Check and acknowledge the interrupt status */ -static int buddha_ack_intr (ide_hwif_t *hwif) +static int buddha_test_irq (ide_hwif_t *hwif) {unsigned char ch;
@@ -109,21 +109,16 @@ static int buddha_ack_intr(ide_hwif_t *hwif)return 1 ; } -static int xsurf_ack_intr (ide_hwif_t *hwif) +static void xsurf_clear_irq (ide_drive_t *drive) { -unsigned char ch; - - ch =z_readb (hwif->io_ports.irq_addr); -/* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ -z_writeb (0 , hwif->io_ports.irq_addr); -if (!(ch &0x80 )) -return 0 ; -return 1 ; +/* +* X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0 +*/ +z_writeb (0 , drive->hwif->io_ports.irq_addr); }static void __init buddha_setup_ports (struct ide_hw *hw,unsigned long base, -unsigned long ctl,unsigned long irq_port, -ide_ack_intr_t *ack_intr) +unsigned long ctl,unsigned long irq_port) {int i;
@@ -138,10 +133,19 @@ static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base, hw->io_ports.irq_addr = irq_port; hw->irq =IRQ_AMIGA_PORTS ; - hw->ack_intr = ack_intr; } +static const struct ide_port_ops buddha_port_ops = { + .test_irq = buddha_test_irq, +}; + +static const struct ide_port_ops xsurf_port_ops = { + .clear_irq = xsurf_clear_irq, + .test_irq = buddha_test_irq, +}; +static const struct ide_port_info buddha_port_info = { + .port_ops = &buddha_port_ops, .host_flags =IDE_HFLAG_MMIO |IDE_HFLAG_NO_DMA , .irq_flags =IRQF_SHARED , .chipset = ide_generic,
@@ -161,6 +165,7 @@ static int __init buddha_init(void)while ((z =zorro_find_device (ZORRO_WILDCARD , z))) {unsigned long board;struct ide_hw hw[MAX_NUM_HWIFS ], *hws[MAX_NUM_HWIFS ]; +struct ide_port_info d = buddha_port_info;if (z->id ==ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA ) { buddha_num_hwifs =BUDDHA_NUM_HWIFS ;
@@ -171,6 +176,7 @@ static int __init buddha_init(void) }else if (z->id ==ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF ) { buddha_num_hwifs =XSURF_NUM_HWIFS ; type=BOARD_XSURF ; + d.port_ops = &xsurf_port_ops; }else continue ;
@@ -203,28 +209,24 @@ fail_base2:for (i =0 ; i < buddha_num_hwifs; i++) {unsigned long base, ctl, irq_port; -ide_ack_intr_t *ack_intr;if (type !=BOARD_XSURF ) { base = buddha_board + buddha_bases[i]; ctl = base +BUDDHA_CONTROL ; irq_port = buddha_board + buddha_irqports[i]; - ack_intr = buddha_ack_intr; }else { base = buddha_board + xsurf_bases[i];/* X-Surf has no CS1* (Control/AltStat) */ ctl =0 ; irq_port = buddha_board + xsurf_irqports[i]; - ack_intr = xsurf_ack_intr; } -buddha_setup_ports (&hw[i], base, ctl, irq_port, - ack_intr); +buddha_setup_ports (&hw[i], base, ctl, irq_port); hws[i] = &hw[i]; } -ide_host_add (&buddha_port_info, hws, i,NULL ); +ide_host_add (&d, hws, i,NULL ); }return 0 ;
drivers/ide/cmd640.c +13 -0
@@ -153,6 +153,7 @@ static int cmd640_vlb;#define ARTTIM23 0x57#define ARTTIM23_DIS_RA2 0x04#define ARTTIM23_DIS_RA3 0x08 +#define ARTTIM23_IDE23INTR 0x10#define DRWTIM23 0x58#define BRST 0x59
@@ -629,12 +630,24 @@ static void cmd640_init_dev(ide_drive_t *drive)#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ } +static int cmd640_test_irq (ide_hwif_t *hwif) +{ +struct pci_dev *dev =to_pci_dev (hwif->dev); +int irq_reg = hwif->channel ?ARTTIM23 :CFR ; +u8 irq_stat, irq_mask = hwif->channel ?ARTTIM23_IDE23INTR : +CFR_IDE01INTR ; + +pci_read_config_byte (dev, irq_reg, &irq_stat); + +return (irq_stat & irq_mask) ?1 :0 ; +}static const struct ide_port_ops cmd640_port_ops = { .init_dev = cmd640_init_dev, #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED .set_pio_mode = cmd640_set_pio_mode, #endif + .test_irq = cmd640_test_irq, };static int pci_conf1 (void )
drivers/ide/cmd64x.c +32 -71
217 lines not on this page · raw message
drivers/ide/cs5536.c +15 -8
@@ -146,14 +146,16 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)struct pci_dev *pdev =to_pci_dev (drive->hwif->dev);ide_drive_t *pair =ide_get_pair_dev (drive);int cshift = (drive->dn &1 ) ?IDE_CAST_D1_SHIFT :IDE_CAST_D0_SHIFT ; +unsigned long timings = (unsigned long )ide_get_drivedata (drive);u32 cast;u8 cmd_pio = pio;if (pair) cmd_pio =min (pio,ide_get_best_pio_mode (pair,255 ,4 )); - drive->drive_data &= (IDE_DRV_MASK <<8 ); - drive->drive_data |= drv_timings[pio]; + timings &= (IDE_DRV_MASK <<8 ); + timings |= drv_timings[pio]; +ide_set_drivedata (drive, (void *)timings);cs5536_program_dtc (drive, drv_timings[pio]);
@@ -186,6 +188,7 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)struct pci_dev *pdev =to_pci_dev (drive->hwif->dev);int dshift = (drive->dn &1 ) ?IDE_D1_SHIFT :IDE_D0_SHIFT ; +unsigned long timings = (unsigned long )ide_get_drivedata (drive);u32 etc;cs5536_read (pdev,ETC , &etc);
@@ -195,8 +198,9 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode) etc |= udma_timings[mode -XFER_UDMA_0 ] << dshift; }else {/* MWDMA */ etc &= ~(IDE_ETC_UDMA_MASK << dshift); - drive->drive_data &=IDE_DRV_MASK ; - drive->drive_data |= mwdma_timings[mode -XFER_MW_DMA_0 ] <<8 ; + timings &=IDE_DRV_MASK ; + timings |= mwdma_timings[mode -XFER_MW_DMA_0 ] <<8 ; +ide_set_drivedata (drive, (void *)timings); }cs5536_write (pdev,ETC , etc);
@@ -204,9 +208,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)static void cs5536_dma_start (ide_drive_t *drive) { +unsigned long timings = (unsigned long )ide_get_drivedata (drive); +if (drive->current_speed <XFER_UDMA_0 && - (drive->drive_data >>8 ) != (drive->drive_data &IDE_DRV_MASK )) -cs5536_program_dtc (drive, drive->drive_data >>8 ); + (timings >>8 ) != (timings &IDE_DRV_MASK )) +cs5536_program_dtc (drive, timings >>8 );ide_dma_start (drive); }
@@ -214,10 +220,11 @@ static void cs5536_dma_start(ide_drive_t *drive)static int cs5536_dma_end (ide_drive_t *drive) {int ret =ide_dma_end (drive); +unsigned long timings = (unsigned long )ide_get_drivedata (drive);if (drive->current_speed <XFER_UDMA_0 && - (drive->drive_data >>8 ) != (drive->drive_data &IDE_DRV_MASK )) -cs5536_program_dtc (drive, drive->drive_data &IDE_DRV_MASK ); + (timings >>8 ) != (timings &IDE_DRV_MASK )) +cs5536_program_dtc (drive, timings &IDE_DRV_MASK );return ret; }
drivers/ide/falconide.c +0 -1
@@ -128,7 +128,6 @@ static void __init falconide_setup_ports(struct ide_hw *hw) hw->io_ports.ctl_addr =ATA_HD_BASE +ATA_HD_CONTROL ; hw->irq =IRQ_MFP_IDE ; - hw->ack_intr =NULL ; }/*
drivers/ide/gayle.c +18 -15
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers");* Check and acknowledge the interrupt status */ -static int gayle_ack_intr_a4000 (ide_hwif_t *hwif) +static int gayle_test_irq (ide_hwif_t *hwif) {unsigned char ch;
@@ -76,21 +76,16 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif)return 1 ; } -static int gayle_ack_intr_a1200 (ide_hwif_t *hwif) +static void gayle_a1200_clear_irq (ide_drive_t *drive) { -unsigned char ch; +ide_hwif_t *hwif = drive->hwif; - ch =z_readb (hwif->io_ports.irq_addr); -if (!(ch &GAYLE_IRQ_IDE )) -return 0 ; (void )z_readb (hwif->io_ports.status_addr);z_writeb (0x7c , hwif->io_ports.irq_addr); -return 1 ; }static void __init gayle_setup_ports (struct ide_hw *hw,unsigned long base, -unsigned long ctl,unsigned long irq_port, -ide_ack_intr_t *ack_intr) +unsigned long ctl,unsigned long irq_port) {int i;
@@ -105,9 +100,17 @@ static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, hw->io_ports.irq_addr = irq_port; hw->irq =IRQ_AMIGA_PORTS ; - hw->ack_intr = ack_intr; } +static const struct ide_port_ops gayle_a4000_port_ops = { + .test_irq = gayle_test_irq, +}; + +static const struct ide_port_ops gayle_a1200_port_ops = { + .clear_irq = gayle_a1200_clear_irq, + .test_irq = gayle_test_irq, +}; +static const struct ide_port_info gayle_port_info = { .host_flags =IDE_HFLAG_MMIO |IDE_HFLAG_SERIALIZE |IDE_HFLAG_NO_DMA ,
@@ -123,9 +126,9 @@ static int __init gayle_init(void) {unsigned long phys_base, res_start, res_n;unsigned long base, ctrlport, irqport; -ide_ack_intr_t *ack_intr;int a4000, i, rc;struct ide_hw hw[GAYLE_NUM_HWIFS ], *hws[GAYLE_NUM_HWIFS ]; +struct ide_port_info d = gayle_port_info;if (!MACH_IS_AMIGA )return -ENODEV ;
@@ -148,11 +151,11 @@ found:if (a4000) { phys_base =GAYLE_BASE_4000 ; irqport = (unsigned long )ZTWO_VADDR (GAYLE_IRQ_4000 ); - ack_intr = gayle_ack_intr_a4000; + d.port_ops = &gayle_a4000_port_ops; }else { phys_base =GAYLE_BASE_1200 ; irqport = (unsigned long )ZTWO_VADDR (GAYLE_IRQ_1200 ); - ack_intr = gayle_ack_intr_a1200; + d.port_ops = &gayle_a1200_port_ops; } res_start = ((unsigned long )phys_base) & ~(GAYLE_NEXT_PORT -1 );
@@ -165,12 +168,12 @@ found: base = (unsigned long )ZTWO_VADDR (phys_base + i *GAYLE_NEXT_PORT ); ctrlport =GAYLE_HAS_CONTROL_REG ? (base +GAYLE_CONTROL ) :0 ; -gayle_setup_ports (&hw[i], base, ctrlport, irqport, ack_intr); +gayle_setup_ports (&hw[i], base, ctrlport, irqport); hws[i] = &hw[i]; } - rc =ide_host_add (&gayle_port_info, hws, i,NULL ); + rc =ide_host_add (&d, hws, i,NULL );if (rc)release_mem_region (res_start, res_n);
drivers/ide/ht6560b.c +24 -9
@@ -44,7 +44,12 @@* bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) */ #define HT_CONFIG_PORT 0x3e6 -#define HT_CONFIG (drivea) (u8)(((drivea)->drive_data & 0xff00) >> 8) + +static inline u8 HT_CONFIG (ide_drive_t *drive) +{ +return ((unsigned long )ide_get_drivedata (drive) &0xff00 ) >>8 ; +} +/* * FIFO + PREFETCH (both a/b-model) */
@@ -90,7 +95,11 @@* Active Time for each drive. Smaller value gives higher speed. * In case of failures you should probably fall back to a higher value. */ -#define HT_TIMING (drivea) (u8)((drivea)->drive_data & 0x00ff) +static inline u8 HT_TIMING (ide_drive_t *drive) +{ +return (unsigned long )ide_get_drivedata (drive) &0x00ff ; +} +#define HT_TIMING_DEFAULT 0xff/*
@@ -242,23 +251,27 @@ static DEFINE_SPINLOCK(ht6560b_lock);*/ static void ht_set_prefetch (ide_drive_t *drive,u8 state) { -unsigned long flags; +unsigned long flags, config;int t =HT_PREFETCH_MODE <<8 ;spin_lock_irqsave (&ht6560b_lock, flags); + config = (unsigned long )ide_get_drivedata (drive); +/* * Prefetch mode and unmask irq seems to conflict */ if (state) { - drive->drive_data |= t;/* enable prefetch mode */ + config |= t;/* enable prefetch mode */ drive->dev_flags |=IDE_DFLAG_NO_UNMASK ; drive->dev_flags &= ~IDE_DFLAG_UNMASK ; }else { - drive->drive_data &= ~t;/* disable prefetch mode */ + config &= ~t;/* disable prefetch mode */ drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK ; } +ide_set_drivedata (drive, (void *)config); +spin_unlock_irqrestore (&ht6560b_lock, flags);#ifdef DEBUG
@@ -268,7 +281,7 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)static void ht6560b_set_pio_mode (ide_drive_t *drive,const u8 pio) { -unsigned long flags; +unsigned long flags, config;u8 timing;switch (pio) {
@@ -281,8 +294,10 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) timing =ht_pio2timings (drive, pio);spin_lock_irqsave (&ht6560b_lock, flags); - drive->drive_data &=0xff00 ; - drive->drive_data |= timing; + config = (unsigned long )ide_get_drivedata (drive); + config &=0xff00 ; + config |= timing; +ide_set_drivedata (drive, (void *)config);spin_unlock_irqrestore (&ht6560b_lock, flags);#ifdef DEBUG
@@ -299,7 +314,7 @@ static void __init ht6560b_init_dev(ide_drive_t *drive)if (hwif->channel) t |= (HT_SECONDARY_IF <<8 ); - drive->drive_data = t; +ide_set_drivedata (drive, (void *)t); }static int probe_ht6560b;
drivers/ide/icside.c +6 -4
@@ -187,7 +187,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {*/ static void icside_set_dma_mode (ide_drive_t *drive,const u8 xfer_mode) { -int cycle_time, use_dma_info =0 ; +unsigned long cycle_time; +int use_dma_info =0 ;switch (xfer_mode) {case XFER_MW_DMA_2 :
@@ -218,10 +219,11 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME ] > cycle_time) cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME ]; - drive->drive_data = cycle_time; +ide_set_drivedata (drive, (void *)cycle_time);printk ("%s: %s selected (peak %dMB/s)\n" , drive->name, -ide_xfer_verbose (xfer_mode),2000 / drive->drive_data); +ide_xfer_verbose (xfer_mode), +2000 / (unsigned long )ide_get_drivedata (drive)); }static const struct ide_port_ops icside_v6_port_ops = {
@@ -277,7 +279,7 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)/* * Select the correct timing for this drive. */ -set_dma_speed (ec->dma, drive->drive_data); +set_dma_speed (ec->dma, (unsigned long )ide_get_drivedata (drive));/* * Tell the DMA engine about the SG table and
drivers/ide/ide-atapi.c +87 -51
297 lines not on this page · raw message
drivers/ide/ide-cd.c +14 -64
141 lines not on this page · raw message
drivers/ide/ide-disk.c +1 -8
@@ -184,14 +184,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,ide_hwif_t *hwif = drive->hwif;BUG_ON (drive->dev_flags &IDE_DFLAG_BLOCKED ); - -if (!blk_fs_request (rq)) { -blk_dump_rq_flags (rq,"ide_do_rw_disk - bad command" ); -if (rq->errors ==0 ) - rq->errors = -EIO ; -ide_complete_rq (drive, -EIO ,ide_rq_bytes (rq)); -return ide_stopped; - } +BUG_ON (!blk_fs_request (rq));ledtrig_ide_activity ();
drivers/ide/ide-floppy.c +24 -32
135 lines not on this page · raw message
drivers/ide/ide-floppy_ioctl.c +23 -20
112 lines not on this page · raw message
drivers/ide/ide-io.c +5 -3
@@ -683,8 +683,9 @@ void ide_timer_expiry (unsigned long data) }else if (drive_is_ready (drive)) {if (drive->waiting_for_dma) hwif->dma_ops->dma_lost_irq (drive); -if (hwif->ack_intr) - hwif->ack_intr (hwif); +if (hwif->port_ops && hwif->port_ops->clear_irq) + hwif->port_ops->clear_irq (drive); +printk (KERN_WARNING "%s: lost interrupt\n" , drive->name); startstop =handler (drive);
@@ -803,7 +804,8 @@ irqreturn_t ide_intr (int irq, void *dev_id)spin_lock_irqsave (&hwif->lock, flags); -if (hwif->ack_intr && hwif->ack_intr (hwif) ==0 ) +if (hwif->port_ops && hwif->port_ops->test_irq && + hwif->port_ops->test_irq (hwif) ==0 ) goto out; handler = hwif->handler;
drivers/ide/ide-ioctls.c +4 -9
@@ -118,7 +118,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)u8 args[4 ], xfer_rate =0 ;struct ide_cmd cmd;struct ide_taskfile *tf = &cmd.tf; -u16 *id = drive->id;if (NULL == (void *) arg) {struct request *rq;
@@ -161,14 +160,10 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)if (tf->command ==ATA_CMD_SET_FEATURES && tf->feature ==SETFEATURES_XFER && - tf->nsect >=XFER_SW_DMA_0 && - (id[ATA_ID_UDMA_MODES ] || - id[ATA_ID_MWDMA_MODES ] || - id[ATA_ID_SWDMA_MODES ])) { - xfer_rate = args[1 ]; -if (tf->nsect >XFER_UDMA_2 && !eighty_ninty_three (drive)) { -printk (KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " -"be set\n" , drive->name); + tf->nsect >=XFER_SW_DMA_0 ) { + xfer_rate =ide_find_dma_mode (drive,XFER_UDMA_6 ); +if (xfer_rate != tf->nsect) { + err = -EINVAL ; goto abort; } }
drivers/ide/ide-probe.c +15 -2
@@ -1170,7 +1170,6 @@ static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw) hwif->irq = hw->irq; hwif->dev = hw->dev; hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; - hwif->ack_intr = hw->ack_intr; hwif->config_data = hw->config; }
@@ -1378,6 +1377,9 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,ide_init_port (hwif, i &1 , d);ide_port_cable_detect (hwif); + + hwif->port_flags |=IDE_PFLAG_PROBING ; +ide_port_init_devices (hwif); }
@@ -1388,6 +1390,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,if (ide_probe_port (hwif) ==0 ) hwif->present =1 ; + hwif->port_flags &= ~IDE_PFLAG_PROBING ; +if ((hwif->host_flags &IDE_HFLAG_4DRIVES ) ==0 || hwif->mate ==NULL || hwif->mate->present ==0 ) {if (ide_register_port (hwif)) {
@@ -1569,11 +1573,20 @@ EXPORT_SYMBOL_GPL(ide_host_remove);void ide_port_scan (ide_hwif_t *hwif) { +int rc; +ide_port_apply_params (hwif);ide_port_cable_detect (hwif); + + hwif->port_flags |=IDE_PFLAG_PROBING ; +ide_port_init_devices (hwif); -if (ide_probe_port (hwif) <0 ) + rc =ide_probe_port (hwif); + + hwif->port_flags &= ~IDE_PFLAG_PROBING ; + +if (rc <0 )return ; hwif->present =1 ;
drivers/ide/ide-tape.c +85 -101
392 lines not on this page · raw message
drivers/ide/ide-xfer-mode.c +12 -0
@@ -107,6 +107,18 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) }EXPORT_SYMBOL_GPL (ide_get_best_pio_mode); +int ide_pio_need_iordy (ide_drive_t *drive,const u8 pio) +{ +/* +* IORDY may lead to controller lock up on certain controllers +* if the port is not occupied. +*/ +if (pio ==0 && (drive->hwif->port_flags &IDE_PFLAG_PROBING )) +return 0 ; +return ata_id_pio_need_iordy (drive->id, pio); +} +EXPORT_SYMBOL_GPL (ide_pio_need_iordy); +int ide_set_pio_mode (ide_drive_t *drive,const u8 mode) {ide_hwif_t *hwif = drive->hwif;
drivers/ide/it8172.c +1 -1
@@ -66,7 +66,7 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)if (drive->media == ide_disk)/* enable prefetch */ drive_enables |=0x0004 << (drive->dn *4 ); -if (ata_id_has_iordy (drive->id)) +if (ide_pio_need_iordy (drive, pio))/* enable IORDY sample-point */ drive_enables |=0x0002 << (drive->dn *4 );
drivers/ide/it8213.c +1 -1
@@ -50,7 +50,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) control |=1 ;/* Programmable timing on */ if (drive->media != ide_disk) control |=4 ;/* ATAPI */ -if (pio >2 ) +if (ide_pio_need_iordy (drive, pio)) control |=2 ;/* IORDY */ if (is_slave) { master_data |=0x4000 ;
drivers/ide/macide.c +18 -12
@@ -53,17 +53,20 @@volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE +IDE_IFR ); -int macide_ack_intr (ide_hwif_t * hwif) +int macide_test_irq (ide_hwif_t *hwif) { -if (*ide_ifr &0x20 ) { - *ide_ifr &= ~0x20 ; +if (*ide_ifr &0x20 )return 1 ; - }return 0 ; } +static void macide_clear_irq (ide_drive_t *drive) +{ + *ide_ifr &= ~0x20 ; +} +static void __init macide_setup_ports (struct ide_hw *hw,unsigned long base, -int irq,ide_ack_intr_t *ack_intr) +int irq) {int i;
@@ -75,10 +78,15 @@ static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base, hw->io_ports.ctl_addr = base +IDE_CONTROL ; hw->irq = irq; - hw->ack_intr = ack_intr; } +static const struct ide_port_ops macide_port_ops = { + .clear_irq = macide_clear_irq, + .test_irq = macide_test_irq, +}; +static const struct ide_port_info macide_port_info = { + .port_ops = &macide_port_ops, .host_flags =IDE_HFLAG_MMIO |IDE_HFLAG_NO_DMA , .irq_flags =IRQF_SHARED , .chipset = ide_generic,
@@ -93,10 +101,10 @@ static const char *mac_ide_name[] =static int __init macide_init (void ) { -ide_ack_intr_t *ack_intr;unsigned long base;int irq;struct ide_hw hw, *hws[] = { &hw }; +struct ide_port_info d = macide_port_info;if (!MACH_IS_MAC )return -ENODEV ;
@@ -104,17 +112,15 @@ static int __init macide_init(void)switch (macintosh_config->ide_type) {case MAC_IDE_QUADRA : base =IDE_BASE ; - ack_intr = macide_ack_intr; irq =IRQ_NUBUS_F ;break ;case MAC_IDE_PB : base =IDE_BASE ; - ack_intr = macide_ack_intr; irq =IRQ_NUBUS_C ;break ;case MAC_IDE_BABOON : base =BABOON_BASE ; - ack_intr =NULL ; + d.port_ops =NULL ; irq =IRQ_BABOON_1 ;break ;default :
@@ -124,9 +130,9 @@ static int __init macide_init(void)printk (KERN_INFO "ide: Macintosh %s IDE controller\n" , mac_ide_name[macintosh_config->ide_type -1 ]); -macide_setup_ports (&hw, base, irq, ack_intr); +macide_setup_ports (&hw, base, irq); -return ide_host_add (&macide_port_info, hws,1 ,NULL ); +return ide_host_add (&d, hws,1 ,NULL ); }module_init (macide_init);
drivers/ide/opti621.c +5 -3
@@ -138,6 +138,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)ide_hwif_t *hwif = drive->hwif;ide_drive_t *pair =ide_get_pair_dev (drive);unsigned long flags; +unsigned long mode =XFER_PIO_0 + pio, pair_mode;u8 tim, misc, addr_pio = pio, clk;/* DRDY is default 2 (by OPTi Databook) */
@@ -150,11 +151,12 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */ }; - drive->drive_data =XFER_PIO_0 + pio; +ide_set_drivedata (drive, (void *)mode);if (pair) { -if (pair->drive_data && pair->drive_data < drive->drive_data) - addr_pio = pair->drive_data -XFER_PIO_0 ; + pair_mode = (unsigned long )ide_get_drivedata (pair); +if (pair_mode && pair_mode < mode) + addr_pio = pair_mode -XFER_PIO_0 ; }spin_lock_irqsave (&opti621_lock, flags);
drivers/ide/pdc202xx_old.c +23 -1
@@ -73,7 +73,7 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)* Prefetch_EN / IORDY_EN / PA[3:0] bits of register A */ AP &= ~0x3f ; -if (ata_id_iordy_disable (drive->id)) +if (ide_pio_need_iordy (drive, speed -XFER_PIO_0 ))AP |=0x20 ;/* set IORDY_EN bit */ if (drive->media == ide_disk)AP |=0x10 ;/* set Prefetch_EN bit */
@@ -104,6 +104,27 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)pdc202xx_set_mode (drive,XFER_PIO_0 + pio); } +static int pdc202xx_test_irq (ide_hwif_t *hwif) +{ +struct pci_dev *dev =to_pci_dev (hwif->dev); +unsigned long high_16 =pci_resource_start (dev,4 ); +u8 sc1d =inb (high_16 +0x1d ); + +if (hwif->channel) { +/* +* bit 7: error, bit 6: interrupting, +* bit 5: FIFO full, bit 4: FIFO empty +*/ +return ((sc1d &0x50 ) ==0x40 ) ?1 :0 ; + }else { +/* +* bit 3: error, bit 2: interrupting, +* bit 1: FIFO full, bit 0: FIFO empty +*/ +return ((sc1d &0x05 ) ==0x04 ) ?1 :0 ; + } +} +static u8 pdc2026x_cable_detect (ide_hwif_t *hwif) {struct pci_dev *dev =to_pci_dev (hwif->dev);
@@ -231,6 +252,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,static const struct ide_port_ops pdc20246_port_ops = { .set_pio_mode = pdc202xx_set_pio_mode, .set_dma_mode = pdc202xx_set_mode, + .test_irq = pdc202xx_test_irq, };static const struct ide_port_ops pdc2026x_port_ops = {
drivers/ide/piix.c +1 -1
@@ -98,7 +98,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) control |=1 ;/* Programmable timing on */ if (drive->media == ide_disk) control |=4 ;/* Prefetch, post write */ -if (pio >2 ) +if (ide_pio_need_iordy (drive, pio)) control |=2 ;/* IORDY */ if (is_slave) { master_data |=0x4000 ;
drivers/ide/q40ide.c +2 -5
@@ -51,9 +51,7 @@ static int q40ide_default_irq(unsigned long base)/* * Addresses are pretranslated for Q40 ISA access. */ -static void q40_ide_setup_ports (struct ide_hw *hw,unsigned long base, -ide_ack_intr_t *ack_intr, -int irq) +static void q40_ide_setup_ports (struct ide_hw *hw,unsigned long base,int irq) {memset (hw,0 ,sizeof (*hw));/* BIG FAT WARNING:
@@ -69,7 +67,6 @@ static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, hw->io_ports.ctl_addr =Q40_ISA_IO_B (base +0x206 ); hw->irq = irq; - hw->ack_intr = ack_intr; } static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
@@ -156,7 +153,7 @@ static int __init q40ide_init(void)release_region (pcide_bases[i],8 );continue ; } -q40_ide_setup_ports (&hw[i], pcide_bases[i],NULL , +q40_ide_setup_ports (&hw[i], pcide_bases[i],q40ide_default_irq (pcide_bases[i])); hws[i] = &hw[i];
drivers/ide/qd65xx.c +7 -4
@@ -180,8 +180,11 @@ static int qd_find_disk_type (ide_drive_t *drive,static void qd_set_timing (ide_drive_t *drive,u8 timing) { - drive->drive_data &=0xff00 ; - drive->drive_data |= timing; +unsigned long data = (unsigned long )ide_get_drivedata (drive); + + data &=0xff00 ; + data |= timing; +ide_set_drivedata (drive, (void *)data);printk (KERN_DEBUG "%s: %#x\n" , drive->name, timing); }
@@ -292,7 +295,7 @@ static void __init qd6500_init_dev(ide_drive_t *drive)u8 base = (hwif->config_data &0xff00 ) >>8 ;u8 config =QD_CONFIG (hwif); - drive->drive_data =QD6500_DEF_DATA ; +ide_set_drivedata (drive, (void *)QD6500_DEF_DATA ); }static void __init qd6580_init_dev (ide_drive_t *drive)
@@ -308,7 +311,7 @@ static void __init qd6580_init_dev(ide_drive_t *drive) }else t2 = t1 = hwif->channel ?QD6580_DEF_DATA2 :QD6580_DEF_DATA ; - drive->drive_data = (drive->dn &1 ) ? t2 : t1; +ide_set_drivedata (drive, (void *)((drive->dn &1 ) ? t2 : t1)); }static const struct ide_tp_ops qd65xx_tp_ops = {
drivers/ide/qd65xx.h +9 -2
@@ -31,8 +31,15 @@#define QD_CONFIG (hwif) ((hwif)->config_data & 0x00ff) -#define QD_TIMING (drive) (u8)(((drive)->drive_data) & 0x00ff) -#define QD_TIMREG (drive) (u8)((((drive)->drive_data) & 0xff00) >> 8) +static inline u8 QD_TIMING (ide_drive_t *drive) +{ +return (unsigned long )ide_get_drivedata (drive) &0x00ff ; +} + +static inline u8 QD_TIMREG (ide_drive_t *drive) +{ +return ((unsigned long )ide_get_drivedata (drive) &0xff00 ) >>8 ; +}#define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))#define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
drivers/ide/sgiioc4.c +54 -65
291 lines not on this page · raw message
drivers/ide/siimage.c +15 -27
103 lines not on this page · raw message
drivers/ide/sl82c105.c +24 -8
@@ -61,8 +61,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)if (cmd_off ==0 ) cmd_off =1 ; -if ((pio >2 ||ata_id_has_iordy (drive->id)) && - !(pio >4 &&ata_id_is_cfa (drive->id))) +if (ide_pio_need_iordy (drive, pio)) iordy =0x40 ;return (cmd_on -1 ) <<8 | (cmd_off -1 ) | iordy;
@@ -74,6 +73,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)static void sl82c105_set_pio_mode (ide_drive_t *drive,const u8 pio) {struct pci_dev *dev =to_pci_dev (drive->hwif->dev); +unsigned long timings = (unsigned long )ide_get_drivedata (drive);int reg =0x44 + drive->dn *4 ;u16 drv_ctrl;
@@ -83,8 +83,9 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)* Store the PIO timings so that we can restore them * in case DMA will be turned off... */ - drive->drive_data &=0xffff0000 ; - drive->drive_data |= drv_ctrl; + timings &=0xffff0000 ; + timings |= drv_ctrl; +ide_set_drivedata (drive, (void *)timings);pci_write_config_word (dev, reg, drv_ctrl);pci_read_config_word (dev, reg, &drv_ctrl);
@@ -100,6 +101,7 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)static void sl82c105_set_dma_mode (ide_drive_t *drive,const u8 speed) {static u16 mwdma_timings[] = {0x0707 ,0x0201 ,0x0200 }; +unsigned long timings = (unsigned long )ide_get_drivedata (drive);u16 drv_ctrl; DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
@@ -111,8 +113,19 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)* Store the DMA timings so that we can actually program * them when DMA will be turned on... */ - drive->drive_data &=0x0000ffff ; - drive->drive_data |= (unsigned long )drv_ctrl <<16 ; + timings &=0x0000ffff ; + timings |= (unsigned long )drv_ctrl <<16 ; +ide_set_drivedata (drive, (void *)timings); +} + +static int sl82c105_test_irq (ide_hwif_t *hwif) +{ +struct pci_dev *dev =to_pci_dev (hwif->dev); +u32 val, mask = hwif->channel ?CTRL_IDE_IRQB :CTRL_IDE_IRQA ; + +pci_read_config_dword (dev,0x40 , &val); + +return (val & mask) ?1 :0 ; }/*
@@ -185,7 +198,8 @@ static void sl82c105_dma_start(ide_drive_t *drive)DBG (("%s(drive:%s)\n" , __func__, drive->name)); -pci_write_config_word (dev, reg, drive->drive_data >>16 ); +pci_write_config_word (dev, reg, + (unsigned long )ide_get_drivedata (drive) >>16 );sl82c105_reset_host (dev);ide_dma_start (drive);
@@ -210,7 +224,8 @@ static int sl82c105_dma_end(ide_drive_t *drive) ret =ide_dma_end (drive); -pci_write_config_word (dev, reg, drive->drive_data); +pci_write_config_word (dev, reg, + (unsigned long )ide_get_drivedata (drive));return ret; }
@@ -289,6 +304,7 @@ static const struct ide_port_ops sl82c105_port_ops = { .set_pio_mode = sl82c105_set_pio_mode, .set_dma_mode = sl82c105_set_dma_mode, .resetproc = sl82c105_resetproc, + .test_irq = sl82c105_test_irq, };static const struct ide_dma_ops sl82c105_dma_ops = {
drivers/ide/slc90e66.c +1 -1
@@ -44,7 +44,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) control |=1 ;/* Programmable timing on */ if (drive->media == ide_disk) control |=4 ;/* Prefetch, post write */ -if (pio >2 ) +if (ide_pio_need_iordy (drive, pio)) control |=2 ;/* IORDY */ if (is_slave) { master_data |=0x4000 ;
include/linux/ata.h +14 -0
@@ -800,6 +800,20 @@ static inline int ata_id_is_ssd(const u16 *id)return id[ATA_ID_ROT_SPEED ] ==0x01 ; } +static inline int ata_id_pio_need_iordy (const u16 *id,const u8 pio) +{ +/* CF spec. r4.1 Table 22 says no IORDY on PIO5 and PIO6. */ +if (pio >4 &&ata_id_is_cfa (id)) +return 0 ; +/* For PIO3 and higher it is mandatory. */ +if (pio >2 ) +return 1 ; +/* Turn it on when possible. */ +if (ata_id_has_iordy (id)) +return 1 ; +return 0 ; +} +static inline int ata_drive_40wire (const u16 *dev_id) {if (ata_id_is_sata (dev_id))
include/linux/ide.h +23 -24
131 lines not on this page · raw message