diff options
Diffstat (limited to 'drivers/ide/cmd64x.c')
| -rw-r--r-- | drivers/ide/cmd64x.c | 103 |
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 | ||
| 229 | static int cmd648_dma_end(ide_drive_t *drive) | 231 | static 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 | ||
| 245 | static int cmd64x_dma_end(ide_drive_t *drive) | 245 | static 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 | ||
| 262 | static int cmd648_dma_test_irq(ide_drive_t *drive) | 259 | static 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 | ||
| 285 | static int cmd64x_dma_test_irq(ide_drive_t *drive) | 273 | static 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) | |||
| 370 | static const struct ide_port_ops cmd64x_port_ops = { | 348 | static 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 | ||
| 376 | static const struct ide_dma_ops cmd64x_dma_ops = { | 356 | static 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 | ||
| 387 | static const struct ide_dma_ops cmd646_rev1_dma_ops = { | 364 | static 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 | ||
| 398 | static 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 | |||
| 409 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | 375 | static 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 | } |
