Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44519
b: refs/heads/master
c: 33b18a6
h: refs/heads/master
i:
  44517: 7b1b0f1
  44515: 939995e
  44511: 838b816
v: v3
  • Loading branch information
Sergei Shtylyov authored and Linus Torvalds committed Dec 13, 2006
1 parent 904a1a3 commit 4d8bb8e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 80 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 471a0bda5a2de5b0fd3b58255791eb831517a52c
refs/heads/master: 33b18a602525198ab8892789dab6839f325407f8
115 changes: 36 additions & 79 deletions trunk/drivers/ide/pci/hpt366.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
* - fix/remove bad/unused timing tables and use one set of tables for the whole
* HPT37x chip family; save space by introducing the separate transfer mode
* table in which the mode lookup is done
* - fix the hotswap code: it caused RESET- to glitch when tristating the bus,
* and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
* <source@mvista.com>
*
*/
Expand Down Expand Up @@ -914,101 +916,68 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
hpt3xxn_set_clock(hwif, wantclock);
}

/*
* Since SUN Cobalt is attempting to do this operation, I should disclose
* this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
* HOTSWAP ATA Infrastructure.
*/

static void hpt3xx_reset (ide_drive_t *drive)
{
}

static int hpt3xx_tristate (ide_drive_t * drive, int state)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 reg59h = 0, reset = (hwif->channel) ? 0x80 : 0x40;
u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;

pci_read_config_byte(dev, 0x59, &reg59h);
pci_read_config_byte(dev, state_reg, &regXXh);

if (state) {
(void) ide_do_reset(drive);
pci_write_config_byte(dev, state_reg, regXXh|0x80);
pci_write_config_byte(dev, 0x59, reg59h|reset);
} else {
pci_write_config_byte(dev, 0x59, reg59h & ~(reset));
pci_write_config_byte(dev, state_reg, regXXh & ~(0x80));
(void) ide_do_reset(drive);
}
return 0;
}

/*
* set/get power state for a drive.
* turning the power off does the following things:
* 1) soft-reset the drive
* 2) tri-states the ide bus
* Set/get power state for a drive.
*
* when we turn things back on, we need to re-initialize things.
* When we turn the power back on, we need to re-initialize things.
*/
#define TRISTATE_BIT 0x8000
static int hpt370_busproc(ide_drive_t * drive, int state)

static int hpt3xx_busproc(ide_drive_t *drive, int state)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = hwif->pci_dev;
u8 tristate = 0, resetmask = 0, bus_reg = 0;
u16 tri_reg;
u8 tristate, resetmask, bus_reg = 0;
u16 tri_reg = 0;

hwif->bus_state = state;

if (hwif->channel) {
/* secondary channel */
tristate = 0x56;
resetmask = 0x80;
tristate = 0x56;
resetmask = 0x80;
} else {
/* primary channel */
tristate = 0x52;
tristate = 0x52;
resetmask = 0x40;
}

/* grab status */
/* Grab the status. */
pci_read_config_word(dev, tristate, &tri_reg);
pci_read_config_byte(dev, 0x59, &bus_reg);

/* set the state. we don't set it if we don't need to do so.
* make sure that the drive knows that it has failed if it's off */
/*
* Set the state. We don't set it if we don't need to do so.
* Make sure that the drive knows that it has failed if it's off.
*/
switch (state) {
case BUSSTATE_ON:
hwif->drives[0].failures = 0;
hwif->drives[1].failures = 0;
if ((bus_reg & resetmask) == 0)
if (!(bus_reg & resetmask))
return 0;
tri_reg &= ~TRISTATE_BIT;
bus_reg &= ~resetmask;
break;
hwif->drives[0].failures = hwif->drives[1].failures = 0;

pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask);
pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT);
return 0;
case BUSSTATE_OFF:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask))
if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT))
return 0;
tri_reg &= ~TRISTATE_BIT;
bus_reg |= resetmask;
break;
case BUSSTATE_TRISTATE:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask))
if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT))
return 0;
tri_reg |= TRISTATE_BIT;
bus_reg |= resetmask;
break;
default:
return -EINVAL;
}
pci_write_config_byte(dev, 0x59, bus_reg);
pci_write_config_word(dev, tristate, tri_reg);

hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;

pci_write_config_word(dev, tristate, tri_reg);
pci_write_config_byte(dev, 0x59, bus_reg | resetmask);
return 0;
}

Expand Down Expand Up @@ -1306,23 +1275,11 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
if (serialize && hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;

if (info->revision >= 3) {
u8 reg5ah = 0;
pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
/*
* set up ioctl for power status.
* note: power affects both
* drives on each channel
*/
hwif->resetproc = &hpt3xx_reset;
hwif->busproc = &hpt370_busproc;
} else if (info->revision >= 2) {
hwif->resetproc = &hpt3xx_reset;
hwif->busproc = &hpt3xx_tristate;
} else {
hwif->resetproc = &hpt3xx_reset;
hwif->busproc = &hpt3xx_tristate;
}
/*
* Set up ioctl for power status.
* NOTE: power affects both drives on each channel.
*/
hwif->busproc = &hpt3xx_busproc;

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

0 comments on commit 4d8bb8e

Please sign in to comment.