diff options
| -rw-r--r-- | drivers/ata/pata_atp867x.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index ebfc8ff86519..27d3148b3d8e 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c | |||
| @@ -149,8 +149,10 @@ static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
| 149 | iowrite8(b, dp->dma_mode); | 149 | iowrite8(b, dp->dma_mode); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static int atp867x_get_active_clocks_shifted(unsigned int clk) | 152 | static int atp867x_get_active_clocks_shifted(struct ata_port *ap, |
| 153 | unsigned int clk) | ||
| 153 | { | 154 | { |
| 155 | struct atp867x_priv *dp = ap->private_data; | ||
| 154 | unsigned char clocks = clk; | 156 | unsigned char clocks = clk; |
| 155 | 157 | ||
| 156 | switch (clocks) { | 158 | switch (clocks) { |
| @@ -159,15 +161,25 @@ static int atp867x_get_active_clocks_shifted(unsigned int clk) | |||
| 159 | break; | 161 | break; |
| 160 | case 1 ... 7: | 162 | case 1 ... 7: |
| 161 | break; | 163 | break; |
| 162 | case 8 ... 12: | 164 | case 9 ... 12: |
| 163 | clocks = 7; | 165 | clocks = 7; |
| 164 | break; | 166 | break; |
| 165 | default: | 167 | default: |
| 166 | printk(KERN_WARNING "ATP867X: active %dclk is invalid. " | 168 | printk(KERN_WARNING "ATP867X: active %dclk is invalid. " |
| 167 | "Using default 8clk.\n", clk); | 169 | "Using default 8clk.\n", clk); |
| 168 | clocks = 0; /* 8 clk */ | 170 | case 8: /* default 8 clk */ |
| 169 | break; | 171 | clocks = 0; |
| 172 | goto active_clock_shift_done; | ||
| 170 | } | 173 | } |
| 174 | |||
| 175 | /* | ||
| 176 | * Doc 6.6.9: increase the clock value by 1 for safer PIO speed | ||
| 177 | * on 66MHz bus | ||
| 178 | */ | ||
| 179 | if (dp->pci66mhz && clocks < 7) | ||
| 180 | clocks++; | ||
| 181 | |||
| 182 | active_clock_shift_done: | ||
| 171 | return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT; | 183 | return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT; |
| 172 | } | 184 | } |
| 173 | 185 | ||
| @@ -181,20 +193,19 @@ static int atp867x_get_recover_clocks_shifted(unsigned int clk) | |||
| 181 | break; | 193 | break; |
| 182 | case 1 ... 11: | 194 | case 1 ... 11: |
| 183 | break; | 195 | break; |
| 184 | case 12: | ||
| 185 | clocks = 0; | ||
| 186 | break; | ||
| 187 | case 13: case 14: | 196 | case 13: case 14: |
| 188 | --clocks; | 197 | --clocks; /* by the spec */ |
| 189 | break; | 198 | break; |
| 190 | case 15: | 199 | case 15: |
| 191 | break; | 200 | break; |
| 192 | default: | 201 | default: |
| 193 | printk(KERN_WARNING "ATP867X: recover %dclk is invalid. " | 202 | printk(KERN_WARNING "ATP867X: recover %dclk is invalid. " |
| 194 | "Using default 15clk.\n", clk); | 203 | "Using default 12clk.\n", clk); |
| 195 | clocks = 0; /* 12 clk */ | 204 | case 12: /* default 12 clk */ |
| 205 | clocks = 0; | ||
| 196 | break; | 206 | break; |
| 197 | } | 207 | } |
| 208 | |||
| 198 | return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT; | 209 | return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT; |
| 199 | } | 210 | } |
| 200 | 211 | ||
| @@ -223,10 +234,8 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
| 223 | b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK); | 234 | b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK); |
| 224 | iowrite8(b, dp->dma_mode); | 235 | iowrite8(b, dp->dma_mode); |
| 225 | 236 | ||
| 226 | b = atp867x_get_active_clocks_shifted(t.active) | | 237 | b = atp867x_get_active_clocks_shifted(ap, t.active) | |
| 227 | atp867x_get_recover_clocks_shifted(t.recover); | 238 | atp867x_get_recover_clocks_shifted(t.recover); |
| 228 | if (dp->pci66mhz) | ||
| 229 | b += 0x10; | ||
| 230 | 239 | ||
| 231 | if (adev->devno & 1) | 240 | if (adev->devno & 1) |
| 232 | iowrite8(b, dp->slave_piospd); | 241 | iowrite8(b, dp->slave_piospd); |
| @@ -239,9 +248,24 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
| 239 | iowrite8(b, dp->eightb_piospd); | 248 | iowrite8(b, dp->eightb_piospd); |
| 240 | } | 249 | } |
| 241 | 250 | ||
| 251 | static int atp867x_cable_override(struct pci_dev *pdev) | ||
| 252 | { | ||
| 253 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_ARTOP && | ||
| 254 | (pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867A || | ||
| 255 | pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867B)) { | ||
| 256 | return 1; | ||
| 257 | } | ||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 242 | static int atp867x_cable_detect(struct ata_port *ap) | 261 | static int atp867x_cable_detect(struct ata_port *ap) |
| 243 | { | 262 | { |
| 244 | return ATA_CBL_PATA40_SHORT; | 263 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
| 264 | |||
| 265 | if (atp867x_cable_override(pdev)) | ||
| 266 | return ATA_CBL_PATA40_SHORT; | ||
| 267 | |||
| 268 | return ATA_CBL_PATA_UNK; | ||
| 245 | } | 269 | } |
| 246 | 270 | ||
| 247 | static struct scsi_host_template atp867x_sht = { | 271 | static struct scsi_host_template atp867x_sht = { |
