Skip to content

Commit

Permalink
ide: add struct ide_port_ops (take 2)
Browse files Browse the repository at this point in the history
* Move hooks for port/host specific methods from ide_hwif_t to
  'struct ide_port_ops'.

* Add 'const struct ide_port_ops *port_ops' to 'struct ide_port_info'
  and ide_hwif_t.

* Update host drivers and core code accordingly.

While at it:

* Rename ata66_*() cable detect functions to *_cable_detect() to match
  the standard naming. (Suggested by Sergei Shtylyov)

v2:
* Fix build for bast-ide. (Noticed by Andrew Morton)

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Apr 26, 2008
1 parent 4a27214 commit ac95bee
Show file tree
Hide file tree
Showing 53 changed files with 493 additions and 436 deletions.
2 changes: 1 addition & 1 deletion drivers/ide/arm/bast-ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq)

ide_init_port_hw(hwif, &hw);
hwif->mmio = 1;
hwif->quirkproc = NULL;
hwif->port_ops = NULL;

idx[0] = i;

Expand Down
13 changes: 11 additions & 2 deletions drivers/ide/arm/icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ static void icside_maskproc(ide_drive_t *drive, int mask)
local_irq_restore(flags);
}

static const struct ide_port_ops icside_v6_no_dma_port_ops = {
.maskproc = icside_maskproc,
};

#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
/*
* SG-DMA support.
Expand Down Expand Up @@ -266,6 +270,11 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
}

static const struct ide_port_ops icside_v6_port_ops = {
.set_dma_mode = icside_set_dma_mode,
.maskproc = icside_maskproc,
};

static void icside_dma_host_set(ide_drive_t *drive, int on)
{
}
Expand Down Expand Up @@ -379,7 +388,6 @@ static void icside_dma_init(ide_hwif_t *hwif)
{
hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0;
hwif->set_dma_mode = icside_set_dma_mode;

hwif->dma_host_set = icside_dma_host_set;
hwif->dma_setup = icside_dma_setup;
Expand Down Expand Up @@ -462,6 +470,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
}

static const struct ide_port_info icside_v6_port_info __initdata = {
.port_ops = &icside_v6_no_dma_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
IDE_HFLAG_NO_AUTOTUNE,
Expand Down Expand Up @@ -526,7 +535,6 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
state->hwif[0] = hwif;
state->hwif[1] = mate;

hwif->maskproc = icside_maskproc;
hwif->hwif_data = state;
hwif->config_data = (unsigned long)ioc_base;
hwif->select_data = sel;
Expand All @@ -539,6 +547,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
icside_dma_init(hwif);
icside_dma_init(mate);
d.port_ops = &icside_v6_dma_port_ops;
} else
d.mwdma_mask = d.swdma_mask = 0;

Expand Down
14 changes: 6 additions & 8 deletions drivers/ide/arm/palm_bk3710.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,16 +317,14 @@ static u8 __devinit palm_bk3710_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}

static void __devinit palm_bk3710_init_hwif(ide_hwif_t *hwif)
{
hwif->set_pio_mode = palm_bk3710_set_pio_mode;
hwif->set_dma_mode = palm_bk3710_set_dma_mode;

hwif->cable_detect = palm_bk3710_cable_detect;
}
static const struct ide_port_ops palm_bk3710_ports_ops = {
.set_pio_mode = palm_bk3710_set_pio_mode,
.set_dma_mode = palm_bk3710_set_dma_mode,
.cable_detect = palm_bk3710_cable_detect,
};

static const struct ide_port_info __devinitdata palm_bk3710_port_info = {
.init_hwif = palm_bk3710_init_hwif,
.port_ops = &palm_bk3710_ports_ops,
.host_flags = IDE_HFLAG_NO_DMA, /* hack (no PCI) */
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA4, /* (input clk 99MHz) */
Expand Down
8 changes: 6 additions & 2 deletions drivers/ide/cris/ide-cris.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,14 @@ static void __init cris_setup_ports(hw_regs_t *hw, unsigned long base)
hw->ack_intr = cris_ide_ack_intr;
}

