Commit d7e6cf35 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] fix cmd640 ide locking

parent 2da13dc5
...@@ -197,8 +197,8 @@ static ide_drive_t *cmd_drives[4]; ...@@ -197,8 +197,8 @@ static ide_drive_t *cmd_drives[4];
* Interface to access cmd640x registers * Interface to access cmd640x registers
*/ */
static unsigned int cmd640_key; static unsigned int cmd640_key;
static void (*put_cmd640_reg)(u16 reg, u8 val); static void (*__put_cmd640_reg)(u16 reg, u8 val);
static u8 (*get_cmd640_reg)(u16 reg); static u8 (*__get_cmd640_reg)(u16 reg);
/* /*
* This is read from the CFR reg, and is used in several places. * This is read from the CFR reg, and is used in several places.
...@@ -215,49 +215,32 @@ static unsigned int cmd640_chip_version; ...@@ -215,49 +215,32 @@ static unsigned int cmd640_chip_version;
static void put_cmd640_reg_pci1 (u16 reg, u8 val) static void put_cmd640_reg_pci1 (u16 reg, u8 val)
{ {
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
outb_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
outb_p(val, (reg & 3) | 0xcfc); outb_p(val, (reg & 3) | 0xcfc);
spin_unlock_irqrestore(&ide_lock, flags);
} }
static u8 get_cmd640_reg_pci1 (u16 reg) static u8 get_cmd640_reg_pci1 (u16 reg)
{ {
u8 b;
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
outb_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
b = inb_p((reg & 3) | 0xcfc); return inb_p((reg & 3) | 0xcfc);
spin_unlock_irqrestore(&ide_lock, flags);
return b;
} }
/* PCI method 2 access (from CMD datasheet) */ /* PCI method 2 access (from CMD datasheet) */
static void put_cmd640_reg_pci2 (u16 reg, u8 val) static void put_cmd640_reg_pci2 (u16 reg, u8 val)
{ {
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
outb_p(0x10, 0xcf8); outb_p(0x10, 0xcf8);
outb_p(val, cmd640_key + reg); outb_p(val, cmd640_key + reg);
outb_p(0, 0xcf8); outb_p(0, 0xcf8);
spin_unlock_irqrestore(&ide_lock, flags);
} }
static u8 get_cmd640_reg_pci2 (u16 reg) static u8 get_cmd640_reg_pci2 (u16 reg)
{ {
u8 b; u8 b;
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
outb_p(0x10, 0xcf8); outb_p(0x10, 0xcf8);
b = inb_p(cmd640_key + reg); b = inb_p(cmd640_key + reg);
outb_p(0, 0xcf8); outb_p(0, 0xcf8);
spin_unlock_irqrestore(&ide_lock, flags);
return b; return b;
} }
...@@ -265,26 +248,36 @@ static u8 get_cmd640_reg_pci2 (u16 reg) ...@@ -265,26 +248,36 @@ static u8 get_cmd640_reg_pci2 (u16 reg)
static void put_cmd640_reg_vlb (u16 reg, u8 val) static void put_cmd640_reg_vlb (u16 reg, u8 val)
{ {
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
outb_p(reg, cmd640_key); outb_p(reg, cmd640_key);
outb_p(val, cmd640_key + 4); outb_p(val, cmd640_key + 4);
spin_unlock_irqrestore(&ide_lock, flags);
} }
static u8 get_cmd640_reg_vlb (u16 reg) static u8 get_cmd640_reg_vlb (u16 reg)
{
outb_p(reg, cmd640_key);
return inb_p(cmd640_key + 4);
}
static u8 get_cmd640_reg(u16 reg)
{ {
u8 b; u8 b;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
outb_p(reg, cmd640_key); b = __get_cmd640_reg(reg);
b = inb_p(cmd640_key + 4);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
return b; return b;
} }
static void put_cmd640_reg(u16 reg, u8 val)
{
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
__put_cmd640_reg(reg,val);
spin_unlock_irqrestore(&ide_lock, flags);
}
static int __init match_pci_cmd640_device (void) static int __init match_pci_cmd640_device (void)
{ {
const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
...@@ -307,8 +300,8 @@ static int __init match_pci_cmd640_device (void) ...@@ -307,8 +300,8 @@ static int __init match_pci_cmd640_device (void)
*/ */
static int __init probe_for_cmd640_pci1 (void) static int __init probe_for_cmd640_pci1 (void)
{ {
get_cmd640_reg = get_cmd640_reg_pci1; __get_cmd640_reg = get_cmd640_reg_pci1;
put_cmd640_reg = put_cmd640_reg_pci1; __put_cmd640_reg = put_cmd640_reg_pci1;
for (cmd640_key = 0x80000000; for (cmd640_key = 0x80000000;
cmd640_key <= 0x8000f800; cmd640_key <= 0x8000f800;
cmd640_key += 0x800) { cmd640_key += 0x800) {
...@@ -323,8 +316,8 @@ static int __init probe_for_cmd640_pci1 (void) ...@@ -323,8 +316,8 @@ static int __init probe_for_cmd640_pci1 (void)
*/ */
static int __init probe_for_cmd640_pci2 (void) static int __init probe_for_cmd640_pci2 (void)
{ {
get_cmd640_reg = get_cmd640_reg_pci2; __get_cmd640_reg = get_cmd640_reg_pci2;
put_cmd640_reg = put_cmd640_reg_pci2; __put_cmd640_reg = put_cmd640_reg_pci2;
for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) { for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) {
if (match_pci_cmd640_device()) if (match_pci_cmd640_device())
return 1; /* success */ return 1; /* success */
...@@ -339,8 +332,8 @@ static int __init probe_for_cmd640_vlb (void) ...@@ -339,8 +332,8 @@ static int __init probe_for_cmd640_vlb (void)
{ {
u8 b; u8 b;
get_cmd640_reg = get_cmd640_reg_vlb; __get_cmd640_reg = get_cmd640_reg_vlb;
put_cmd640_reg = put_cmd640_reg_vlb; __put_cmd640_reg = put_cmd640_reg_vlb;
cmd640_key = 0x178; cmd640_key = 0x178;
b = get_cmd640_reg(CFR); b = get_cmd640_reg(CFR);
if (b == 0xff || b == 0x00 || (b & CFR_AT_VESA_078h)) { if (b == 0xff || b == 0x00 || (b & CFR_AT_VESA_078h)) {
...@@ -454,7 +447,7 @@ static void set_prefetch_mode (unsigned int index, int mode) ...@@ -454,7 +447,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
b = get_cmd640_reg(reg); b = __get_cmd640_reg(reg);
if (mode) { /* want prefetch on? */ if (mode) { /* want prefetch on? */
#if CMD640_PREFETCH_MASKS #if CMD640_PREFETCH_MASKS
drive->no_unmask = 1; drive->no_unmask = 1;
...@@ -468,7 +461,7 @@ static void set_prefetch_mode (unsigned int index, int mode) ...@@ -468,7 +461,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
drive->io_32bit = 0; drive->io_32bit = 0;
b |= prefetch_masks[index]; /* disable prefetch */ b |= prefetch_masks[index]; /* disable prefetch */
} }
put_cmd640_reg(reg, b); __put_cmd640_reg(reg, b);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -576,9 +569,9 @@ static void program_drive_counts (unsigned int index) ...@@ -576,9 +569,9 @@ static void program_drive_counts (unsigned int index)
* and then the active/recovery counts into the DRWTIM reg * and then the active/recovery counts into the DRWTIM reg
* (this converts counts of 16 into counts of zero -- okay). * (this converts counts of 16 into counts of zero -- okay).
*/ */
setup_count |= get_cmd640_reg(arttim_regs[index]) & 0x3f; setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
put_cmd640_reg(arttim_regs[index], setup_count); __put_cmd640_reg(arttim_regs[index], setup_count);
put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment