diff options
Diffstat (limited to 'drivers/ata/pata_efar.c')
-rw-r--r-- | drivers/ata/pata_efar.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 5556163c80de..1617421f7e76 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -68,6 +68,8 @@ static int efar_cable_detect(struct ata_port *ap) | |||
68 | return ATA_CBL_PATA80; | 68 | return ATA_CBL_PATA80; |
69 | } | 69 | } |
70 | 70 | ||
71 | static DEFINE_SPINLOCK(efar_lock); | ||
72 | |||
71 | /** | 73 | /** |
72 | * efar_set_piomode - Initialize host controller PATA PIO timings | 74 | * efar_set_piomode - Initialize host controller PATA PIO timings |
73 | * @ap: Port whose timings we are configuring | 75 | * @ap: Port whose timings we are configuring |
@@ -84,7 +86,9 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
84 | unsigned int pio = adev->pio_mode - XFER_PIO_0; | 86 | unsigned int pio = adev->pio_mode - XFER_PIO_0; |
85 | struct pci_dev *dev = to_pci_dev(ap->host->dev); | 87 | struct pci_dev *dev = to_pci_dev(ap->host->dev); |
86 | unsigned int idetm_port= ap->port_no ? 0x42 : 0x40; | 88 | unsigned int idetm_port= ap->port_no ? 0x42 : 0x40; |
89 | unsigned long flags; | ||
87 | u16 idetm_data; | 90 | u16 idetm_data; |
91 | u8 udma_enable; | ||
88 | int control = 0; | 92 | int control = 0; |
89 | 93 | ||
90 | /* | 94 | /* |
@@ -107,6 +111,8 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
107 | if (adev->class == ATA_DEV_ATA) | 111 | if (adev->class == ATA_DEV_ATA) |
108 | control |= 4; /* PPE */ | 112 | control |= 4; /* PPE */ |
109 | 113 | ||
114 | spin_lock_irqsave(&efar_lock, flags); | ||
115 | |||
110 | pci_read_config_word(dev, idetm_port, &idetm_data); | 116 | pci_read_config_word(dev, idetm_port, &idetm_data); |
111 | 117 | ||
112 | /* Set PPE, IE, and TIME as appropriate */ | 118 | /* Set PPE, IE, and TIME as appropriate */ |
@@ -131,6 +137,11 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
131 | 137 | ||
132 | idetm_data |= 0x4000; /* Ensure SITRE is set */ | 138 | idetm_data |= 0x4000; /* Ensure SITRE is set */ |
133 | pci_write_config_word(dev, idetm_port, idetm_data); | 139 | pci_write_config_word(dev, idetm_port, idetm_data); |
140 | |||
141 | pci_read_config_byte(dev, 0x48, &udma_enable); | ||
142 | udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); | ||
143 | pci_write_config_byte(dev, 0x48, udma_enable); | ||
144 | spin_unlock_irqrestore(&efar_lock, flags); | ||
134 | } | 145 | } |
135 | 146 | ||
136 | /** | 147 | /** |
@@ -151,6 +162,7 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
151 | u16 master_data; | 162 | u16 master_data; |
152 | u8 speed = adev->dma_mode; | 163 | u8 speed = adev->dma_mode; |
153 | int devid = adev->devno + 2 * ap->port_no; | 164 | int devid = adev->devno + 2 * ap->port_no; |
165 | unsigned long flags; | ||
154 | u8 udma_enable; | 166 | u8 udma_enable; |
155 | 167 | ||
156 | static const /* ISP RTC */ | 168 | static const /* ISP RTC */ |
@@ -160,6 +172,8 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
160 | { 2, 1 }, | 172 | { 2, 1 }, |
161 | { 2, 3 }, }; | 173 | { 2, 3 }, }; |
162 | 174 | ||
175 | spin_lock_irqsave(&efar_lock, flags); | ||
176 | |||
163 | pci_read_config_word(dev, master_port, &master_data); | 177 | pci_read_config_word(dev, master_port, &master_data); |
164 | pci_read_config_byte(dev, 0x48, &udma_enable); | 178 | pci_read_config_byte(dev, 0x48, &udma_enable); |
165 | 179 | ||
@@ -217,6 +231,7 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
217 | pci_write_config_word(dev, master_port, master_data); | 231 | pci_write_config_word(dev, master_port, master_data); |
218 | } | 232 | } |
219 | pci_write_config_byte(dev, 0x48, udma_enable); | 233 | pci_write_config_byte(dev, 0x48, udma_enable); |
234 | spin_unlock_irqrestore(&efar_lock, flags); | ||
220 | } | 235 | } |
221 | 236 | ||
222 | static struct scsi_host_template efar_sht = { | 237 | static struct scsi_host_template efar_sht = { |