static const struct ide_port_ops cris_port_ops = {
.set_pio_mode = cris_set_pio_mode,
.set_dma_mode = cris_set_dma_mode,
};

static const struct ide_port_info cris_port_info __initdata = {
.chipset = ide_etrax100,
.port_ops = &cris_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_NO_DMA, /* no SFF-style DMA */
.pio_mask = ATA_PIO4,
Expand All @@ -810,8 +816,6 @@ static int __init init_e100_ide(void)
ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1;
hwif->set_pio_mode = &cris_set_pio_mode;
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
9 changes: 5 additions & 4 deletions drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,15 +574,16 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
unsigned int mask = 0;

switch(base) {
case XFER_UDMA_0:
if ((id->field_valid & 4) == 0)
break;

if (hwif->udma_filter)
mask = hwif->udma_filter(drive);
if (port_ops && port_ops->udma_filter)
mask = port_ops->udma_filter(drive);
else
mask = hwif->ultra_mask;
mask &= id->dma_ultra;
Expand All @@ -598,8 +599,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_MW_DMA_0:
if ((id->field_valid & 2) == 0)
break;
if (hwif->mdma_filter)
mask = hwif->mdma_filter(drive);
if (port_ops && port_ops->mdma_filter)
mask = port_ops->mdma_filter(drive);
else
mask = hwif->mwdma_mask;
mask &= id->dma_mword;
Expand Down
5 changes: 3 additions & 2 deletions drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ static ide_startstop_t do_special (ide_drive_t *drive)
#endif
if (s->b.set_tune) {
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
u8 req_pio = drive->tune_req;

s->b.set_tune = 0;
Expand All @@ -733,10 +734,10 @@ static ide_startstop_t do_special (ide_drive_t *drive)
unsigned long flags;

spin_lock_irqsave(&ide_lock, flags);
hwif->set_pio_mode(drive, req_pio);
port_ops->set_pio_mode(drive, req_pio);
spin_unlock_irqrestore(&ide_lock, flags);
} else
hwif->set_pio_mode(drive, req_pio);
port_ops->set_pio_mode(drive, req_pio);
} else {
int keep_dma = drive->using_dma;

Expand Down
28 changes: 18 additions & 10 deletions drivers/ide/ide-iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,20 @@ EXPORT_SYMBOL(default_hwif_mmiops);
void SELECT_DRIVE (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;

if (hwif->selectproc)
hwif->selectproc(drive);
if (port_ops && port_ops->selectproc)
port_ops->selectproc(drive);

hwif->OUTB(drive->select.all, hwif->io_ports[IDE_SELECT_OFFSET]);
}

void SELECT_MASK (ide_drive_t *drive, int mask)
{
if (HWIF(drive)->maskproc)
HWIF(drive)->maskproc(drive, mask);
const struct ide_port_ops *port_ops = drive->hwif->port_ops;

if (port_ops && port_ops->maskproc)
port_ops->maskproc(drive, mask);
}

/*
Expand Down Expand Up @@ -905,10 +908,11 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
const struct ide_port_ops *port_ops = hwif->port_ops;
u8 tmp;

if (hwif->reset_poll != NULL) {
if (hwif->reset_poll(drive)) {
if (port_ops && port_ops->reset_poll) {
if (port_ops->reset_poll(drive)) {
printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
hwif->name, drive->name);
return ide_stopped;
Expand Down Expand Up @@ -974,6 +978,8 @@ static void ide_disk_pre_reset(ide_drive_t *drive)

static void pre_reset(ide_drive_t *drive)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;

if (drive->media == ide_disk)
ide_disk_pre_reset(drive);
else
Expand All @@ -994,8 +1000,8 @@ static void pre_reset(ide_drive_t *drive)
return;
}

if (HWIF(drive)->pre_reset != NULL)
HWIF(drive)->pre_reset(drive);
if (port_ops && port_ops->pre_reset)
port_ops->pre_reset(drive);

if (drive->current_speed != 0xff)
drive->desired_speed = drive->current_speed;
Expand Down Expand Up @@ -1023,6 +1029,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
unsigned long flags;
ide_hwif_t *hwif;
ide_hwgroup_t *hwgroup;
const struct ide_port_ops *port_ops;
u8 ctl;

spin_lock_irqsave(&ide_lock, flags);
Expand Down Expand Up @@ -1089,8 +1096,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
* state when the disks are reset this way. At least, the Winbond
* 553 documentation says that
*/
if (hwif->resetproc)
hwif->resetproc(drive);
port_ops = hwif->port_ops;
if (port_ops && port_ops->resetproc)
port_ops->resetproc(drive);

spin_unlock_irqrestore(&ide_lock, flags);
return ide_started;
Expand Down
24 changes: 14 additions & 10 deletions drivers/ide/ide-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,10 @@ EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
void ide_set_pio(ide_drive_t *drive, u8 req_pio)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
u8 host_pio, pio;

if (hwif->set_pio_mode == NULL ||
if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return;

Expand Down Expand Up @@ -343,50 +344,52 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;

if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0;

if (hwif->set_pio_mode == NULL)
if (port_ops == NULL || port_ops->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);
if (port_ops->set_dma_mode == NULL) {
port_ops->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);
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
return 0;
} else {
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
port_ops->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;
const struct ide_port_ops *port_ops = hwif->port_ops;

if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0;

if (hwif->set_dma_mode == NULL)
if (port_ops == NULL || port_ops->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);
port_ops->set_dma_mode(drive, mode);
return 0;
} else {
hwif->set_dma_mode(drive, mode);
port_ops->set_dma_mode(drive, mode);
return ide_config_drive_speed(drive, mode);
}
}
Expand All @@ -406,8 +409,9 @@ EXPORT_SYMBOL_GPL(ide_set_dma_mode);
int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;

if (hwif->set_dma_mode == NULL ||
if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return -1;

Expand Down
20 changes: 14 additions & 6 deletions drivers/ide/ide-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,14 @@ static int ide_probe_port(ide_hwif_t *hwif)

static void ide_port_tune_devices(ide_hwif_t *hwif)
{
const struct ide_port_ops *port_ops = hwif->port_ops;
int unit;

for (unit = 0; unit < MAX_DRIVES; unit++) {
ide_drive_t *drive = &hwif->drives[unit];

if (drive->present && hwif->quirkproc)
hwif->quirkproc(drive);
if (drive->present && port_ops && port_ops->quirkproc)
port_ops->quirkproc(drive);
}

for (unit = 0; unit < MAX_DRIVES; ++unit) {
Expand Down Expand Up @@ -1324,6 +1325,7 @@ static void hwif_register_devices(ide_hwif_t *hwif)

static void ide_port_init_devices(ide_hwif_t *hwif)
{
const struct ide_port_ops *port_ops = hwif->port_ops;
int i;

for (i = 0; i < MAX_DRIVES; i++) {
Expand All @@ -1339,8 +1341,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
drive->autotune = 1;
}

if (hwif->port_init_devs)
hwif->port_init_devs(hwif);
if (port_ops && port_ops->port_init_devs)
port_ops->port_init_devs(hwif);
}

static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
Expand All @@ -1365,6 +1367,10 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
hwif->host_flags = d->host_flags;
hwif->pio_mask = d->pio_mask;

/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
hwif->port_ops = d->port_ops;

if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
hwif->mate->serialized = hwif->serialized = 1;

Expand All @@ -1386,9 +1392,11 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,

static void ide_port_cable_detect(ide_hwif_t *hwif)
{
if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
const struct ide_port_ops *port_ops = hwif->port_ops;

if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = hwif->cable_detect(hwif);
hwif->cbl = port_ops->cable_detect(hwif);
}
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/ide/ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,12 @@ int set_pio_mode(ide_drive_t *drive, int arg)
{
struct request rq;
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;

if (arg < 0 || arg > 255)
return -EINVAL;

if (hwif->set_pio_mode == NULL ||
if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return -ENOSYS;

Expand Down
Loading

0 comments on commit ac95bee

Please sign in to comment.