Skip to content

Commit

Permalink
ide: move ide_config_drive_speed() calls to upper layers (take 2)
Browse files Browse the repository at this point in the history
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.

* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program 
  the host for the transfer mode after programming the device.  Set it
  in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
  and via82cxxx host drivers.

* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
  skip programming of host/device for the transfer mode ("smart" hosts).
  Set it in it821x host driver and check it in ide_tune_dma().

* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
  direct ->set_pio_mode/->speedproc users to use these helpers.

* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
  methods to callers.

* Rename ->speedproc method to ->set_dma_mode, make it void and update
  all implementations accordingly.

* Update ide_set_xfer_rate() comments.

* Unexport ide_config_drive_speed().

v2:
* Fix issues noticed by Sergei:
  - export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
    to setting DMA modes from sc1200_set_pio_mode() to do_special()
  - check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
  - check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
  - check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
  - return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
  - don't set ->set_{pio,dma}_mode on it821x in "smart" mode
  - fix build problem in pmac.c
  - minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
  - improve patch description

Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
  PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
  the device (not really an issue since 0x00 is not supported correctly by
  any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Oct 13, 2007
1 parent 6e24939 commit 88b2b32
Show file tree
Hide file tree
Showing 36 changed files with 304 additions and 521 deletions.
8 changes: 3 additions & 5 deletions drivers/ide/arm/icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
* MW1 80 50 50 150 C
* MW2 70 25 25 120 C
*/
static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
{
int cycle_time, use_dma_info = 0;

Expand All @@ -273,7 +273,7 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
cycle_time = 480;
break;
default:
return 1;
return;
}

/*
Expand All @@ -287,8 +287,6 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)

printk("%s: %s selected (peak %dMB/s)\n", drive->name,
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);

return ide_config_drive_speed(drive, xfer_mode);
}

static void icside_dma_host_off(ide_drive_t *drive)
Expand Down Expand Up @@ -433,7 +431,7 @@ static void icside_dma_init(ide_hwif_t *hwif)

hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0;
hwif->speedproc = icside_set_speed;
hwif->set_dma_mode = icside_set_dma_mode;
hwif->autodma = 1;

hwif->ide_dma_check = icside_dma_check;
Expand Down
8 changes: 2 additions & 6 deletions drivers/ide/cris/ide-cris.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,11 +716,9 @@ static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio)
}

cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);

(void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}

static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
int cyc = 0, dvs = 0, strobe = 0, hold = 0;

Expand Down Expand Up @@ -759,8 +757,6 @@ static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
else
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);

return ide_config_drive_speed(drive, speed);
}

void __init
Expand Down Expand Up @@ -791,7 +787,7 @@ init_e100_ide (void)
hwif->mmio = 1;
hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode;
hwif->speedproc = &speed_cris_ide;
hwif->set_dma_mode = &cris_set_dma_mode;
hwif->ata_input_data = &cris_ide_input_data;
hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes;
Expand Down
5 changes: 4 additions & 1 deletion drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,10 @@ int ide_tune_dma(ide_drive_t *drive)
if (!speed)
return 0;

if (drive->hwif->speedproc(drive, speed))
if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0;

if (ide_set_dma_mode(drive, speed))
return 0;

return 1;
Expand Down
3 changes: 0 additions & 3 deletions drivers/ide/ide-iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,9 +862,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}

EXPORT_SYMBOL(ide_config_drive_speed);


/*
* This should get invoked any time we exit the driver to
* wait for an interrupt response from a drive. handler() points
Expand Down
78 changes: 61 additions & 17 deletions drivers/ide/ide-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio)
drive->name, host_pio, req_pio,
req_pio == 255 ? "(auto-tune)" : "", pio);

hwif->set_pio_mode(drive, pio);
(void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
}

EXPORT_SYMBOL_GPL(ide_set_pio);
Expand Down Expand Up @@ -378,39 +378,83 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}

int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = drive->hwif;

if (hwif->set_pio_mode == NULL)
return -1;

/*
* TODO: temporary hack for some legacy host drivers that didn't
* set transfer mode on the device in ->set_pio_mode method...
*/
if (hwif->set_dma_mode == NULL) {
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
return 0;
}

if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
return 0;
} else {
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
return ide_config_drive_speed(drive, mode);
}
}

int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = drive->hwif;

if (hwif->set_dma_mode == NULL)
return -1;

if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
hwif->set_dma_mode(drive, mode);
return 0;
} else {
hwif->set_dma_mode(drive, mode);
return ide_config_drive_speed(drive, mode);
}
}

