diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-12-07 14:30:06 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-03-01 14:58:43 -0500 |
commit | 1a1b172b9672e88d37adb5925b509e9236625d7e (patch) | |
tree | 9ccb1bb12343ed4ab5799d9ab08bd67f5b75bfba /drivers/ata/pata_hpt37x.c | |
parent | 60661933995bc7a09686c901439e17c2a4ea7d5d (diff) |
pata_hpt{37x|3x2n}: unify mode programming
As these drivers' set_piomode() and set_dmamode() methods are almost
identical, factor out the common hpt{37x|3x2n}_set_mode() function
to be called by both of them, the same as in 'pata_hpt366' driver.
This results in ~5% decrease in the 'pata_hpt37x' driver binary
size and in ~4% decrease in the 'pata_hpt3x2n' driver binary size
(as measured on x86-32).
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_hpt37x.c')
-rw-r--r-- | drivers/ata/pata_hpt37x.c | 137 |
1 files changed, 59 insertions, 78 deletions
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 342aaaaf3832..9b191763e6e5 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/libata.h> | 24 | #include <linux/libata.h> |
25 | 25 | ||
26 | #define DRV_NAME "pata_hpt37x" | 26 | #define DRV_NAME "pata_hpt37x" |
27 | #define DRV_VERSION "0.6.14" | 27 | #define DRV_VERSION "0.6.15" |
28 | 28 | ||
29 | struct hpt_clock { | 29 | struct hpt_clock { |
30 | u8 xfer_speed; | 30 | u8 xfer_speed; |
@@ -384,20 +384,12 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) | |||
384 | return ata_sff_prereset(link, deadline); | 384 | return ata_sff_prereset(link, deadline); |
385 | } | 385 | } |
386 | 386 | ||
387 | /** | 387 | static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, |
388 | * hpt370_set_piomode - PIO setup | 388 | u8 mode) |
389 | * @ap: ATA interface | ||
390 | * @adev: device on the interface | ||
391 | * | ||
392 | * Perform PIO mode setup. | ||
393 | */ | ||
394 | |||
395 | static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
396 | { | 389 | { |
397 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 390 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
398 | u32 addr1, addr2; | 391 | u32 addr1, addr2; |
399 | u32 reg; | 392 | u32 reg, timing, mask; |
400 | u32 mode; | ||
401 | u8 fast; | 393 | u8 fast; |
402 | 394 | ||
403 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | 395 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); |
@@ -409,11 +401,31 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
409 | fast |= 0x01; | 401 | fast |= 0x01; |
410 | pci_write_config_byte(pdev, addr2, fast); | 402 | pci_write_config_byte(pdev, addr2, fast); |
411 | 403 | ||
404 | /* Determine timing mask and find matching mode entry */ | ||
405 | if (mode < XFER_MW_DMA_0) | ||
406 | mask = 0xcfc3ffff; | ||
407 | else if (mode < XFER_UDMA_0) | ||
408 | mask = 0x31c001ff; | ||
409 | else | ||
410 | mask = 0x303c0000; | ||
411 | |||
412 | timing = hpt37x_find_mode(ap, mode); | ||
413 | |||
412 | pci_read_config_dword(pdev, addr1, ®); | 414 | pci_read_config_dword(pdev, addr1, ®); |
413 | mode = hpt37x_find_mode(ap, adev->pio_mode); | 415 | reg = (reg & ~mask) | (timing & mask); |
414 | mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | 416 | pci_write_config_dword(pdev, addr1, reg); |
415 | reg &= ~0xCFC3FFFF; /* Strip timing bits */ | 417 | } |
416 | pci_write_config_dword(pdev, addr1, reg | mode); | 418 | /** |
419 | * hpt370_set_piomode - PIO setup | ||
420 | * @ap: ATA interface | ||
421 | * @adev: device on the interface | ||
422 | * | ||
423 | * Perform PIO mode setup. | ||
424 | */ | ||
425 | |||
426 | static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
427 | { | ||
428 | hpt370_set_mode(ap, adev, adev->pio_mode); | ||
417 | } | 429 | } |
418 | 430 | ||
419 | /** | 431 | /** |
@@ -421,33 +433,12 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
421 | * @ap: ATA interface | 433 | * @ap: ATA interface |
422 | * @adev: Device being configured | 434 | * @adev: Device being configured |
423 | * | 435 | * |
424 | * Set up the channel for MWDMA or UDMA modes. Much the same as with | 436 | * Set up the channel for MWDMA or UDMA modes. |
425 | * PIO, load the mode number and then set MWDMA or UDMA flag. | ||
426 | */ | 437 | */ |
427 | 438 | ||
428 | static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 439 | static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
429 | { | 440 | { |
430 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 441 | hpt370_set_mode(ap, adev, adev->dma_mode); |
431 | u32 addr1, addr2; | ||
432 | u32 reg, mode, mask; | ||
433 | u8 fast; | ||
434 | |||
435 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | ||
436 | addr2 = 0x51 + 4 * ap->port_no; | ||
437 | |||
438 | /* Fast interrupt prediction disable, hold off interrupt disable */ | ||
439 | pci_read_config_byte(pdev, addr2, &fast); | ||
440 | fast &= ~0x02; | ||
441 | fast |= 0x01; | ||
442 | pci_write_config_byte(pdev, addr2, fast); | ||
443 | |||
444 | mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; | ||
445 | |||
446 | pci_read_config_dword(pdev, addr1, ®); | ||
447 | mode = hpt37x_find_mode(ap, adev->dma_mode); | ||
448 | mode &= mask; | ||
449 | reg &= ~mask; | ||
450 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
451 | } | 442 | } |
452 | 443 | ||
453 | /** | 444 | /** |
@@ -487,20 +478,12 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) | |||
487 | ata_bmdma_stop(qc); | 478 | ata_bmdma_stop(qc); |
488 | } | 479 | } |
489 | 480 | ||
490 | /** | 481 | static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev, |
491 | * hpt372_set_piomode - PIO setup | 482 | u8 mode) |
492 | * @ap: ATA interface | ||
493 | * @adev: device on the interface | ||
494 | * | ||
495 | * Perform PIO mode setup. | ||
496 | */ | ||
497 | |||
498 | static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
499 | { | 483 | { |
500 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 484 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
501 | u32 addr1, addr2; | 485 | u32 addr1, addr2; |
502 | u32 reg; | 486 | u32 reg, timing, mask; |
503 | u32 mode; | ||
504 | u8 fast; | 487 | u8 fast; |
505 | 488 | ||
506 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | 489 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); |
@@ -511,13 +494,32 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
511 | fast &= ~0x07; | 494 | fast &= ~0x07; |
512 | pci_write_config_byte(pdev, addr2, fast); | 495 | pci_write_config_byte(pdev, addr2, fast); |
513 | 496 | ||
497 | /* Determine timing mask and find matching mode entry */ | ||
498 | if (mode < XFER_MW_DMA_0) | ||
499 | mask = 0xcfc3ffff; | ||
500 | else if (mode < XFER_UDMA_0) | ||
501 | mask = 0x31c001ff; | ||
502 | else | ||
503 | mask = 0x303c0000; | ||
504 | |||
505 | timing = hpt37x_find_mode(ap, mode); | ||
506 | |||
514 | pci_read_config_dword(pdev, addr1, ®); | 507 | pci_read_config_dword(pdev, addr1, ®); |
515 | mode = hpt37x_find_mode(ap, adev->pio_mode); | 508 | reg = (reg & ~mask) | (timing & mask); |
509 | pci_write_config_dword(pdev, addr1, reg); | ||
510 | } | ||
516 | 511 | ||
517 | printk("Find mode for %d reports %X\n", adev->pio_mode, mode); | 512 | /** |
518 | mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | 513 | * hpt372_set_piomode - PIO setup |
519 | reg &= ~0xCFC3FFFF; /* Strip timing bits */ | 514 | * @ap: ATA interface |
520 | pci_write_config_dword(pdev, addr1, reg | mode); | 515 | * @adev: device on the interface |
516 | * | ||
517 | * Perform PIO mode setup. | ||
518 | */ | ||
519 | |||
520 | static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
521 | { | ||
522 | hpt372_set_mode(ap, adev, adev->pio_mode); | ||
521 | } | 523 | } |
522 | 524 | ||
523 | /** | 525 | /** |
@@ -525,33 +527,12 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
525 | * @ap: ATA interface | 527 | * @ap: ATA interface |
526 | * @adev: Device being configured | 528 | * @adev: Device being configured |
527 | * | 529 | * |
528 | * Set up the channel for MWDMA or UDMA modes. Much the same as with | 530 | * Set up the channel for MWDMA or UDMA modes. |
529 | * PIO, load the mode number and then set MWDMA or UDMA flag. | ||
530 | */ | 531 | */ |
531 | 532 | ||
532 | static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 533 | static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
533 | { | 534 | { |
534 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 535 | hpt372_set_mode(ap, adev, adev->dma_mode); |
535 | u32 addr1, addr2; | ||
536 | u32 reg, mode, mask; | ||
537 | u8 fast; | ||
538 | |||
539 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | ||
540 | addr2 = 0x51 + 4 * ap->port_no; | ||
541 | |||
542 | /* Fast interrupt prediction disable, hold off interrupt disable */ | ||
543 | pci_read_config_byte(pdev, addr2, &fast); | ||
544 | fast &= ~0x07; | ||
545 | pci_write_config_byte(pdev, addr2, fast); | ||
546 | |||
547 | mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; | ||
548 | |||
549 | pci_read_config_dword(pdev, addr1, ®); | ||
550 | mode = hpt37x_find_mode(ap, adev->dma_mode); | ||
551 | printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); | ||
552 | mode &= mask; | ||
553 | reg &= ~mask; | ||
554 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
555 | } | 536 | } |
556 | 537 | ||
557 | /** | 538 | /** |