diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-07-24 12:16:06 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-31 02:04:50 -0400 |
commit | 963e4975c6f93c148ca809d986d412201df9af89 (patch) | |
tree | 41cb6ec55e48a2186dbe4c13531fd05439efbade /drivers/ata/pata_it821x.c | |
parent | 1f938d060a7bc01b5f82d46db3e38cd501b445a6 (diff) |
pata_it821x: Driver updates and reworking
- Add support for the RDC 1010 variant
- Rework the core library to have a read_id method. This allows the hacky
bits of it821x to go and prepares us for pata_hd
- Switch from WARN to BUG in ata_id_string as it will reboot if you get
it wrong so WARN won't be seen
- Allow the issue of command 0xFC on the 821x. This is needed to query
rebuild status.
- Tidy up printk formatting
- Do more ident rewriting on RAID volumes to handle firmware provided
ident data which is rather wonky
- Report the firmware revision and device layout in RAID mode
- Don't try and disable raid on the 8211 or RDC - they don't have the
relevant bits
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_it821x.c')
-rw-r--r-- | drivers/ata/pata_it821x.c | 270 |
1 files changed, 236 insertions, 34 deletions
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index e10816931b2f..27843c70eb9d 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -80,7 +80,7 @@ | |||
80 | 80 | ||
81 | 81 | ||
82 | #define DRV_NAME "pata_it821x" | 82 | #define DRV_NAME "pata_it821x" |
83 | #define DRV_VERSION "0.3.8" | 83 | #define DRV_VERSION "0.4.0" |
84 | 84 | ||
85 | struct it821x_dev | 85 | struct it821x_dev |
86 | { | 86 | { |
@@ -425,6 +425,8 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc) | |||
425 | case ATA_CMD_WRITE_MULTI: | 425 | case ATA_CMD_WRITE_MULTI: |
426 | case ATA_CMD_WRITE_MULTI_EXT: | 426 | case ATA_CMD_WRITE_MULTI_EXT: |
427 | case ATA_CMD_ID_ATA: | 427 | case ATA_CMD_ID_ATA: |
428 | case ATA_CMD_INIT_DEV_PARAMS: | ||
429 | case 0xFC: /* Internal 'report rebuild state' */ | ||
428 | /* Arguably should just no-op this one */ | 430 | /* Arguably should just no-op this one */ |
429 | case ATA_CMD_SET_FEATURES: | 431 | case ATA_CMD_SET_FEATURES: |
430 | return ata_sff_qc_issue(qc); | 432 | return ata_sff_qc_issue(qc); |
@@ -509,7 +511,7 @@ static void it821x_dev_config(struct ata_device *adev) | |||
509 | 511 | ||
510 | if (strstr(model_num, "Integrated Technology Express")) { | 512 | if (strstr(model_num, "Integrated Technology Express")) { |
511 | /* RAID mode */ | 513 | /* RAID mode */ |
512 | printk(KERN_INFO "IT821x %sRAID%d volume", | 514 | ata_dev_printk(adev, KERN_INFO, "%sRAID%d volume", |
513 | adev->id[147]?"Bootable ":"", | 515 | adev->id[147]?"Bootable ":"", |
514 | adev->id[129]); | 516 | adev->id[129]); |
515 | if (adev->id[129] != 1) | 517 | if (adev->id[129] != 1) |
@@ -519,37 +521,51 @@ static void it821x_dev_config(struct ata_device *adev) | |||
519 | /* This is a controller firmware triggered funny, don't | 521 | /* This is a controller firmware triggered funny, don't |
520 | report the drive faulty! */ | 522 | report the drive faulty! */ |
521 | adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; | 523 | adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; |
524 | /* No HPA in 'smart' mode */ | ||
525 | adev->horkage |= ATA_HORKAGE_BROKEN_HPA; | ||
522 | } | 526 | } |
523 | 527 | ||
524 | /** | 528 | /** |
525 | * it821x_ident_hack - Hack identify data up | 529 | * it821x_read_id - Hack identify data up |
526 | * @ap: Port | 530 | * @adev: device to read |
531 | * @tf: proposed taskfile | ||
532 | * @id: buffer for returned ident data | ||
527 | * | 533 | * |
528 | * Walk the devices on this firmware driven port and slightly | 534 | * Query the devices on this firmware driven port and slightly |
529 | * mash the identify data to stop us and common tools trying to | 535 | * mash the identify data to stop us and common tools trying to |
530 | * use features not firmware supported. The firmware itself does | 536 | * use features not firmware supported. The firmware itself does |
531 | * some masking (eg SMART) but not enough. | 537 | * some masking (eg SMART) but not enough. |
532 | * | ||
533 | * This is a bit of an abuse of the cable method, but it is the | ||
534 | * only method called at the right time. We could modify the libata | ||
535 | * core specifically for ident hacking but while we have one offender | ||
536 | * it seems better to keep the fallout localised. | ||
537 | */ | 538 | */ |
538 | 539 | ||
539 | static int it821x_ident_hack(struct ata_port *ap) | 540 | static unsigned int it821x_read_id(struct ata_device *adev, |
541 | struct ata_taskfile *tf, u16 *id) | ||
540 | { | 542 | { |
541 | struct ata_device *adev; | 543 | unsigned int err_mask; |
542 | ata_link_for_each_dev(adev, &ap->link) { | 544 | unsigned char model_num[ATA_ID_PROD_LEN + 1]; |
543 | if (ata_dev_enabled(adev)) { | 545 | |
544 | adev->id[84] &= ~(1 << 6); /* No FUA */ | 546 | err_mask = ata_do_dev_read_id(adev, tf, id); |
545 | adev->id[85] &= ~(1 << 10); /* No HPA */ | 547 | if (err_mask) |
546 | adev->id[76] = 0; /* No NCQ/AN etc */ | 548 | return err_mask; |
547 | } | 549 | ata_id_c_string(id, model_num, ATA_ID_PROD, sizeof(model_num)); |
550 | |||
551 | id[83] &= ~(1 << 12); /* Cache flush is firmware handled */ | ||
552 | id[83] &= ~(1 << 13); /* Ditto for LBA48 flushes */ | ||
553 | id[84] &= ~(1 << 6); /* No FUA */ | ||
554 | id[85] &= ~(1 << 10); /* No HPA */ | ||
555 | id[76] = 0; /* No NCQ/AN etc */ | ||
556 | |||
557 | if (strstr(model_num, "Integrated Technology Express")) { | ||
558 | /* Set feature bits the firmware neglects */ | ||
559 | id[49] |= 0x0300; /* LBA, DMA */ | ||
560 | id[82] |= 0x0400; /* LBA48 */ | ||
561 | id[83] &= 0x7FFF; | ||
562 | id[83] |= 0x4000; /* Word 83 is valid */ | ||
563 | id[86] |= 0x0400; /* LBA48 on */ | ||
564 | id[ATA_ID_MAJOR_VER] |= 0x1F; | ||
548 | } | 565 | } |
549 | return ata_cable_unknown(ap); | 566 | return err_mask; |
550 | } | 567 | } |
551 | 568 | ||
552 | |||
553 | /** | 569 | /** |
554 | * it821x_check_atapi_dma - ATAPI DMA handler | 570 | * it821x_check_atapi_dma - ATAPI DMA handler |
555 | * @qc: Command we are about to issue | 571 | * @qc: Command we are about to issue |
@@ -577,6 +593,136 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) | |||
577 | return 0; | 593 | return 0; |
578 | } | 594 | } |
579 | 595 | ||
596 | /** | ||
597 | * it821x_display_disk - display disk setup | ||
598 | * @n: Device number | ||
599 | * @buf: Buffer block from firmware | ||
600 | * | ||
601 | * Produce a nice informative display of the device setup as provided | ||
602 | * by the firmware. | ||
603 | */ | ||
604 | |||
605 | static void it821x_display_disk(int n, u8 *buf) | ||
606 | { | ||
607 | unsigned char id[41]; | ||
608 | int mode = 0; | ||
609 | char *mtype; | ||
610 | char mbuf[8]; | ||
611 | char *cbl = "(40 wire cable)"; | ||
612 | |||
613 | static const char *types[5] = { | ||
614 | "RAID0", "RAID1" "RAID 0+1", "JBOD", "DISK" | ||
615 | }; | ||
616 | |||
617 | if (buf[52] > 4) /* No Disk */ | ||
618 | return; | ||
619 | |||
620 | ata_id_c_string((u16 *)buf, id, 0, 41); | ||
621 | |||
622 | if (buf[51]) { | ||
623 | mode = ffs(buf[51]); | ||
624 | mtype = "UDMA"; | ||
625 | } else if (buf[49]) { | ||
626 | mode = ffs(buf[49]); | ||
627 | mtype = "MWDMA"; | ||
628 | } | ||
629 | |||
630 | if (buf[76]) | ||
631 | cbl = ""; | ||
632 | |||
633 | if (mode) | ||
634 | snprintf(mbuf, 8, "%5s%d", mtype, mode - 1); | ||
635 | else | ||
636 | strcpy(mbuf, "PIO"); | ||
637 | if (buf[52] == 4) | ||
638 | printk(KERN_INFO "%d: %-6s %-8s %s %s\n", | ||
639 | n, mbuf, types[buf[52]], id, cbl); | ||
640 | else | ||
641 | printk(KERN_INFO "%d: %-6s %-8s Volume: %1d %s %s\n", | ||
642 | n, mbuf, types[buf[52]], buf[53], id, cbl); | ||
643 | if (buf[125] < 100) | ||
644 | printk(KERN_INFO "%d: Rebuilding: %d%%\n", n, buf[125]); | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * it821x_firmware_command - issue firmware command | ||
649 | * @ap: IT821x port to interrogate | ||
650 | * @cmd: command | ||
651 | * @len: length | ||
652 | * | ||
653 | * Issue firmware commands expecting data back from the controller. We | ||
654 | * use this to issue commands that do not go via the normal paths. Other | ||
655 | * commands such as 0xFC can be issued normally. | ||
656 | */ | ||
657 | |||
658 | static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len) | ||
659 | { | ||
660 | u8 status; | ||
661 | int n = 0; | ||
662 | u16 *buf = kmalloc(len, GFP_KERNEL); | ||
663 | if (buf == NULL) { | ||
664 | printk(KERN_ERR "it821x_firmware_command: Out of memory\n"); | ||
665 | return NULL; | ||
666 | } | ||
667 | /* This isn't quite a normal ATA command as we are talking to the | ||
668 | firmware not the drives */ | ||
669 | ap->ctl |= ATA_NIEN; | ||
670 | iowrite8(ap->ctl, ap->ioaddr.ctl_addr); | ||
671 | ata_wait_idle(ap); | ||
672 | iowrite8(ATA_DEVICE_OBS, ap->ioaddr.device_addr); | ||
673 | iowrite8(cmd, ap->ioaddr.command_addr); | ||
674 | udelay(1); | ||
675 | /* This should be almost immediate but a little paranoia goes a long | ||
676 | way. */ | ||
677 | while(n++ < 10) { | ||
678 | status = ioread8(ap->ioaddr.status_addr); | ||
679 | if (status & ATA_ERR) { | ||
680 | kfree(buf); | ||
681 | printk(KERN_ERR "it821x_firmware_command: rejected\n"); | ||
682 | return NULL; | ||
683 | } | ||
684 | if (status & ATA_DRQ) { | ||
685 | ioread16_rep(ap->ioaddr.data_addr, buf, len/2); | ||
686 | return (u8 *)buf; | ||
687 | } | ||
688 | mdelay(1); | ||
689 | } | ||
690 | kfree(buf); | ||
691 | printk(KERN_ERR "it821x_firmware_command: timeout\n"); | ||
692 | return NULL; | ||
693 | } | ||
694 | |||
695 | /** | ||
696 | * it821x_probe_firmware - firmware reporting/setup | ||
697 | * @ap: IT821x port being probed | ||
698 | * | ||
699 | * Probe the firmware of the controller by issuing firmware command | ||
700 | * 0xFA and analysing the returned data. | ||
701 | */ | ||
702 | |||
703 | static void it821x_probe_firmware(struct ata_port *ap) | ||
704 | { | ||
705 | u8 *buf; | ||
706 | int i; | ||
707 | |||
708 | /* This is a bit ugly as we can't just issue a task file to a device | ||
709 | as this is controller magic */ | ||
710 | |||
711 | buf = it821x_firmware_command(ap, 0xFA, 512); | ||
712 | |||
713 | if (buf != NULL) { | ||
714 | printk(KERN_INFO "pata_it821x: Firmware %02X/%02X/%02X%02X\n", | ||
715 | buf[505], | ||
716 | buf[506], | ||
717 | buf[507], | ||
718 | buf[508]); | ||
719 | for (i = 0; i < 4; i++) | ||
720 | it821x_display_disk(i, buf + 128 * i); | ||
721 | kfree(buf); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | |||
580 | 726 | ||
581 | /** | 727 | /** |
582 | * it821x_port_start - port setup | 728 | * it821x_port_start - port setup |
@@ -610,6 +756,8 @@ static int it821x_port_start(struct ata_port *ap) | |||
610 | /* Long I/O's although allowed in LBA48 space cause the | 756 | /* Long I/O's although allowed in LBA48 space cause the |
611 | onboard firmware to enter the twighlight zone */ | 757 | onboard firmware to enter the twighlight zone */ |
612 | /* No ATAPI DMA in this mode either */ | 758 | /* No ATAPI DMA in this mode either */ |
759 | if (ap->port_no == 0) | ||
760 | it821x_probe_firmware(ap); | ||
613 | } | 761 | } |
614 | /* Pull the current clocks from 0x50 */ | 762 | /* Pull the current clocks from 0x50 */ |
615 | if (conf & (1 << (1 + ap->port_no))) | 763 | if (conf & (1 << (1 + ap->port_no))) |
@@ -631,6 +779,25 @@ static int it821x_port_start(struct ata_port *ap) | |||
631 | return 0; | 779 | return 0; |
632 | } | 780 | } |
633 | 781 | ||
782 | /** | ||
783 | * it821x_rdc_cable - Cable detect for RDC1010 | ||
784 | * @ap: port we are checking | ||
785 | * | ||
786 | * Return the RDC1010 cable type. Unlike the IT821x we know how to do | ||
787 | * this and can do host side cable detect | ||
788 | */ | ||
789 | |||
790 | static int it821x_rdc_cable(struct ata_port *ap) | ||
791 | { | ||
792 | u16 r40; | ||
793 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
794 | |||
795 | pci_read_config_word(pdev, 0x40, &r40); | ||
796 | if (r40 & (1 << (2 + ap->port_no))) | ||
797 | return ATA_CBL_PATA40; | ||
798 | return ATA_CBL_PATA80; | ||
799 | } | ||
800 | |||
634 | static struct scsi_host_template it821x_sht = { | 801 | static struct scsi_host_template it821x_sht = { |
635 | ATA_BMDMA_SHT(DRV_NAME), | 802 | ATA_BMDMA_SHT(DRV_NAME), |
636 | }; | 803 | }; |
@@ -641,9 +808,10 @@ static struct ata_port_operations it821x_smart_port_ops = { | |||
641 | .check_atapi_dma= it821x_check_atapi_dma, | 808 | .check_atapi_dma= it821x_check_atapi_dma, |
642 | .qc_issue = it821x_smart_qc_issue, | 809 | .qc_issue = it821x_smart_qc_issue, |
643 | 810 | ||
644 | .cable_detect = it821x_ident_hack, | 811 | .cable_detect = ata_cable_80wire, |
645 | .set_mode = it821x_smart_set_mode, | 812 | .set_mode = it821x_smart_set_mode, |
646 | .dev_config = it821x_dev_config, | 813 | .dev_config = it821x_dev_config, |
814 | .read_id = it821x_read_id, | ||
647 | 815 | ||
648 | .port_start = it821x_port_start, | 816 | .port_start = it821x_port_start, |
649 | }; | 817 | }; |
@@ -664,8 +832,29 @@ static struct ata_port_operations it821x_passthru_port_ops = { | |||
664 | .port_start = it821x_port_start, | 832 | .port_start = it821x_port_start, |
665 | }; | 833 | }; |
666 | 834 | ||
835 | static struct ata_port_operations it821x_rdc_port_ops = { | ||
836 | .inherits = &ata_bmdma_port_ops, | ||
837 | |||
838 | .check_atapi_dma= it821x_check_atapi_dma, | ||
839 | .sff_dev_select = it821x_passthru_dev_select, | ||
840 | .bmdma_start = it821x_passthru_bmdma_start, | ||
841 | .bmdma_stop = it821x_passthru_bmdma_stop, | ||
842 | .qc_issue = it821x_passthru_qc_issue, | ||
843 | |||
844 | .cable_detect = it821x_rdc_cable, | ||
845 | .set_piomode = it821x_passthru_set_piomode, | ||
846 | .set_dmamode = it821x_passthru_set_dmamode, | ||
847 | |||
848 | .port_start = it821x_port_start, | ||
849 | }; | ||
850 | |||
667 | static void it821x_disable_raid(struct pci_dev *pdev) | 851 | static void it821x_disable_raid(struct pci_dev *pdev) |
668 | { | 852 | { |
853 | /* Neither the RDC nor the IT8211 */ | ||
854 | if (pdev->vendor != PCI_VENDOR_ID_ITE || | ||
855 | pdev->device != PCI_DEVICE_ID_ITE_8212) | ||
856 | return; | ||
857 | |||
669 | /* Reset local CPU, and set BIOS not ready */ | 858 | /* Reset local CPU, and set BIOS not ready */ |
670 | pci_write_config_byte(pdev, 0x5E, 0x01); | 859 | pci_write_config_byte(pdev, 0x5E, 0x01); |
671 | 860 | ||
@@ -690,6 +879,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
690 | .flags = ATA_FLAG_SLAVE_POSS, | 879 | .flags = ATA_FLAG_SLAVE_POSS, |
691 | .pio_mask = 0x1f, | 880 | .pio_mask = 0x1f, |
692 | .mwdma_mask = 0x07, | 881 | .mwdma_mask = 0x07, |
882 | .udma_mask = ATA_UDMA6, | ||
693 | .port_ops = &it821x_smart_port_ops | 883 | .port_ops = &it821x_smart_port_ops |
694 | }; | 884 | }; |
695 | static const struct ata_port_info info_passthru = { | 885 | static const struct ata_port_info info_passthru = { |
@@ -699,6 +889,13 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
699 | .udma_mask = ATA_UDMA6, | 889 | .udma_mask = ATA_UDMA6, |
700 | .port_ops = &it821x_passthru_port_ops | 890 | .port_ops = &it821x_passthru_port_ops |
701 | }; | 891 | }; |
892 | static const struct ata_port_info info_rdc = { | ||
893 | .flags = ATA_FLAG_SLAVE_POSS, | ||
894 | .pio_mask = 0x1f, | ||
895 | .mwdma_mask = 0x07, | ||
896 | /* No UDMA */ | ||
897 | .port_ops = &it821x_rdc_port_ops | ||
898 | }; | ||
702 | 899 | ||
703 | const struct ata_port_info *ppi[] = { NULL, NULL }; | 900 | const struct ata_port_info *ppi[] = { NULL, NULL }; |
704 | static char *mode[2] = { "pass through", "smart" }; | 901 | static char *mode[2] = { "pass through", "smart" }; |
@@ -707,21 +904,25 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
707 | rc = pcim_enable_device(pdev); | 904 | rc = pcim_enable_device(pdev); |
708 | if (rc) | 905 | if (rc) |
709 | return rc; | 906 | return rc; |
907 | |||
908 | if (pdev->vendor == PCI_VENDOR_ID_RDC) { | ||
909 | ppi[0] = &info_rdc; | ||
910 | } else { | ||
911 | /* Force the card into bypass mode if so requested */ | ||
912 | if (it8212_noraid) { | ||
913 | printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n"); | ||
914 | it821x_disable_raid(pdev); | ||
915 | } | ||
916 | pci_read_config_byte(pdev, 0x50, &conf); | ||
917 | conf &= 1; | ||
710 | 918 | ||
711 | /* Force the card into bypass mode if so requested */ | 919 | printk(KERN_INFO DRV_NAME": controller in %s mode.\n", |
712 | if (it8212_noraid) { | 920 | mode[conf]); |
713 | printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n"); | 921 | if (conf == 0) |
714 | it821x_disable_raid(pdev); | 922 | ppi[0] = &info_passthru; |
923 | else | ||
924 | ppi[0] = &info_smart; | ||
715 | } | 925 | } |
716 | pci_read_config_byte(pdev, 0x50, &conf); | ||
717 | conf &= 1; | ||
718 | |||
719 | printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]); | ||
720 | if (conf == 0) | ||
721 | ppi[0] = &info_passthru; | ||
722 | else | ||
723 | ppi[0] = &info_smart; | ||
724 | |||
725 | return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL); | 926 | return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL); |
726 | } | 927 | } |
727 | 928 | ||
@@ -745,6 +946,7 @@ static int it821x_reinit_one(struct pci_dev *pdev) | |||
745 | static const struct pci_device_id it821x[] = { | 946 | static const struct pci_device_id it821x[] = { |
746 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), }, | 947 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), }, |
747 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), }, | 948 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), }, |
949 | { PCI_VDEVICE(RDC, 0x1010), }, | ||
748 | 950 | ||
749 | { }, | 951 | { }, |
750 | }; | 952 | }; |