EXPORT_SYMBOL_GPL(ide_set_dma_mode);

/**
* ide_set_xfer_rate - set transfer rate
* @drive: drive to set
* @speed: speed to attempt to set
* @rate: speed to attempt to set
*
* General helper for setting the speed of an IDE device. This
* function knows about user enforced limits from the configuration
* which speedproc() does not. High level drivers should never
* invoke speedproc() directly.
* which ->set_pio_mode/->set_dma_mode does not.
*/

int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
{
ide_hwif_t *hwif = drive->hwif;

if (hwif->speedproc == NULL)
if (hwif->set_dma_mode == NULL)
return -1;

rate = ide_rate_filter(drive, rate);

if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) {
if (hwif->set_pio_mode)
hwif->set_pio_mode(drive, rate - XFER_PIO_0);
if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
return ide_set_pio_mode(drive, rate);

/*
* FIXME: this is incorrect to return zero here but
* since all users of ide_set_xfer_rate() ignore
* the return value it is not a problem currently
*/
return 0;
}
/*
* TODO: transfer modes 0x00-0x07 passed from the user-space are
* currently handled here which needs fixing (please note that such
* case could happen iff the transfer mode has already been set on
* the device by ide-proc.c::set_xfer_rate()).
*/

return hwif->speedproc(drive, rate);
return ide_set_dma_mode(drive, rate);
}

static void ide_dump_opcode(ide_drive_t *drive)
Expand Down
2 changes: 1 addition & 1 deletion drivers/ide/ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
#endif

hwif->set_pio_mode = tmp_hwif->set_pio_mode;
hwif->speedproc = tmp_hwif->speedproc;
hwif->set_dma_mode = tmp_hwif->set_dma_mode;
hwif->mdma_filter = tmp_hwif->mdma_filter;
hwif->udma_filter = tmp_hwif->udma_filter;
hwif->selectproc = tmp_hwif->selectproc;
Expand Down
27 changes: 6 additions & 21 deletions drivers/ide/mips/au1xxx-ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,7 @@ void auide_outsw(unsigned long port, void *addr, u32 count)

static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
int mem_sttime;
int mem_stcfg;

if (ide_config_drive_speed(drive, pio + XFER_PIO_0))
return;

mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2);
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);

/* set pio mode! */
switch(pio) {
Expand Down Expand Up @@ -168,13 +161,9 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
au_writel(mem_stcfg,MEM_STCFG2);
}

static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
int mem_sttime;
int mem_stcfg;

mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2);
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);

switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
Expand Down Expand Up @@ -210,16 +199,11 @@ static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
break;
#endif
default:
return 1;
return;
}

if (ide_config_drive_speed(drive, speed))
return 1;

au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2);

return 0;
}

/*
Expand Down Expand Up @@ -681,6 +665,7 @@ static int au_ide_probe(struct device *dev)
#endif

hwif->pio_mask = ATA_PIO4;
hwif->host_flags = IDE_HFLAG_POST_SET_MODE;

hwif->noprobe = 0;
hwif->drives[0].unmask = 1;
Expand All @@ -701,7 +686,7 @@ static int au_ide_probe(struct device *dev)
#endif

hwif->set_pio_mode = &au1xxx_set_pio_mode;
hwif->speedproc = &auide_tune_chipset;
hwif->set_dma_mode = &auide_set_dma_mode;

#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
hwif->dma_off_quietly = &auide_dma_off_quietly;
Expand Down
12 changes: 5 additions & 7 deletions drivers/ide/pci/aec62xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings;
}

static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
Expand All @@ -111,10 +111,9 @@ static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
pci_write_config_byte(dev, 0x54, tmp2);
local_irq_restore(flags);
return(ide_config_drive_speed(drive, speed));
}

static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
Expand All @@ -135,12 +134,11 @@ static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
local_irq_restore(flags);
return(ide_config_drive_speed(drive, speed));
}

static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
(void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
}

static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
Expand Down Expand Up @@ -205,9 +203,9 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
if(hwif->mate)
hwif->mate->serialized = hwif->serialized = 1;
hwif->speedproc = &aec6210_tune_chipset;
hwif->set_dma_mode = &aec6210_set_mode;
} else
hwif->speedproc = &aec6260_tune_chipset;
hwif->set_dma_mode = &aec6260_set_mode;

if (!hwif->dma_base) {
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
Expand Down
Loading

0 comments on commit 88b2b32

Please sign in to comment.