aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/cmd64x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/cmd64x.c')
-rw-r--r--drivers/ide/cmd64x.c103
1 files changed, 32 insertions, 71 deletions
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 80b777e4247b..03c86209446f 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 1998 David S. Miller (davem@redhat.com) 7 * Copyright (C) 1998 David S. Miller (davem@redhat.com)
8 * 8 *
9 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> 9 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
10 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> 10 * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com>
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
@@ -118,8 +118,9 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
118 ide_hwif_t *hwif = drive->hwif; 118 ide_hwif_t *hwif = drive->hwif;
119 struct pci_dev *dev = to_pci_dev(hwif->dev); 119 struct pci_dev *dev = to_pci_dev(hwif->dev);
120 struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); 120 struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
121 unsigned long setup_count;
121 unsigned int cycle_time; 122 unsigned int cycle_time;
122 u8 setup_count, arttim = 0; 123 u8 arttim = 0;
123 124
124 static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; 125 static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
125 static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; 126 static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
@@ -140,10 +141,11 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
140 if (hwif->channel) { 141 if (hwif->channel) {
141 ide_drive_t *pair = ide_get_pair_dev(drive); 142 ide_drive_t *pair = ide_get_pair_dev(drive);
142 143
143 drive->drive_data = setup_count; 144 ide_set_drivedata(drive, (void *)setup_count);
144 145
145 if (pair) 146 if (pair)
146 setup_count = max_t(u8, setup_count, pair->drive_data); 147 setup_count = max_t(u8, setup_count,
148 (unsigned long)ide_get_drivedata(pair));
147 } 149 }
148 150
149 if (setup_count > 5) /* shouldn't actually happen... */ 151 if (setup_count > 5) /* shouldn't actually happen... */
@@ -226,11 +228,11 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
226 (void) pci_write_config_byte(dev, pciU, regU); 228 (void) pci_write_config_byte(dev, pciU, regU);
227} 229}
228 230
229static int cmd648_dma_end(ide_drive_t *drive) 231static void cmd648_clear_irq(ide_drive_t *drive)
230{ 232{
231 ide_hwif_t *hwif = drive->hwif; 233 ide_hwif_t *hwif = drive->hwif;
232 unsigned long base = hwif->dma_base - (hwif->channel * 8); 234 struct pci_dev *dev = to_pci_dev(hwif->dev);
233 int err = ide_dma_end(drive); 235 unsigned long base = pci_resource_start(dev, 4);
234 u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : 236 u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
235 MRDMODE_INTR_CH0; 237 MRDMODE_INTR_CH0;
236 u8 mrdmode = inb(base + 1); 238 u8 mrdmode = inb(base + 1);
@@ -238,11 +240,9 @@ static int cmd648_dma_end(ide_drive_t *drive)
238 /* clear the interrupt bit */ 240 /* clear the interrupt bit */
239 outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, 241 outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,
240 base + 1); 242 base + 1);
241
242 return err;
243} 243}
244 244
245static int cmd64x_dma_end(ide_drive_t *drive) 245static void cmd64x_clear_irq(ide_drive_t *drive)
246{ 246{
247 ide_hwif_t *hwif = drive->hwif; 247 ide_hwif_t *hwif = drive->hwif;
248 struct pci_dev *dev = to_pci_dev(hwif->dev); 248 struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -250,62 +250,40 @@ static int cmd64x_dma_end(ide_drive_t *drive)
250 u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : 250 u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 :
251 CFR_INTR_CH0; 251 CFR_INTR_CH0;
252 u8 irq_stat = 0; 252 u8 irq_stat = 0;
253 int err = ide_dma_end(drive);
254 253
255 (void) pci_read_config_byte(dev, irq_reg, &irq_stat); 254 (void) pci_read_config_byte(dev, irq_reg, &irq_stat);
256 /* clear the interrupt bit */ 255 /* clear the interrupt bit */
257 (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask); 256 (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask);
258
259 return err;
260} 257}
261 258
262static int cmd648_dma_test_irq(ide_drive_t *drive) 259static int cmd648_test_irq(ide_hwif_t *hwif)
263{ 260{
264 ide_hwif_t *hwif = drive->hwif; 261 struct pci_dev *dev = to_pci_dev(hwif->dev);
265 unsigned long base = hwif->dma_base - (hwif->channel * 8); 262 unsigned long base = pci_resource_start(dev, 4);
266 u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : 263 u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
267 MRDMODE_INTR_CH0; 264 MRDMODE_INTR_CH0;
268 u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
269 u8 mrdmode = inb(base + 1); 265 u8 mrdmode = inb(base + 1);
270 266
271#ifdef DEBUG 267 pr_debug("%s: mrdmode: 0x%02x irq_mask: 0x%02x\n",
272 printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", 268 hwif->name, mrdmode, irq_mask);
273 drive->name, dma_stat, mrdmode, irq_mask);
274#endif
275 if (!(mrdmode & irq_mask))
276 return 0;
277
278 /* return 1 if INTR asserted */
279 if (dma_stat & 4)
280 return 1;
281 269
282 return 0; 270 return (mrdmode & irq_mask) ? 1 : 0;
283} 271}
284 272
285static int cmd64x_dma_test_irq(ide_drive_t *drive) 273static int cmd64x_test_irq(ide_hwif_t *hwif)
286{ 274{
287 ide_hwif_t *hwif = drive->hwif;
288 struct pci_dev *dev = to_pci_dev(hwif->dev); 275 struct pci_dev *dev = to_pci_dev(hwif->dev);
289 int irq_reg = hwif->channel ? ARTTIM23 : CFR; 276 int irq_reg = hwif->channel ? ARTTIM23 : CFR;
290 u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : 277 u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 :
291 CFR_INTR_CH0; 278 CFR_INTR_CH0;
292 u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
293 u8 irq_stat = 0; 279 u8 irq_stat = 0;
294 280
295 (void) pci_read_config_byte(dev, irq_reg, &irq_stat); 281 (void) pci_read_config_byte(dev, irq_reg, &irq_stat);
296 282
297#ifdef DEBUG 283 pr_debug("%s: irq_stat: 0x%02x irq_mask: 0x%02x\n",
298 printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n", 284 hwif->name, irq_stat, irq_mask);
299 drive->name, dma_stat, irq_stat, irq_mask);
300#endif
301 if (!(irq_stat & irq_mask))
302 return 0;
303
304 /* return 1 if INTR asserted */
305 if (dma_stat & 4)
306 return 1;
307 285
308 return 0; 286 return (irq_stat & irq_mask) ? 1 : 0;
309} 287}
310 288
311/* 289/*
@@ -370,18 +348,17 @@ static u8 cmd64x_cable_detect(ide_hwif_t *hwif)
370static const struct ide_port_ops cmd64x_port_ops = { 348static const struct ide_port_ops cmd64x_port_ops = {
371 .set_pio_mode = cmd64x_set_pio_mode, 349 .set_pio_mode = cmd64x_set_pio_mode,
372 .set_dma_mode = cmd64x_set_dma_mode, 350 .set_dma_mode = cmd64x_set_dma_mode,
351 .clear_irq = cmd64x_clear_irq,
352 .test_irq = cmd64x_test_irq,
373 .cable_detect = cmd64x_cable_detect, 353 .cable_detect = cmd64x_cable_detect,
374}; 354};
375 355
376static const struct ide_dma_ops cmd64x_dma_ops = { 356static const struct ide_port_ops cmd648_port_ops = {
377 .dma_host_set = ide_dma_host_set, 357 .set_pio_mode = cmd64x_set_pio_mode,
378 .dma_setup = ide_dma_setup, 358 .set_dma_mode = cmd64x_set_dma_mode,
379 .dma_start = ide_dma_start, 359 .clear_irq = cmd648_clear_irq,
380 .dma_end = cmd64x_dma_end, 360 .test_irq = cmd648_test_irq,
381 .dma_test_irq = cmd64x_dma_test_irq, 361 .cable_detect = cmd64x_cable_detect,
382 .dma_lost_irq = ide_dma_lost_irq,
383 .dma_timer_expiry = ide_dma_sff_timer_expiry,
384 .dma_sff_read_status = ide_dma_sff_read_status,
385}; 362};
386 363
387static const struct ide_dma_ops cmd646_rev1_dma_ops = { 364static const struct ide_dma_ops cmd646_rev1_dma_ops = {
@@ -395,24 +372,12 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
395 .dma_sff_read_status = ide_dma_sff_read_status, 372 .dma_sff_read_status = ide_dma_sff_read_status,
396}; 373};
397 374
398static const struct ide_dma_ops cmd648_dma_ops = {
399 .dma_host_set = ide_dma_host_set,
400 .dma_setup = ide_dma_setup,
401 .dma_start = ide_dma_start,
402 .dma_end = cmd648_dma_end,
403 .dma_test_irq = cmd648_dma_test_irq,
404 .dma_lost_irq = ide_dma_lost_irq,
405 .dma_timer_expiry = ide_dma_sff_timer_expiry,
406 .dma_sff_read_status = ide_dma_sff_read_status,
407};
408
409static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { 375static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
410 { /* 0: CMD643 */ 376 { /* 0: CMD643 */
411 .name = DRV_NAME, 377 .name = DRV_NAME,
412 .init_chipset = init_chipset_cmd64x, 378 .init_chipset = init_chipset_cmd64x,
413 .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, 379 .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
414 .port_ops = &cmd64x_port_ops, 380 .port_ops = &cmd64x_port_ops,
415 .dma_ops = &cmd64x_dma_ops,
416 .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | 381 .host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
417 IDE_HFLAG_ABUSE_PREFETCH, 382 IDE_HFLAG_ABUSE_PREFETCH,
418 .pio_mask = ATA_PIO5, 383 .pio_mask = ATA_PIO5,
@@ -423,8 +388,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
423 .name = DRV_NAME, 388 .name = DRV_NAME,
424 .init_chipset = init_chipset_cmd64x, 389 .init_chipset = init_chipset_cmd64x,
425 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, 390 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
426 .port_ops = &cmd64x_port_ops, 391 .port_ops = &cmd648_port_ops,
427 .dma_ops = &cmd648_dma_ops,
428 .host_flags = IDE_HFLAG_SERIALIZE | 392 .host_flags = IDE_HFLAG_SERIALIZE |
429 IDE_HFLAG_ABUSE_PREFETCH, 393 IDE_HFLAG_ABUSE_PREFETCH,
430 .pio_mask = ATA_PIO5, 394 .pio_mask = ATA_PIO5,
@@ -435,8 +399,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
435 .name = DRV_NAME, 399 .name = DRV_NAME,
436 .init_chipset = init_chipset_cmd64x, 400 .init_chipset = init_chipset_cmd64x,
437 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, 401 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
438 .port_ops = &cmd64x_port_ops, 402 .port_ops = &cmd648_port_ops,
439 .dma_ops = &cmd648_dma_ops,
440 .host_flags = IDE_HFLAG_ABUSE_PREFETCH, 403 .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
441 .pio_mask = ATA_PIO5, 404 .pio_mask = ATA_PIO5,
442 .mwdma_mask = ATA_MWDMA2, 405 .mwdma_mask = ATA_MWDMA2,
@@ -446,8 +409,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
446 .name = DRV_NAME, 409 .name = DRV_NAME,
447 .init_chipset = init_chipset_cmd64x, 410 .init_chipset = init_chipset_cmd64x,
448 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, 411 .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
449 .port_ops = &cmd64x_port_ops, 412 .port_ops = &cmd648_port_ops,
450 .dma_ops = &cmd648_dma_ops,
451 .host_flags = IDE_HFLAG_ABUSE_PREFETCH, 413 .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
452 .pio_mask = ATA_PIO5, 414 .pio_mask = ATA_PIO5,
453 .mwdma_mask = ATA_MWDMA2, 415 .mwdma_mask = ATA_MWDMA2,
@@ -484,10 +446,9 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic
484 */ 446 */
485 if (dev->revision < 3) { 447 if (dev->revision < 3) {
486 d.enablebits[0].reg = 0; 448 d.enablebits[0].reg = 0;
449 d.port_ops = &cmd64x_port_ops;
487 if (dev->revision == 1) 450 if (dev->revision == 1)
488 d.dma_ops = &cmd646_rev1_dma_ops; 451 d.dma_ops = &cmd646_rev1_dma_ops;
489 else
490 d.dma_ops = &cmd64x_dma_ops;
491 } 452 }
492 } 453 }
493 } 454 }